1
1
use crate :: runtime_extensions:: call_to_blockifier_runtime_extension:: execution:: entry_point:: {
2
2
CallInfoWithExecutionData , ContractClassEntryPointExecutionResult ,
3
3
} ;
4
+ use crate :: runtime_extensions:: native:: native_syscall_handler:: CheatableNativeSyscallHandler ;
4
5
use crate :: state:: CheatnetState ;
5
- use blockifier:: execution:: entry_point:: { EntryPointExecutionContext , ExecutableCallEntryPoint } ;
6
+ use blockifier:: execution:: call_info:: { BuiltinCounterMap , CallExecution , CallInfo , Retdata } ;
7
+ use blockifier:: execution:: contract_class:: TrackedResource ;
8
+ use blockifier:: execution:: entry_point:: {
9
+ EntryPointExecutionContext , EntryPointExecutionResult , ExecutableCallEntryPoint ,
10
+ } ;
11
+ use blockifier:: execution:: errors:: {
12
+ EntryPointExecutionError , PostExecutionError , PreExecutionError ,
13
+ } ;
6
14
use blockifier:: execution:: native:: contract_class:: NativeCompiledClassV1 ;
7
- use blockifier:: execution:: native:: entry_point_execution :: execute_entry_point_call ;
15
+ use blockifier:: execution:: native:: syscall_handler :: NativeSyscallHandler ;
8
16
use blockifier:: state:: state_api:: State ;
17
+ use blockifier:: transaction:: objects:: ExecutionResourcesTraits ;
18
+ use blockifier:: utils:: add_maps;
19
+ use cairo_native:: execution_result:: { BuiltinStats , ContractExecutionResult } ;
20
+ use cairo_native:: utils:: BuiltinCosts ;
21
+ use cairo_vm:: types:: builtin_name:: BuiltinName ;
9
22
use std:: default:: Default ;
10
23
11
24
pub ( crate ) fn execute_entry_point_call_native (
@@ -15,8 +28,13 @@ pub(crate) fn execute_entry_point_call_native(
15
28
cheatnet_state : & mut CheatnetState , // Added parameter
16
29
context : & mut EntryPointExecutionContext ,
17
30
) -> ContractClassEntryPointExecutionResult {
31
+ let syscall_handler = CheatableNativeSyscallHandler {
32
+ cheatnet_state,
33
+ native_syscall_handler : & mut NativeSyscallHandler :: new ( call. clone ( ) , state, context) ,
34
+ } ;
35
+
18
36
// TODO error handling
19
- let call_info = execute_entry_point_call ( call, native_compiled_class_v1, state , context )
37
+ let call_info = execute_entry_point_call ( call, native_compiled_class_v1, syscall_handler )
20
38
. expect ( "Native execution failed" ) ;
21
39
22
40
Ok ( CallInfoWithExecutionData {
@@ -26,3 +44,175 @@ pub(crate) fn execute_entry_point_call_native(
26
44
vm_trace : None ,
27
45
} )
28
46
}
47
+
48
+ // Copied from blockifier
49
+ // todo(rodrigo): add an `entry point not found` test for Native
50
+ #[ allow( clippy:: result_large_err) ]
51
+ pub fn execute_entry_point_call (
52
+ call : ExecutableCallEntryPoint ,
53
+ compiled_class : NativeCompiledClassV1 ,
54
+ // state: &mut dyn State,
55
+ // context: &mut EntryPointExecutionContext,
56
+ mut syscall_handler : CheatableNativeSyscallHandler ,
57
+ ) -> EntryPointExecutionResult < CallInfo > {
58
+ let entry_point = compiled_class. get_entry_point ( & call. type_and_selector ( ) ) ?;
59
+
60
+ // let mut syscall_handler: NativeSyscallHandler<'_> =
61
+ // NativeSyscallHandler::new(call, state, context);
62
+
63
+ let gas_costs = & syscall_handler
64
+ . native_syscall_handler
65
+ . base
66
+ . context
67
+ . gas_costs ( ) ;
68
+ let builtin_costs = BuiltinCosts {
69
+ // todo(rodrigo): Unsure of what value `const` means, but 1 is the right value.
70
+ r#const : 1 ,
71
+ pedersen : gas_costs. builtins . pedersen ,
72
+ bitwise : gas_costs. builtins . bitwise ,
73
+ ecop : gas_costs. builtins . ecop ,
74
+ poseidon : gas_costs. builtins . poseidon ,
75
+ add_mod : gas_costs. builtins . add_mod ,
76
+ mul_mod : gas_costs. builtins . mul_mod ,
77
+ } ;
78
+
79
+ // Pre-charge entry point's initial budget to ensure sufficient gas for executing a minimal
80
+ // entry point code. When redepositing is used, the entry point is aware of this pre-charge
81
+ // and adjusts the gas counter accordingly if a smaller amount of gas is required.
82
+ let initial_budget = syscall_handler
83
+ . native_syscall_handler
84
+ . base
85
+ . context
86
+ . gas_costs ( )
87
+ . base
88
+ . entry_point_initial_budget ;
89
+ let call_initial_gas = syscall_handler
90
+ . native_syscall_handler
91
+ . base
92
+ . call
93
+ . initial_gas
94
+ . checked_sub ( initial_budget)
95
+ . ok_or ( PreExecutionError :: InsufficientEntryPointGas ) ?;
96
+
97
+ let execution_result = compiled_class. executor . run (
98
+ entry_point. selector . 0 ,
99
+ & syscall_handler
100
+ . native_syscall_handler
101
+ . base
102
+ . call
103
+ . calldata
104
+ . 0
105
+ . clone ( ) ,
106
+ call_initial_gas,
107
+ Some ( builtin_costs) ,
108
+ & mut syscall_handler,
109
+ ) ;
110
+
111
+ syscall_handler. native_syscall_handler . finalize ( ) ;
112
+
113
+ let call_result = execution_result. map_err ( EntryPointExecutionError :: NativeUnexpectedError ) ?;
114
+
115
+ // TODO consider modifying this so it doesn't use take internally
116
+ if let Some ( error) = syscall_handler. unrecoverable_error ( ) {
117
+ return Err ( EntryPointExecutionError :: NativeUnrecoverableError (
118
+ Box :: new ( error) ,
119
+ ) ) ;
120
+ }
121
+
122
+ create_callinfo ( call_result, syscall_handler)
123
+ }
124
+
125
+ // Copied from blockifier
126
+ #[ allow( clippy:: result_large_err) ]
127
+ fn create_callinfo (
128
+ call_result : ContractExecutionResult ,
129
+ syscall_handler : CheatableNativeSyscallHandler < ' _ > ,
130
+ ) -> Result < CallInfo , EntryPointExecutionError > {
131
+ let remaining_gas = call_result. remaining_gas ;
132
+
133
+ if remaining_gas > syscall_handler. native_syscall_handler . base . call . initial_gas {
134
+ return Err ( PostExecutionError :: MalformedReturnData {
135
+ error_message : format ! (
136
+ "Unexpected remaining gas. Used gas is greater than initial gas: {} > {}" ,
137
+ remaining_gas, syscall_handler. native_syscall_handler. base. call. initial_gas
138
+ ) ,
139
+ }
140
+ . into ( ) ) ;
141
+ }
142
+
143
+ let gas_consumed = syscall_handler. native_syscall_handler . base . call . initial_gas - remaining_gas;
144
+ let vm_resources = CallInfo :: summarize_vm_resources (
145
+ syscall_handler
146
+ . native_syscall_handler
147
+ . base
148
+ . inner_calls
149
+ . iter ( ) ,
150
+ ) ;
151
+
152
+ // Retrieve the builtin counts from the syscall handler
153
+ let version_constants = syscall_handler
154
+ . native_syscall_handler
155
+ . base
156
+ . context
157
+ . versioned_constants ( ) ;
158
+ let syscall_builtin_counts = version_constants
159
+ . get_additional_os_syscall_resources (
160
+ & syscall_handler. native_syscall_handler . base . syscalls_usage ,
161
+ )
162
+ . filter_unused_builtins ( )
163
+ . prover_builtins ( ) ;
164
+ let entry_point_builtins = builtin_stats_to_builtin_counter_map ( call_result. builtin_stats ) ;
165
+ let mut builtin_counters = syscall_builtin_counts;
166
+ add_maps ( & mut builtin_counters, & entry_point_builtins) ;
167
+
168
+ Ok ( CallInfo {
169
+ call : syscall_handler
170
+ . native_syscall_handler
171
+ . base
172
+ . call
173
+ . clone ( )
174
+ . into ( ) ,
175
+ execution : CallExecution {
176
+ retdata : Retdata ( call_result. return_values ) ,
177
+ events : syscall_handler. native_syscall_handler . base . events . clone ( ) ,
178
+ cairo_native : true ,
179
+ l2_to_l1_messages : syscall_handler
180
+ . native_syscall_handler
181
+ . base
182
+ . l2_to_l1_messages
183
+ . clone ( ) ,
184
+ failed : call_result. failure_flag ,
185
+ gas_consumed,
186
+ } ,
187
+ resources : vm_resources,
188
+ inner_calls : syscall_handler
189
+ . native_syscall_handler
190
+ . base
191
+ . inner_calls
192
+ . clone ( ) ,
193
+ storage_access_tracker : syscall_handler
194
+ . native_syscall_handler
195
+ . base
196
+ . storage_access_tracker
197
+ . clone ( ) ,
198
+ tracked_resource : TrackedResource :: SierraGas ,
199
+ builtin_counters,
200
+ } )
201
+ }
202
+
203
+ fn builtin_stats_to_builtin_counter_map ( builtin_stats : BuiltinStats ) -> BuiltinCounterMap {
204
+ let builtins = [
205
+ ( BuiltinName :: range_check, builtin_stats. range_check ) ,
206
+ ( BuiltinName :: pedersen, builtin_stats. pedersen ) ,
207
+ ( BuiltinName :: bitwise, builtin_stats. bitwise ) ,
208
+ ( BuiltinName :: ec_op, builtin_stats. ec_op ) ,
209
+ ( BuiltinName :: poseidon, builtin_stats. poseidon ) ,
210
+ ( BuiltinName :: range_check96, builtin_stats. range_check96 ) ,
211
+ ( BuiltinName :: add_mod, builtin_stats. add_mod ) ,
212
+ ( BuiltinName :: mul_mod, builtin_stats. mul_mod ) ,
213
+ ] ;
214
+ builtins
215
+ . into_iter ( )
216
+ . filter ( |( _, count) | * count > 0 )
217
+ . collect ( )
218
+ }
0 commit comments