Skip to content

Commit 9ee1d28

Browse files
feat(starknet_os): os_logger: implement OsLogger::exit_syscall
1 parent 3dca312 commit 9ee1d28

File tree

1 file changed

+61
-3
lines changed

1 file changed

+61
-3
lines changed

crates/starknet_os/src/hint_processor/os_logger.rs

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub enum OsLoggerError {
4141
BuiltinsNotInSameSegment { builtin: BuiltinName, self_ptr: Relocatable, enter_ptr: Relocatable },
4242
#[error("Failed to build builtin pointer map: {0}.")]
4343
BuiltinPtrs(OsHintError),
44+
#[error("Called exit_syscall with empty call stack.")]
45+
CallStackEmpty,
4446
#[error("SyscallTrace should be finalized only once.")]
4547
DoubleFinalize,
4648
#[error("Failed to fetch identifier data for struct {0}.")]
@@ -60,6 +62,8 @@ pub enum OsLoggerError {
6062
ResourceAccessBeforeFinalize,
6163
#[error("The {0} syscall is not supposed to have an inner syscall.")]
6264
UnexpectedParentSyscall(String),
65+
#[error("Unexpected syscall {actual:?}, expected {expected:?}.")]
66+
UnexpectedSyscall { expected: SyscallSelector, actual: SyscallSelector },
6367
#[error("{0}")]
6468
UnknownBuiltin(String),
6569
#[error("Builtin {0} is not in the known sizes mapping {:?}.", BUILTIN_INSTANCE_SIZES)]
@@ -98,6 +102,10 @@ impl SyscallTrace {
98102
pub fn new(selector: SyscallSelector, is_deprecated: bool, tab_count: usize) -> Self {
99103
Self { selector, is_deprecated, tab_count, inner_syscalls: Vec::new(), resources: None }
100104
}
105+
106+
pub fn push_inner_syscall(&mut self, inner: SyscallTrace) {
107+
self.inner_syscalls.push(inner);
108+
}
101109
}
102110

103111
impl ResourceFinalizer for SyscallTrace {
@@ -110,10 +118,10 @@ impl ResourceFinalizer for SyscallTrace {
110118
}
111119
}
112120

113-
impl TryFrom<SyscallTrace> for String {
121+
impl TryFrom<&SyscallTrace> for String {
114122
type Error = OsLoggerError;
115123

116-
fn try_from(trace: SyscallTrace) -> OsLoggerResult<Self> {
124+
fn try_from(trace: &SyscallTrace) -> OsLoggerResult<Self> {
117125
let deprecated_prefix = if trace.is_deprecated { "deprecated " } else { "" };
118126
let indentation = " ".repeat(trace.tab_count + 1);
119127
let resources = trace.get_resources()?;
@@ -145,7 +153,6 @@ impl TryFrom<SyscallTrace> for String {
145153
pub struct OsTransactionTrace {
146154
tx_type: TransactionType,
147155
tx_hash: TransactionHash,
148-
#[allow(dead_code)]
149156
syscalls: Vec<SyscallTrace>,
150157
resources: Option<ExecutionResources>,
151158
}
@@ -154,6 +161,10 @@ impl OsTransactionTrace {
154161
pub fn new(tx_type: TransactionType, tx_hash: TransactionHash) -> Self {
155162
Self { tx_type, tx_hash, syscalls: Vec::new(), resources: None }
156163
}
164+
165+
pub fn push_syscall(&mut self, syscall: SyscallTrace) {
166+
self.syscalls.push(syscall);
167+
}
157168
}
158169

159170
impl ResourceFinalizer for OsTransactionTrace {
@@ -404,4 +415,51 @@ impl OsLogger {
404415

405416
Ok(())
406417
}
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+
}
407465
}

0 commit comments

Comments
 (0)