@@ -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 ,
@@ -240,6 +243,76 @@ pub fn get_block_hash_syscall(
240
243
Ok ( GetBlockHashResponse { block_hash } )
241
244
}
242
245
246
+ #[ allow( clippy:: needless_pass_by_value) ]
247
+ pub fn storage_read (
248
+ request : StorageReadRequest ,
249
+ _vm : & mut VirtualMachine ,
250
+ syscall_handler : & mut SyscallHintProcessor < ' _ > ,
251
+ cheatnet_state : & mut CheatnetState ,
252
+ _remaining_gas : & mut u64 ,
253
+ ) -> SyscallResult < StorageReadResponse > {
254
+ let original_storage_address = syscall_handler. base . call . storage_address ;
255
+ maybe_modify_storage_address ( syscall_handler, cheatnet_state) ;
256
+
257
+ let value = syscall_handler
258
+ . base
259
+ . storage_read ( request. address )
260
+ . inspect_err ( |_| {
261
+ // Restore state on error before bubbling up
262
+ syscall_handler. base . call . storage_address = original_storage_address;
263
+ } ) ?;
264
+
265
+ // Restore the original storage_address
266
+ syscall_handler. base . call . storage_address = original_storage_address;
267
+
268
+ Ok ( StorageReadResponse { value } )
269
+ }
270
+
271
+ #[ allow( clippy:: needless_pass_by_value) ]
272
+ pub fn storage_write (
273
+ request : StorageWriteRequest ,
274
+ _vm : & mut VirtualMachine ,
275
+ syscall_handler : & mut SyscallHintProcessor < ' _ > ,
276
+ cheatnet_state : & mut CheatnetState ,
277
+ _remaining_gas : & mut u64 ,
278
+ ) -> SyscallResult < StorageWriteResponse > {
279
+ let original_storage_address = syscall_handler. base . call . storage_address ;
280
+ maybe_modify_storage_address ( syscall_handler, cheatnet_state) ;
281
+
282
+ syscall_handler
283
+ . base
284
+ . storage_write ( request. address , request. value )
285
+ . inspect_err ( |_| {
286
+ // Restore state on error before bubbling up
287
+ syscall_handler. base . call . storage_address = original_storage_address;
288
+ } ) ?;
289
+
290
+ // Restore the original storage_address
291
+ syscall_handler. base . call . storage_address = original_storage_address;
292
+
293
+ Ok ( StorageWriteResponse { } )
294
+ }
295
+
296
+ // This logic is used to modify the storage address to enable using `contract_state_for_testing`
297
+ // inside `interact_with_state` closure cheatcode.
298
+ fn maybe_modify_storage_address (
299
+ syscall_handler : & mut SyscallHintProcessor < ' _ > ,
300
+ cheatnet_state : & mut CheatnetState ,
301
+ ) {
302
+ let contract_address = syscall_handler. storage_address ( ) ;
303
+
304
+ if contract_address
305
+ != TryFromHexStr :: try_from_hex_str ( TEST_ADDRESS ) . expect ( "Failed to parse TEST_ADDRESS" )
306
+ {
307
+ return ;
308
+ }
309
+
310
+ let cheated_data = cheatnet_state. get_cheated_data ( contract_address) ;
311
+ if let Some ( actual_address) = cheated_data. contract_address {
312
+ syscall_handler. base . call . storage_address = actual_address;
313
+ }
314
+ }
315
+
243
316
#[ derive( Debug ) ]
244
317
// crates/blockifier/src/execution/syscalls/mod.rs:127 (SingleSegmentResponse)
245
318
// It is created here because fields in the original structure are private
0 commit comments