@@ -41,6 +41,8 @@ pub enum OsLoggerError {
41
41
BuiltinsNotInSameSegment { builtin : BuiltinName , self_ptr : Relocatable , enter_ptr : Relocatable } ,
42
42
#[ error( "Failed to build builtin pointer map: {0}." ) ]
43
43
BuiltinPtrs ( OsHintError ) ,
44
+ #[ error( "Called exit_syscall with empty call stack." ) ]
45
+ CallStackEmpty ,
44
46
#[ error( "SyscallTrace should be finalized only once." ) ]
45
47
DoubleFinalize ,
46
48
#[ error( "Failed to fetch identifier data for struct {0}." ) ]
@@ -60,6 +62,8 @@ pub enum OsLoggerError {
60
62
ResourceAccessBeforeFinalize ,
61
63
#[ error( "The {0} syscall is not supposed to have an inner syscall." ) ]
62
64
UnexpectedParentSyscall ( String ) ,
65
+ #[ error( "Unexpected syscall {actual:?}, expected {expected:?}." ) ]
66
+ UnexpectedSyscall { expected : SyscallSelector , actual : SyscallSelector } ,
63
67
#[ error( "{0}" ) ]
64
68
UnknownBuiltin ( String ) ,
65
69
#[ error( "Builtin {0} is not in the known sizes mapping {:?}." , BUILTIN_INSTANCE_SIZES ) ]
@@ -98,6 +102,10 @@ impl SyscallTrace {
98
102
pub fn new ( selector : SyscallSelector , is_deprecated : bool , tab_count : usize ) -> Self {
99
103
Self { selector, is_deprecated, tab_count, inner_syscalls : Vec :: new ( ) , resources : None }
100
104
}
105
+
106
+ pub fn push_inner_syscall ( & mut self , inner : SyscallTrace ) {
107
+ self . inner_syscalls . push ( inner) ;
108
+ }
101
109
}
102
110
103
111
impl ResourceFinalizer for SyscallTrace {
@@ -110,10 +118,10 @@ impl ResourceFinalizer for SyscallTrace {
110
118
}
111
119
}
112
120
113
- impl TryFrom < SyscallTrace > for String {
121
+ impl TryFrom < & SyscallTrace > for String {
114
122
type Error = OsLoggerError ;
115
123
116
- fn try_from ( trace : SyscallTrace ) -> OsLoggerResult < Self > {
124
+ fn try_from ( trace : & SyscallTrace ) -> OsLoggerResult < Self > {
117
125
let deprecated_prefix = if trace. is_deprecated { "deprecated " } else { "" } ;
118
126
let indentation = " " . repeat ( trace. tab_count + 1 ) ;
119
127
let resources = trace. get_resources ( ) ?;
@@ -145,7 +153,6 @@ impl TryFrom<SyscallTrace> for String {
145
153
pub struct OsTransactionTrace {
146
154
tx_type : TransactionType ,
147
155
tx_hash : TransactionHash ,
148
- #[ allow( dead_code) ]
149
156
syscalls : Vec < SyscallTrace > ,
150
157
resources : Option < ExecutionResources > ,
151
158
}
@@ -154,6 +161,10 @@ impl OsTransactionTrace {
154
161
pub fn new ( tx_type : TransactionType , tx_hash : TransactionHash ) -> Self {
155
162
Self { tx_type, tx_hash, syscalls : Vec :: new ( ) , resources : None }
156
163
}
164
+
165
+ pub fn push_syscall ( & mut self , syscall : SyscallTrace ) {
166
+ self . syscalls . push ( syscall) ;
167
+ }
157
168
}
158
169
159
170
impl ResourceFinalizer for OsTransactionTrace {
@@ -404,4 +415,51 @@ impl OsLogger {
404
415
405
416
Ok ( ( ) )
406
417
}
418
+
419
+ #[ allow( clippy:: too_many_arguments) ]
420
+ pub fn exit_syscall (
421
+ & mut self ,
422
+ selector : SyscallSelector ,
423
+ n_steps : usize ,
424
+ range_check_ptr : Relocatable ,
425
+ ids_data : & HashMap < String , HintReference > ,
426
+ vm : & VirtualMachine ,
427
+ ap_tracking : & ApTracking ,
428
+ os_program : & Program ,
429
+ ) -> OsLoggerResult < ( ) > {
430
+ let mut current_syscall = self . syscall_stack . pop ( ) . ok_or ( OsLoggerError :: CallStackEmpty ) ?;
431
+ let enter_resources_counter =
432
+ self . resource_counter_stack . pop ( ) . ok_or ( OsLoggerError :: CallStackEmpty ) ?;
433
+ // A sanity check to ensure we store the syscall we work on.
434
+ if selector != current_syscall. selector {
435
+ return Err ( OsLoggerError :: UnexpectedSyscall {
436
+ actual : selector,
437
+ expected : current_syscall. selector ,
438
+ } ) ;
439
+ }
440
+
441
+ let exit_resources_counter =
442
+ ResourceCounter :: new ( n_steps, range_check_ptr, ids_data, vm, ap_tracking, os_program) ?;
443
+
444
+ current_syscall
445
+ . finalize_resources ( exit_resources_counter. sub_counter ( & enter_resources_counter) ?) ?;
446
+
447
+ if current_syscall. selector . is_calling_syscall ( ) {
448
+ self . log ( & format ! ( "Exiting {}." , String :: try_from( & current_syscall) ?) , false ) ;
449
+ }
450
+
451
+ match self . syscall_stack . last_mut ( ) {
452
+ Some ( last_call) => {
453
+ last_call. push_inner_syscall ( current_syscall) ;
454
+ }
455
+ None => {
456
+ self . current_tx
457
+ . as_mut ( )
458
+ . ok_or ( OsLoggerError :: NotInTxContext ) ?
459
+ . push_syscall ( current_syscall) ;
460
+ }
461
+ }
462
+
463
+ Ok ( ( ) )
464
+ }
407
465
}
0 commit comments