Skip to content

Commit dfe5ff3

Browse files
authored
Replace custom memory methods with Cairo's MemBuffer (#248)
Replaced custom memory methhods in `cheatcodes_hint_processor.rs` with `MemBuffer` methods exposed in `Cairo`.
1 parent 499f83e commit dfe5ff3

File tree

2 files changed

+42
-112
lines changed

2 files changed

+42
-112
lines changed

starknet-foundry/crates/forge/src/cheatcodes_hint_processor.rs

Lines changed: 34 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use cairo_vm::hint_processor::hint_processor_definition::HintProcessorLogic;
2424
use cairo_vm::hint_processor::hint_processor_definition::HintReference;
2525
use cairo_vm::serde::deserialize_program::ApTracking;
2626
use cairo_vm::types::exec_scope::ExecutionScopes;
27-
use cairo_vm::types::relocatable::Relocatable;
2827
use cairo_vm::vm::errors::hint_errors::HintError;
2928
use cairo_vm::vm::errors::memory_errors::MemoryError;
3029
use cairo_vm::vm::errors::vm_errors::VirtualMachineError;
@@ -46,13 +45,10 @@ use starknet_api::transaction::{
4645
use starknet_api::{patricia_key, stark_felt, StarknetApiError};
4746
use thiserror::Error;
4847

49-
use crate::vm_memory::{
50-
felt_from_pointer, insert_at_pointer, relocatable_from_pointer, usize_from_pointer,
51-
write_cheatcode_panic,
52-
};
48+
use crate::vm_memory::write_cheatcode_panic;
5349
use cairo_lang_casm::hints::{Hint, StarknetHint};
5450
use cairo_lang_casm::operand::{CellRef, ResOperand};
55-
use cairo_lang_runner::casm_run::extract_relocatable;
51+
use cairo_lang_runner::casm_run::{extract_relocatable, vm_get_range, MemBuffer};
5652
use cairo_lang_runner::short_string::as_cairo_short_string;
5753
use cairo_lang_runner::{
5854
casm_run::{cell_ref_to_relocatable, extract_buffer, get_ptr},
@@ -173,19 +169,16 @@ fn execute_syscall(
173169
blockifier_state: &mut CachedState<DictStateReader>,
174170
) -> Result<(), HintError> {
175171
let (cell, offset) = extract_buffer(system);
176-
let mut system_ptr = get_ptr(vm, cell, &offset)?;
172+
let system_ptr = get_ptr(vm, cell, &offset)?;
177173

178-
let selector = felt_from_pointer(vm, &mut system_ptr)
179-
.unwrap()
180-
.to_bytes_be();
174+
let mut buffer = MemBuffer::new(vm, system_ptr);
181175

182-
let gas_counter = usize_from_pointer(vm, &mut system_ptr).unwrap();
183-
let contract_address = felt_from_pointer(vm, &mut system_ptr).unwrap();
184-
let entry_point_selector = felt_from_pointer(vm, &mut system_ptr).unwrap();
176+
let selector = buffer.next_felt252().unwrap().to_bytes_be();
177+
let gas_counter = buffer.next_usize().unwrap();
178+
let contract_address = buffer.next_felt252().unwrap().into_owned();
179+
let entry_point_selector = buffer.next_felt252().unwrap().into_owned();
185180

186-
let start = relocatable_from_pointer(vm, &mut system_ptr).unwrap();
187-
let end = relocatable_from_pointer(vm, &mut system_ptr).unwrap();
188-
let calldata = read_data_from_range(vm, start, end).unwrap();
181+
let calldata = buffer.next_arr().unwrap();
189182

190183
assert_eq!(std::str::from_utf8(&selector).unwrap(), "CallContract");
191184
let call_result = call_contract(
@@ -201,18 +194,10 @@ fn execute_syscall(
201194
CallContractOutput::Panic { panic_data } => (panic_data, 1),
202195
};
203196

204-
insert_at_pointer(vm, &mut system_ptr, gas_counter).unwrap();
205-
insert_at_pointer(vm, &mut system_ptr, Felt252::from(exit_code)).unwrap();
206-
207-
let mut ptr = vm.add_memory_segment();
208-
let start = ptr;
209-
for value in result {
210-
insert_at_pointer(vm, &mut ptr, value).unwrap();
211-
}
212-
let end = ptr;
197+
buffer.write(gas_counter).unwrap();
198+
buffer.write(Felt252::from(exit_code)).unwrap();
213199

214-
insert_at_pointer(vm, &mut system_ptr, start).unwrap();
215-
insert_at_pointer(vm, &mut system_ptr, end).unwrap();
200+
buffer.write_arr(result.iter()).unwrap();
216201

217202
Ok(())
218203
}
@@ -343,7 +328,7 @@ fn execute_cheatcode_hint(
343328
// Extract the inputs.
344329
let input_start = extract_relocatable(vm, input_start)?;
345330
let input_end = extract_relocatable(vm, input_end)?;
346-
let inputs = read_data_from_range(vm, input_start, input_end)
331+
let inputs = vm_get_range(vm, input_start, input_end)
347332
.map_err(|_| HintError::CustomHint(Box::from("Failed to read input data".to_string())))?;
348333

349334
match_cheatcode_by_selector(
@@ -368,8 +353,8 @@ fn match_cheatcode_by_selector(
368353
output_end: &CellRef,
369354
contracts: &HashMap<String, StarknetContractArtifacts>,
370355
) -> Result<(), EnhancedHintError> {
371-
let mut result_segment_ptr = vm.add_memory_segment();
372-
let result_start = result_segment_ptr;
356+
let mut buffer = MemBuffer::new_segment(vm);
357+
let result_start = buffer.ptr;
373358

374359
match selector {
375360
"prepare" => todo!(),
@@ -380,22 +365,16 @@ fn match_cheatcode_by_selector(
380365
"start_prank" => todo!(),
381366
"stop_prank" => todo!(),
382367
"mock_call" => todo!(),
383-
"declare" => declare(
384-
vm,
385-
blockifier_state,
386-
&inputs,
387-
&mut result_segment_ptr,
388-
contracts,
389-
),
390-
"deploy" => deploy(vm, blockifier_state, &inputs, &mut result_segment_ptr),
368+
"declare" => declare(&mut buffer, blockifier_state, &inputs, contracts),
369+
"deploy" => deploy(&mut buffer, blockifier_state, &inputs),
391370
"print" => {
392371
print(inputs);
393372
Ok(())
394373
}
395374
_ => Err(anyhow!("Unknown cheatcode selector: {selector}")).map_err(Into::into),
396375
}?;
397376

398-
let result_end = result_segment_ptr;
377+
let result_end = buffer.ptr;
399378
insert_value_to_cellref!(vm, output_start, result_start)?;
400379
insert_value_to_cellref!(vm, output_end, result_end)?;
401380

@@ -413,10 +392,9 @@ fn print(inputs: Vec<Felt252>) {
413392
}
414393

415394
fn declare(
416-
vm: &mut VirtualMachine,
395+
buffer: &mut MemBuffer,
417396
blockifier_state: &mut CachedState<DictStateReader>,
418397
inputs: &[Felt252],
419-
result_segment_ptr: &mut Relocatable,
420398
contracts: &HashMap<String, StarknetContractArtifacts>,
421399
) -> Result<(), EnhancedHintError> {
422400
let contract_value = inputs[0].clone();
@@ -465,8 +443,12 @@ fn declare(
465443
// result_segment.
466444
let felt_class_hash = felt252_from_hex_string(&class_hash.to_string()).unwrap();
467445

468-
insert_at_pointer(vm, result_segment_ptr, Felt252::from(0))?;
469-
insert_at_pointer(vm, result_segment_ptr, felt_class_hash)?;
446+
buffer
447+
.write(Felt252::from(0))
448+
.expect("Failed to insert error code");
449+
buffer
450+
.write(felt_class_hash)
451+
.expect("Failed to insert declared contract class hash");
470452

471453
Ok(())
472454
}
@@ -479,10 +461,9 @@ fn get_class_hash(casm_contract: &str) -> Result<ClassHash> {
479461
}
480462

481463
fn deploy(
482-
vm: &mut VirtualMachine,
464+
buffer: &mut MemBuffer,
483465
blockifier_state: &mut CachedState<DictStateReader>,
484466
inputs: &[Felt252],
485-
result_segment_ptr: &mut Relocatable,
486467
) -> Result<(), EnhancedHintError> {
487468
// TODO(#1991) deploy should fail if contract address provided doesn't match calculated
488469
// or not accept this address as argument at all.
@@ -504,9 +485,8 @@ fn deploy(
504485
let contract_class = blockifier_state.get_compiled_contract_class(&class_hash)?;
505486
if contract_class.constructor_selector().is_none() && !calldata.is_empty() {
506487
write_cheatcode_panic(
507-
vm,
508-
result_segment_ptr,
509-
vec![felt_from_short_string("No constructor in contract")],
488+
buffer,
489+
vec![felt_from_short_string("No constructor in contract")].as_slice(),
510490
);
511491
return Ok(());
512492
}
@@ -538,8 +518,11 @@ fn deploy(
538518
.expect("Failed to get contract_address from return_data");
539519
let contract_address = Felt252::from_bytes_be(contract_address.bytes());
540520

541-
insert_at_pointer(vm, result_segment_ptr, 0).expect("Failed to insert error code");
542-
insert_at_pointer(vm, result_segment_ptr, contract_address)
521+
buffer
522+
.write(Felt252::from(0))
523+
.expect("Failed to insert error code");
524+
buffer
525+
.write(contract_address)
543526
.expect("Failed to insert deployed contract address");
544527
} else {
545528
let revert_error = tx_info
@@ -548,7 +531,7 @@ fn deploy(
548531
let extracted_panic_data = try_extract_panic_data(&revert_error)
549532
.expect("Unparseable error message, {revert_error}");
550533

551-
write_cheatcode_panic(vm, result_segment_ptr, extracted_panic_data);
534+
write_cheatcode_panic(buffer, extracted_panic_data.as_slice());
552535
}
553536
Ok(())
554537
}
@@ -603,19 +586,6 @@ fn create_execute_calldata(
603586
Calldata(execute_calldata.into())
604587
}
605588

606-
fn read_data_from_range(
607-
vm: &VirtualMachine,
608-
mut start: Relocatable,
609-
end: Relocatable,
610-
) -> Result<Vec<Felt252>> {
611-
let mut calldata: Vec<Felt252> = vec![];
612-
while start != end {
613-
let value = felt_from_pointer(vm, &mut start)?;
614-
calldata.push(value);
615-
}
616-
Ok(calldata)
617-
}
618-
619589
fn felt252_from_hex_string(value: &str) -> Result<Felt252> {
620590
let stripped_value = value.replace("0x", "");
621591
Felt252::from_str_radix(&stripped_value, 16)
Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,12 @@
1-
use anyhow::{anyhow, Result};
21
use cairo_felt::Felt252;
3-
use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable};
4-
use cairo_vm::vm::vm_core::VirtualMachine;
5-
use num_traits::ToPrimitive;
2+
use cairo_lang_runner::casm_run::MemBuffer;
63

7-
pub(crate) fn write_cheatcode_panic(
8-
vm: &mut VirtualMachine,
9-
result_segment_ptr: &mut Relocatable,
10-
panic_data: Vec<Felt252>,
11-
) {
12-
insert_at_pointer(vm, result_segment_ptr, 1).expect("Failed to insert err code");
13-
insert_at_pointer(vm, result_segment_ptr, panic_data.len())
4+
pub(crate) fn write_cheatcode_panic(buffer: &mut MemBuffer, panic_data: &[Felt252]) {
5+
buffer.write(1).expect("Failed to insert err code");
6+
buffer
7+
.write(panic_data.len())
148
.expect("Failed to insert panic_data len");
15-
for datum in panic_data {
16-
insert_at_pointer(vm, result_segment_ptr, datum).expect("Failed to insert error in memory");
17-
}
18-
}
19-
20-
pub(crate) fn insert_at_pointer<T: Into<MaybeRelocatable>>(
21-
vm: &mut VirtualMachine,
22-
ptr: &mut Relocatable,
23-
value: T,
24-
) -> Result<()> {
25-
vm.insert_value(*ptr, value)?;
26-
*ptr += 1;
27-
Ok(())
28-
}
29-
30-
pub(crate) fn usize_from_pointer(vm: &VirtualMachine, ptr: &mut Relocatable) -> Result<usize> {
31-
let gas_counter = vm
32-
.get_integer(*ptr)?
33-
.to_usize()
34-
.ok_or_else(|| anyhow!("Failed to convert to usize"))?;
35-
*ptr += 1;
36-
Ok(gas_counter)
37-
}
38-
39-
pub(crate) fn relocatable_from_pointer(
40-
vm: &VirtualMachine,
41-
ptr: &mut Relocatable,
42-
) -> Result<Relocatable> {
43-
let start = vm.get_relocatable(*ptr)?;
44-
*ptr += 1;
45-
Ok(start)
46-
}
47-
48-
pub(crate) fn felt_from_pointer(vm: &VirtualMachine, ptr: &mut Relocatable) -> Result<Felt252> {
49-
let entry_point_selector = vm.get_integer(*ptr)?.into_owned();
50-
*ptr += 1;
51-
Ok(entry_point_selector)
9+
buffer
10+
.write_data(panic_data.iter())
11+
.expect("Failed to insert error in memory");
5212
}

0 commit comments

Comments
 (0)