@@ -8,7 +8,8 @@ use blockifier::execution::syscalls::hint_processor::{
8
8
use blockifier:: execution:: syscalls:: syscall_base:: SyscallResult ;
9
9
use blockifier:: execution:: syscalls:: vm_syscall_utils:: {
10
10
CallContractRequest , DeployRequest , DeployResponse , EmptyRequest , GetBlockHashRequest ,
11
- GetBlockHashResponse , GetExecutionInfoResponse , LibraryCallRequest , SyscallResponse ,
11
+ GetBlockHashResponse , GetExecutionInfoResponse , LibraryCallRequest , StorageReadRequest ,
12
+ StorageReadResponse , StorageWriteRequest , StorageWriteResponse , SyscallResponse ,
12
13
SyscallSelector , WriteResponseResult ,
13
14
} ;
14
15
use blockifier:: execution:: { call_info:: CallInfo , entry_point:: ConstructorContext } ;
@@ -28,6 +29,8 @@ use blockifier::{
28
29
} ;
29
30
use cairo_vm:: types:: relocatable:: Relocatable ;
30
31
use cairo_vm:: vm:: vm_core:: VirtualMachine ;
32
+ use conversions:: string:: TryFromHexStr ;
33
+ use runtime:: starknet:: constants:: TEST_ADDRESS ;
31
34
use starknet_api:: core:: calculate_contract_address;
32
35
use starknet_api:: {
33
36
contract_class:: EntryPointType ,
@@ -245,6 +248,76 @@ pub fn get_block_hash_syscall(
245
248
Ok ( GetBlockHashResponse { block_hash } )
246
249
}
247
250
251
+ #[ expect( clippy:: needless_pass_by_value, clippy:: result_large_err) ]
252
+ pub fn storage_read (
253
+ request : StorageReadRequest ,
254
+ _vm : & mut VirtualMachine ,
255
+ syscall_handler : & mut SyscallHintProcessor < ' _ > ,
256
+ cheatnet_state : & mut CheatnetState ,
257
+ _remaining_gas : & mut u64 ,
258
+ ) -> SyscallResult < StorageReadResponse > {
259
+ let original_storage_address = syscall_handler. base . call . storage_address ;
260
+ maybe_modify_storage_address ( syscall_handler, cheatnet_state) ;
261
+
262
+ let value = syscall_handler
263
+ . base
264
+ . storage_read ( request. address )
265
+ . inspect_err ( |_| {
266
+ // Restore state on error before bubbling up
267
+ syscall_handler. base . call . storage_address = original_storage_address;
268
+ } ) ?;
269
+
270
+ // Restore the original storage_address
271
+ syscall_handler. base . call . storage_address = original_storage_address;
272
+
273
+ Ok ( StorageReadResponse { value } )
274
+ }
275
+
276
+ #[ expect( clippy:: needless_pass_by_value, clippy:: result_large_err) ]
277
+ pub fn storage_write (
278
+ request : StorageWriteRequest ,
279
+ _vm : & mut VirtualMachine ,
280
+ syscall_handler : & mut SyscallHintProcessor < ' _ > ,
281
+ cheatnet_state : & mut CheatnetState ,
282
+ _remaining_gas : & mut u64 ,
283
+ ) -> SyscallResult < StorageWriteResponse > {
284
+ let original_storage_address = syscall_handler. base . call . storage_address ;
285
+ maybe_modify_storage_address ( syscall_handler, cheatnet_state) ;
286
+
287
+ syscall_handler
288
+ . base
289
+ . storage_write ( request. address , request. value )
290
+ . inspect_err ( |_| {
291
+ // Restore state on error before bubbling up
292
+ syscall_handler. base . call . storage_address = original_storage_address;
293
+ } ) ?;
294
+
295
+ // Restore the original storage_address
296
+ syscall_handler. base . call . storage_address = original_storage_address;
297
+
298
+ Ok ( StorageWriteResponse { } )
299
+ }
300
+
301
+ // This logic is used to modify the storage address to enable using `contract_state_for_testing`
302
+ // inside `interact_with_state` closure cheatcode.
303
+ fn maybe_modify_storage_address (
304
+ syscall_handler : & mut SyscallHintProcessor < ' _ > ,
305
+ cheatnet_state : & mut CheatnetState ,
306
+ ) {
307
+ let contract_address = syscall_handler. storage_address ( ) ;
308
+ let test_address =
309
+ TryFromHexStr :: try_from_hex_str ( TEST_ADDRESS ) . expect ( "Failed to parse `TEST_ADDRESS`" ) ;
310
+
311
+ if contract_address != test_address {
312
+ return ;
313
+ }
314
+
315
+ let cheated_data = cheatnet_state. get_cheated_data ( contract_address) ;
316
+ if let Some ( actual_address) = cheated_data. contract_address {
317
+ syscall_handler. base . call . storage_address = actual_address;
318
+ }
319
+ }
320
+
248
321
#[ derive( Debug ) ]
249
322
// crates/blockifier/src/execution/syscalls/mod.rs:127 (SingleSegmentResponse)
250
323
// It is created here because fields in the original structure are private
0 commit comments