@@ -2,18 +2,25 @@ use super::calls::{execute_inner_call, execute_library_call};
2
2
use super :: execution_info:: get_cheated_exec_info_ptr;
3
3
use crate :: runtime_extensions:: call_to_blockifier_runtime_extension:: CheatnetState ;
4
4
use crate :: runtime_extensions:: call_to_blockifier_runtime_extension:: execution:: entry_point:: execute_constructor_entry_point;
5
+ use blockifier:: context:: TransactionContext ;
6
+ use blockifier:: execution:: common_hints:: ExecutionMode ;
7
+ use blockifier:: execution:: execution_utils:: ReadOnlySegment ;
5
8
use blockifier:: execution:: syscalls:: hint_processor:: {
6
- SyscallExecutionError , SyscallHintProcessor ,
9
+ INVALID_ARGUMENT , SyscallExecutionError , SyscallHintProcessor ,
7
10
} ;
8
11
use blockifier:: execution:: syscalls:: syscall_base:: SyscallResult ;
9
12
use blockifier:: execution:: syscalls:: vm_syscall_utils:: {
10
13
CallContractRequest , CallContractResponse , DeployRequest , DeployResponse , EmptyRequest ,
11
14
GetBlockHashRequest , GetBlockHashResponse , GetExecutionInfoResponse , LibraryCallRequest ,
12
- LibraryCallResponse , StorageReadRequest , StorageReadResponse , StorageWriteRequest ,
13
- StorageWriteResponse , SyscallSelector ,
15
+ LibraryCallResponse , MetaTxV0Request , MetaTxV0Response , StorageReadRequest ,
16
+ StorageReadResponse , StorageWriteRequest , StorageWriteResponse , SyscallSelector ,
17
+ TryExtractRevert ,
14
18
} ;
15
19
use blockifier:: execution:: { call_info:: CallInfo , entry_point:: ConstructorContext } ;
16
20
use blockifier:: state:: errors:: StateError ;
21
+ use blockifier:: transaction:: objects:: {
22
+ CommonAccountFields , DeprecatedTransactionInfo , TransactionInfo ,
23
+ } ;
17
24
use blockifier:: {
18
25
execution:: entry_point:: {
19
26
CallEntryPoint , CallType , EntryPointExecutionContext , EntryPointExecutionResult ,
@@ -24,15 +31,24 @@ use blockifier::{
24
31
execution:: execution_utils:: update_remaining_gas,
25
32
execution:: syscalls:: hint_processor:: create_retdata_segment,
26
33
} ;
34
+ use cairo_vm:: Felt252 ;
27
35
use cairo_vm:: vm:: vm_core:: VirtualMachine ;
28
36
use conversions:: string:: TryFromHexStr ;
29
37
use runtime:: starknet:: constants:: TEST_ADDRESS ;
30
- use starknet_api:: core:: calculate_contract_address;
38
+ use starknet_api:: abi:: abi_utils:: selector_from_name;
39
+ use starknet_api:: core:: EntryPointSelector ;
40
+ use starknet_api:: transaction:: constants:: EXECUTE_ENTRY_POINT_NAME ;
41
+ use starknet_api:: transaction:: fields:: TransactionSignature ;
42
+ use starknet_api:: transaction:: { TransactionHasher , TransactionOptions , signed_tx_version} ;
31
43
use starknet_api:: {
32
44
contract_class:: EntryPointType ,
33
- core:: { ClassHash , ContractAddress } ,
34
- transaction:: fields:: Calldata ,
45
+ core:: { ClassHash , ContractAddress , Nonce , calculate_contract_address} ,
46
+ transaction:: {
47
+ InvokeTransactionV0 , TransactionVersion ,
48
+ fields:: { Calldata , Fee } ,
49
+ } ,
35
50
} ;
51
+ use std:: sync:: Arc ;
36
52
37
53
#[ expect( clippy:: result_large_err) ]
38
54
pub fn get_execution_info_syscall (
@@ -224,6 +240,152 @@ pub fn call_contract_syscall(
224
240
// endregion
225
241
}
226
242
243
+ // blockifier/src/execution/syscalls/hint_processor.rs:637 (meta_tx_v0)
244
+ #[ allow( clippy:: result_large_err) ]
245
+ pub fn meta_tx_v0_syscall (
246
+ request : MetaTxV0Request ,
247
+ vm : & mut VirtualMachine ,
248
+ syscall_handler : & mut SyscallHintProcessor < ' _ > ,
249
+ cheatnet_state : & mut CheatnetState ,
250
+ remaining_gas : & mut u64 ,
251
+ ) -> SyscallResult < MetaTxV0Response > {
252
+ let storage_address = request. contract_address ;
253
+ let selector = request. entry_point_selector ;
254
+
255
+ // region: Modified blockifier code
256
+ let retdata_segment = meta_tx_v0 (
257
+ syscall_handler,
258
+ vm,
259
+ cheatnet_state,
260
+ storage_address,
261
+ selector,
262
+ request. calldata ,
263
+ request. signature ,
264
+ remaining_gas,
265
+ ) ?;
266
+ // endregion
267
+
268
+ Ok ( MetaTxV0Response {
269
+ segment : retdata_segment,
270
+ } )
271
+ }
272
+
273
+ // blockifier/src/execution/syscalls/syscall_base.rs:278 (meta_tx_v0)
274
+ #[ allow( clippy:: result_large_err, clippy:: too_many_arguments) ]
275
+ fn meta_tx_v0 (
276
+ syscall_handler : & mut SyscallHintProcessor < ' _ > ,
277
+ vm : & mut VirtualMachine ,
278
+ cheatnet_state : & mut CheatnetState ,
279
+ contract_address : ContractAddress ,
280
+ entry_point_selector : EntryPointSelector ,
281
+ calldata : Calldata ,
282
+ signature : TransactionSignature ,
283
+ remaining_gas : & mut u64 ,
284
+ ) -> SyscallResult < ReadOnlySegment > {
285
+ syscall_handler. increment_linear_factor_by ( & SyscallSelector :: MetaTxV0 , calldata. 0 . len ( ) ) ;
286
+
287
+ if syscall_handler. base . context . execution_mode == ExecutionMode :: Validate {
288
+ //region: Modified blockifier code
289
+ unreachable ! (
290
+ "`ExecutionMode::Validate` should never occur as execution mode is hardcoded to `Execute`"
291
+ ) ;
292
+ // endregion
293
+ }
294
+
295
+ if entry_point_selector != selector_from_name ( EXECUTE_ENTRY_POINT_NAME ) {
296
+ return Err ( SyscallExecutionError :: Revert {
297
+ error_data : vec ! [ Felt252 :: from_hex( INVALID_ARGUMENT ) . unwrap( ) ] ,
298
+ } ) ;
299
+ }
300
+
301
+ let mut entry_point = CallEntryPoint {
302
+ class_hash : None ,
303
+ code_address : Some ( contract_address) ,
304
+ entry_point_type : EntryPointType :: External ,
305
+ entry_point_selector,
306
+ calldata : calldata. clone ( ) ,
307
+ storage_address : contract_address,
308
+ caller_address : ContractAddress :: default ( ) ,
309
+ call_type : CallType :: Call ,
310
+ // NOTE: this value might be overridden later on.
311
+ initial_gas : * remaining_gas,
312
+ } ;
313
+
314
+ let old_tx_context = syscall_handler. base . context . tx_context . clone ( ) ;
315
+ let only_query = old_tx_context. tx_info . only_query ( ) ;
316
+
317
+ // Compute meta-transaction hash.
318
+ let transaction_hash = InvokeTransactionV0 {
319
+ max_fee : Fee ( 0 ) ,
320
+ signature : signature. clone ( ) ,
321
+ contract_address,
322
+ entry_point_selector,
323
+ calldata,
324
+ }
325
+ . calculate_transaction_hash (
326
+ & syscall_handler
327
+ . base
328
+ . context
329
+ . tx_context
330
+ . block_context
331
+ . chain_info ( )
332
+ . chain_id ,
333
+ & signed_tx_version (
334
+ & TransactionVersion :: ZERO ,
335
+ & TransactionOptions { only_query } ,
336
+ ) ,
337
+ ) ?;
338
+
339
+ let class_hash = syscall_handler
340
+ . base
341
+ . state
342
+ . get_class_hash_at ( contract_address) ?;
343
+
344
+ // Replace `tx_context`.
345
+ let new_tx_info = TransactionInfo :: Deprecated ( DeprecatedTransactionInfo {
346
+ common_fields : CommonAccountFields {
347
+ transaction_hash,
348
+ version : TransactionVersion :: ZERO ,
349
+ signature,
350
+ nonce : Nonce ( 0 . into ( ) ) ,
351
+ sender_address : contract_address,
352
+ only_query,
353
+ } ,
354
+ max_fee : Fee ( 0 ) ,
355
+ } ) ;
356
+ syscall_handler. base . context . tx_context = Arc :: new ( TransactionContext {
357
+ block_context : old_tx_context. block_context . clone ( ) ,
358
+ tx_info : new_tx_info,
359
+ } ) ;
360
+
361
+ // region: Modified blockifier code
362
+ // No error should be propagated until we restore the old `tx_context`.
363
+ let retdata_segment = execute_inner_call (
364
+ & mut entry_point,
365
+ vm,
366
+ syscall_handler,
367
+ cheatnet_state,
368
+ remaining_gas,
369
+ )
370
+ . map_err ( |error| {
371
+ SyscallExecutionError :: from_self_or_revert ( error. try_extract_revert ( ) . map_original (
372
+ |error| {
373
+ error. as_call_contract_execution_error (
374
+ class_hash,
375
+ contract_address,
376
+ entry_point_selector,
377
+ )
378
+ } ,
379
+ ) )
380
+ } ) ?;
381
+ // endregion
382
+
383
+ // Restore the old `tx_context`.
384
+ syscall_handler. base . context . tx_context = old_tx_context;
385
+
386
+ Ok ( retdata_segment)
387
+ }
388
+
227
389
#[ expect( clippy:: needless_pass_by_value, clippy:: result_large_err) ]
228
390
pub fn get_block_hash_syscall (
229
391
request : GetBlockHashRequest ,
0 commit comments