@@ -11,7 +11,7 @@ use blockifier::execution::syscalls::SyscallResult;
11
11
12
12
use cairo_felt:: Felt252 ;
13
13
use cairo_lang_casm:: hints:: { Hint , StarknetHint } ;
14
- use cairo_lang_casm:: operand:: ResOperand ;
14
+ use cairo_lang_casm:: operand:: { CellRef , ResOperand } ;
15
15
use cairo_lang_runner:: casm_run:: {
16
16
extract_buffer, extract_relocatable, get_ptr, vm_get_range, MemBuffer ,
17
17
} ;
@@ -75,6 +75,17 @@ impl<'a> ResourceTracker for StarknetRuntime<'a> {
75
75
}
76
76
}
77
77
78
+ impl < ' a > SignalPropagator for StarknetRuntime < ' a > {
79
+ fn propagate_system_call_signal (
80
+ & mut self ,
81
+ _selector : DeprecatedSyscallSelector ,
82
+ _vm : & mut VirtualMachine ,
83
+ ) {
84
+ }
85
+
86
+ fn propagate_cheatcode_signal ( & mut self , _selector : & str , _inputs : Vec < Felt252 > ) { }
87
+ }
88
+
78
89
fn parse_selector ( selector : & BigIntAsHex ) -> Result < String , HintError > {
79
90
let selector = & selector. value . to_bytes_be ( ) . 1 ;
80
91
let selector = std:: str:: from_utf8 ( selector) . map_err ( |_| {
@@ -159,49 +170,21 @@ impl<Extension: ExtensionLogic> HintProcessorLogic for ExtendedRuntime<Extension
159
170
output_end,
160
171
} = starknet_hint
161
172
{
162
- let selector = parse_selector ( selector) ?;
163
- let inputs = fetch_cheatcode_input ( vm, input_start, input_end) ?;
164
-
165
- if let CheatcodeHandlingResult :: Handled ( res) = self . extension . handle_cheatcode (
166
- & selector,
167
- inputs,
168
- & mut self . extended_runtime ,
169
- ) ? {
170
- let mut buffer = MemBuffer :: new_segment ( vm) ;
171
- let result_start = buffer. ptr ;
172
- buffer
173
- . write_data ( res. iter ( ) )
174
- . expect ( "Failed to insert cheatcode result to memory" ) ;
175
- let result_end = buffer. ptr ;
176
- insert_value_to_cellref ! ( vm, output_start, result_start) ?;
177
- insert_value_to_cellref ! ( vm, output_end, result_end) ?;
178
- return Ok ( ( ) ) ;
179
- }
180
- }
181
-
182
- if let StarknetHint :: SystemCall { system } = starknet_hint {
183
- let ( cell, offset) = extract_buffer ( system) ;
184
- let system_ptr = get_ptr ( vm, cell, & offset) ?;
185
-
186
- self . verify_syscall_ptr ( system_ptr) ?;
187
-
188
- // We peek into memory to check the selector
189
- let selector = DeprecatedSyscallSelector :: try_from ( felt_to_stark_felt (
190
- & vm. get_integer ( * self . get_mut_syscall_ptr ( ) ) . unwrap ( ) ,
191
- ) ) ?;
192
-
193
- if let SyscallHandlingResult :: Handled ( ( ) ) =
194
- self . extension
195
- . override_system_call ( selector, vm, & mut self . extended_runtime ) ?
196
- {
197
- return Ok ( ( ) ) ;
198
- }
199
- let res = self
200
- . extended_runtime
201
- . execute_hint ( vm, exec_scopes, hint_data, constants) ;
202
- self . extension
203
- . post_syscall_hook ( & selector, & mut self . extended_runtime ) ;
204
- return res;
173
+ return self . execute_cheatcode_hint (
174
+ vm,
175
+ exec_scopes,
176
+ hint_data,
177
+ constants,
178
+ selector,
179
+ & VmIoPointers {
180
+ input_start,
181
+ input_end,
182
+ output_start,
183
+ output_end,
184
+ } ,
185
+ ) ;
186
+ } else if let StarknetHint :: SystemCall { system } = starknet_hint {
187
+ return self . execute_syscall_hint ( vm, exec_scopes, hint_data, constants, system) ;
205
188
}
206
189
}
207
190
self . extended_runtime
@@ -220,6 +203,117 @@ impl<Extension: ExtensionLogic> HintProcessorLogic for ExtendedRuntime<Extension
220
203
}
221
204
}
222
205
206
+ struct VmIoPointers < ' a > {
207
+ input_start : & ' a ResOperand ,
208
+ input_end : & ' a ResOperand ,
209
+ output_start : & ' a CellRef ,
210
+ output_end : & ' a CellRef ,
211
+ }
212
+
213
+ impl < Extension : ExtensionLogic > ExtendedRuntime < Extension > {
214
+ fn execute_cheatcode_hint (
215
+ & mut self ,
216
+ vm : & mut VirtualMachine ,
217
+ exec_scopes : & mut ExecutionScopes ,
218
+ hint_data : & Box < dyn Any > ,
219
+ constants : & HashMap < String , Felt252 > ,
220
+ selector : & BigIntAsHex ,
221
+ vm_io_ptrs : & VmIoPointers ,
222
+ ) -> Result < ( ) , HintError > {
223
+ let selector = parse_selector ( selector) ?;
224
+ let inputs = fetch_cheatcode_input ( vm, vm_io_ptrs. input_start , vm_io_ptrs. input_end ) ?;
225
+
226
+ if let CheatcodeHandlingResult :: Handled ( res) = self . extension . handle_cheatcode (
227
+ & selector,
228
+ inputs. clone ( ) ,
229
+ & mut self . extended_runtime ,
230
+ ) ? {
231
+ let mut buffer = MemBuffer :: new_segment ( vm) ;
232
+ let result_start = buffer. ptr ;
233
+ buffer
234
+ . write_data ( res. iter ( ) )
235
+ . expect ( "Failed to insert cheatcode result to memory" ) ;
236
+ let result_end = buffer. ptr ;
237
+ let output_start = vm_io_ptrs. output_start ;
238
+ let output_end = vm_io_ptrs. output_end ;
239
+ insert_value_to_cellref ! ( vm, output_start, result_start) ?;
240
+ insert_value_to_cellref ! ( vm, output_end, result_end) ?;
241
+ self . propagate_cheatcode_signal ( & selector, inputs) ;
242
+ Ok ( ( ) )
243
+ } else {
244
+ let res = self
245
+ . extended_runtime
246
+ . execute_hint ( vm, exec_scopes, hint_data, constants) ;
247
+ self . extension
248
+ . handle_cheatcode_signal ( & selector, inputs, & mut self . extended_runtime ) ;
249
+ res
250
+ }
251
+ }
252
+ fn execute_syscall_hint (
253
+ & mut self ,
254
+ vm : & mut VirtualMachine ,
255
+ exec_scopes : & mut ExecutionScopes ,
256
+ hint_data : & Box < dyn Any > ,
257
+ constants : & HashMap < String , Felt252 > ,
258
+ system : & ResOperand ,
259
+ ) -> Result < ( ) , HintError > {
260
+ let ( cell, offset) = extract_buffer ( system) ;
261
+ let system_ptr = get_ptr ( vm, cell, & offset) ?;
262
+
263
+ self . verify_syscall_ptr ( system_ptr) ?;
264
+
265
+ // We peek into memory to check the selector
266
+ let selector = DeprecatedSyscallSelector :: try_from ( felt_to_stark_felt (
267
+ & vm. get_integer ( * self . get_mut_syscall_ptr ( ) ) . unwrap ( ) ,
268
+ ) ) ?;
269
+
270
+ if let SyscallHandlingResult :: Handled ( ( ) ) =
271
+ self . extension
272
+ . override_system_call ( selector, vm, & mut self . extended_runtime ) ?
273
+ {
274
+ self . propagate_system_call_signal ( selector, vm) ;
275
+ Ok ( ( ) )
276
+ } else {
277
+ let res = self
278
+ . extended_runtime
279
+ . execute_hint ( vm, exec_scopes, hint_data, constants) ;
280
+ self . extension
281
+ . post_syscall_hook ( & selector, & mut self . extended_runtime ) ;
282
+ res
283
+ }
284
+ }
285
+ }
286
+
287
+ pub trait SignalPropagator {
288
+ fn propagate_system_call_signal (
289
+ & mut self ,
290
+ selector : DeprecatedSyscallSelector ,
291
+ vm : & mut VirtualMachine ,
292
+ ) ;
293
+
294
+ fn propagate_cheatcode_signal ( & mut self , selector : & str , inputs : Vec < Felt252 > ) ;
295
+ }
296
+
297
+ impl < Extension : ExtensionLogic > SignalPropagator for ExtendedRuntime < Extension > {
298
+ fn propagate_system_call_signal (
299
+ & mut self ,
300
+ selector : DeprecatedSyscallSelector ,
301
+ vm : & mut VirtualMachine ,
302
+ ) {
303
+ self . extended_runtime
304
+ . propagate_system_call_signal ( selector, vm) ;
305
+ self . extension
306
+ . handle_system_call_signal ( selector, vm, & mut self . extended_runtime ) ;
307
+ }
308
+
309
+ fn propagate_cheatcode_signal ( & mut self , selector : & str , inputs : Vec < Felt252 > ) {
310
+ self . extended_runtime
311
+ . propagate_cheatcode_signal ( selector, inputs. clone ( ) ) ;
312
+ self . extension
313
+ . handle_cheatcode_signal ( selector, inputs, & mut self . extended_runtime ) ;
314
+ }
315
+ }
316
+
223
317
impl < Extension : ExtensionLogic > SyscallPtrAccess for ExtendedRuntime < Extension > {
224
318
fn get_mut_syscall_ptr ( & mut self ) -> & mut Relocatable {
225
319
self . extended_runtime . get_mut_syscall_ptr ( )
@@ -263,7 +357,7 @@ pub enum CheatcodeHandlingResult {
263
357
}
264
358
265
359
pub trait ExtensionLogic {
266
- type Runtime : HintProcessor + SyscallPtrAccess ;
360
+ type Runtime : HintProcessor + SyscallPtrAccess + SignalPropagator ;
267
361
268
362
fn override_system_call (
269
363
& mut self ,
@@ -291,6 +385,30 @@ pub trait ExtensionLogic {
291
385
) -> Result < CheatcodeHandlingResult , EnhancedHintError > {
292
386
Ok ( CheatcodeHandlingResult :: Forwarded )
293
387
}
388
+
389
+ /// Different from `override_system_call` because it cannot be overridden,
390
+ /// always receives a signal and cannot return an error
391
+ /// Signals are executed in reverse order to normal syscall handlers
392
+ /// Signals are executed after syscall is handled
393
+ fn handle_system_call_signal (
394
+ & mut self ,
395
+ _selector : DeprecatedSyscallSelector ,
396
+ _vm : & mut VirtualMachine ,
397
+ _extended_runtime : & mut Self :: Runtime ,
398
+ ) {
399
+ }
400
+
401
+ /// Different from `handle_cheadcode` because it cannot be overridden,
402
+ /// always receives a signal and cannot return an error
403
+ /// Signals are executed in reverse order to normal cheatcode handlers
404
+ /// Signals are executed after cheatcode is handled
405
+ fn handle_cheatcode_signal (
406
+ & mut self ,
407
+ _selector : & str ,
408
+ _inputs : Vec < Felt252 > ,
409
+ _extended_runtime : & mut Self :: Runtime ,
410
+ ) {
411
+ }
294
412
}
295
413
296
414
// All errors that can be thrown from the hint executor have to be added here,
0 commit comments