Skip to content

Commit 374bdf5

Browse files
starknet_os: output txs_trace from os_run (#8512)
1 parent 9875037 commit 374bdf5

File tree

4 files changed

+125
-9
lines changed

4 files changed

+125
-9
lines changed

crates/starknet_committer_and_os_cli/src/os_cli/commands.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use starknet_api::executable_transaction::{AccountTransaction, Transaction};
1717
use starknet_os::hint_processor::aggregator_hint_processor::AggregatorInput;
1818
use starknet_os::io::os_input::{OsBlockInput, OsHints, StarknetOsInput};
1919
use starknet_os::io::os_output::{StarknetAggregatorRunnerOutput, StarknetOsRunnerOutput};
20-
use starknet_os::runner::{run_aggregator, run_os_stateless};
20+
use starknet_os::runner::{run_aggregator, run_os_stateless, run_os_stateless_for_testing};
2121
use tracing::info;
2222
use tracing::level_filters::LevelFilter;
2323
use tracing_subscriber::reload::Handle;
@@ -88,6 +88,7 @@ pub(crate) fn parse_and_run_os(
8888
input_path: String,
8989
output_path: String,
9090
log_filter_handle: Handle<LevelFilter, Registry>,
91+
include_txs_trace: bool,
9192
) {
9293
let OsCliInput { layout, os_hints, cairo_pie_zip_path } = load_input(input_path);
9394
log_filter_handle
@@ -97,13 +98,21 @@ pub(crate) fn parse_and_run_os(
9798
validate_os_input(&os_hints.os_input);
9899

99100
info!("Running OS...");
100-
let StarknetOsRunnerOutput { cairo_pie, da_segment, metrics, unused_hints, .. } =
101-
run_os_stateless(layout, os_hints)
101+
let (runner_output, txs_trace) = if include_txs_trace {
102+
let (output, traces) = run_os_stateless_for_testing(layout, os_hints)
102103
.unwrap_or_else(|err| panic!("OS run failed. Error: {err}"));
104+
(output, Some(traces))
105+
} else {
106+
let output = run_os_stateless(layout, os_hints)
107+
.unwrap_or_else(|err| panic!("OS run failed. Error: {err}"));
108+
(output, None)
109+
};
110+
111+
let StarknetOsRunnerOutput { cairo_pie, da_segment, metrics, unused_hints, .. } = runner_output;
103112

104113
info!("Finished running OS. Serializing OS output...");
105114
serialize_runner_output(
106-
&OsCliOutput { da_segment, metrics: metrics.into(), unused_hints },
115+
&OsCliOutput { da_segment, metrics: metrics.into(), unused_hints, txs_trace },
107116
output_path,
108117
&cairo_pie,
109118
cairo_pie_zip_path,

crates/starknet_committer_and_os_cli/src/os_cli/run_os_cli.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use cairo_vm::types::relocatable::MaybeRelocatable;
55
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
66
use clap::{Parser, Subcommand};
77
use serde::Serialize;
8+
use starknet_os::hint_processor::os_logger::OsTransactionTrace;
89
use starknet_os::hints::enum_definition::AllHints;
910
use starknet_os::metrics::OsMetrics;
1011
use starknet_types_core::felt::Felt;
@@ -62,6 +63,8 @@ enum Command {
6263
RunOsStateless {
6364
#[clap(flatten)]
6465
io_args: IoArgs,
66+
#[clap(long)]
67+
include_txs_trace: bool,
6568
},
6669
RunAggregator {
6770
#[clap(flatten)]
@@ -81,8 +84,11 @@ pub async fn run_os_cli(
8184
Command::PythonTest(python_test_arg) => {
8285
run_python_test::<OsPythonTestRunner>(python_test_arg).await;
8386
}
84-
Command::RunOsStateless { io_args: IoArgs { input_path, output_path } } => {
85-
parse_and_run_os(input_path, output_path, log_filter_handle);
87+
Command::RunOsStateless {
88+
io_args: IoArgs { input_path, output_path },
89+
include_txs_trace,
90+
} => {
91+
parse_and_run_os(input_path, output_path, log_filter_handle, include_txs_trace);
8692
}
8793
Command::RunAggregator { io_args: IoArgs { input_path, output_path } } => {
8894
parse_and_run_aggregator(input_path, output_path, log_filter_handle);
@@ -141,6 +147,8 @@ pub(crate) struct OsCliOutput {
141147
pub(crate) da_segment: Option<Vec<Felt>>,
142148
pub(crate) metrics: OsCliMetrics,
143149
pub unused_hints: HashSet<AllHints>,
150+
#[serde(skip_serializing_if = "Option::is_none")]
151+
pub(crate) txs_trace: Option<Vec<OsTransactionTrace>>,
144152
}
145153

146154
#[derive(Serialize)]

crates/starknet_os/src/hint_processor/os_logger.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use cairo_vm::types::relocatable::Relocatable;
99
use cairo_vm::vm::errors::memory_errors::MemoryError;
1010
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
1111
use cairo_vm::vm::vm_core::VirtualMachine;
12+
use serde::Serialize;
1213
use starknet_api::executable_transaction::TransactionType;
1314
use starknet_api::transaction::TransactionHash;
1415

@@ -82,6 +83,7 @@ pub trait ResourceFinalizer {
8283
}
8384
}
8485

86+
#[cfg_attr(any(test, feature = "testing"), derive(Serialize, Debug, Clone))]
8587
pub struct SyscallTrace {
8688
selector: SyscallSelector,
8789
is_deprecated: bool,
@@ -142,6 +144,7 @@ impl TryFrom<&SyscallTrace> for String {
142144
}
143145
}
144146

147+
#[cfg_attr(any(test, feature = "testing"), derive(Serialize, Debug, Clone))]
145148
pub struct OsTransactionTrace {
146149
tx_type: TransactionType,
147150
tx_hash: TransactionHash,
@@ -508,4 +511,9 @@ impl OsLogger {
508511
self.txs.push(current_tx);
509512
Ok(())
510513
}
514+
515+
#[cfg(any(test, feature = "testing"))]
516+
pub fn get_txs(&self) -> &Vec<OsTransactionTrace> {
517+
&self.txs
518+
}
511519
}

crates/starknet_os/src/runner.rs

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1+
use std::collections::BTreeMap;
2+
13
use apollo_starknet_os_program::{AGGREGATOR_PROGRAM, OS_PROGRAM};
24
use blockifier::state::state_api::StateReader;
5+
use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
36
use cairo_vm::cairo_run::CairoRunConfig;
47
use cairo_vm::hint_processor::hint_processor_definition::HintProcessor;
58
use cairo_vm::types::layout_name::LayoutName;
69
use cairo_vm::types::program::Program;
710
use cairo_vm::vm::errors::vm_exception::VmException;
811
use cairo_vm::vm::runners::cairo_pie::CairoPie;
912
use cairo_vm::vm::runners::cairo_runner::CairoRunner;
10-
#[cfg(feature = "include_program_output")]
13+
use starknet_api::core::CompiledClassHash;
14+
use starknet_api::deprecated_contract_class::ContractClass;
1115
use starknet_types_core::felt::Felt;
1216

1317
use crate::errors::StarknetOsError;
1418
use crate::hint_processor::aggregator_hint_processor::{AggregatorHintProcessor, AggregatorInput};
1519
use crate::hint_processor::common_hint_processor::CommonHintProcessor;
20+
use crate::hint_processor::os_logger::OsTransactionTrace;
1621
use crate::hint_processor::panicking_state_reader::PanickingStateReader;
1722
use crate::hint_processor::snos_hint_processor::SnosHintProcessor;
18-
use crate::io::os_input::{OsHints, StarknetOsInput};
23+
use crate::io::os_input::{
24+
CachedStateInput,
25+
OsBlockInput,
26+
OsHints,
27+
OsHintsConfig,
28+
StarknetOsInput,
29+
};
1930
use crate::io::os_output::{StarknetAggregatorRunnerOutput, StarknetOsRunnerOutput};
2031
use crate::metrics::OsMetrics;
2132

@@ -105,6 +116,33 @@ pub fn run_os<S: StateReader>(
105116
}: OsHints,
106117
state_readers: Vec<S>,
107118
) -> Result<StarknetOsRunnerOutput, StarknetOsError> {
119+
let (runner_output, snos_hint_processor) = create_hint_processor_and_run_os(
120+
layout,
121+
os_hints_config,
122+
&os_block_inputs,
123+
cached_state_inputs,
124+
deprecated_compiled_classes,
125+
compiled_classes,
126+
state_readers,
127+
public_key_x,
128+
public_key_y,
129+
)?;
130+
131+
generate_os_output(runner_output, snos_hint_processor)
132+
}
133+
134+
#[allow(clippy::too_many_arguments)]
135+
fn create_hint_processor_and_run_os<'a, S: StateReader>(
136+
layout: LayoutName,
137+
os_hints_config: OsHintsConfig,
138+
os_block_inputs: &'a [OsBlockInput],
139+
cached_state_inputs: Vec<CachedStateInput>,
140+
deprecated_compiled_classes: BTreeMap<CompiledClassHash, ContractClass>,
141+
compiled_classes: BTreeMap<CompiledClassHash, CasmContractClass>,
142+
state_readers: Vec<S>,
143+
public_key_x: Felt,
144+
public_key_y: Felt,
145+
) -> Result<(RunnerReturnObject, SnosHintProcessor<'a, S>), StarknetOsError> {
108146
// Create the hint processor.
109147
let mut snos_hint_processor = SnosHintProcessor::new(
110148
&OS_PROGRAM,
@@ -118,8 +156,16 @@ pub fn run_os<S: StateReader>(
118156
public_key_y,
119157
)?;
120158

121-
let mut runner_output = run_program(layout, &OS_PROGRAM, &mut snos_hint_processor)?;
159+
// Run the OS program.
160+
let runner_output = run_program(layout, &OS_PROGRAM, &mut snos_hint_processor)?;
161+
162+
Ok((runner_output, snos_hint_processor))
163+
}
122164

165+
fn generate_os_output(
166+
mut runner_output: RunnerReturnObject,
167+
mut snos_hint_processor: SnosHintProcessor<'_, impl StateReader>,
168+
) -> Result<StarknetOsRunnerOutput, StarknetOsError> {
123169
Ok(StarknetOsRunnerOutput {
124170
#[cfg(feature = "include_program_output")]
125171
os_output: {
@@ -143,6 +189,43 @@ pub fn run_os<S: StateReader>(
143189
})
144190
}
145191

192+
/// Runs the OS the same way as `run_os`. Returns also the transactions trace which are needed for
193+
/// some tests.
194+
#[cfg(any(test, feature = "testing"))]
195+
pub fn run_os_for_testing<S: StateReader>(
196+
layout: LayoutName,
197+
OsHints {
198+
os_hints_config,
199+
os_input:
200+
StarknetOsInput {
201+
os_block_inputs,
202+
cached_state_inputs,
203+
deprecated_compiled_classes,
204+
compiled_classes,
205+
public_key_x,
206+
public_key_y,
207+
},
208+
}: OsHints,
209+
state_readers: Vec<S>,
210+
) -> Result<(StarknetOsRunnerOutput, Vec<OsTransactionTrace>), StarknetOsError> {
211+
let (runner_output, snos_hint_processor) = create_hint_processor_and_run_os(
212+
layout,
213+
os_hints_config,
214+
&os_block_inputs,
215+
cached_state_inputs,
216+
deprecated_compiled_classes,
217+
compiled_classes,
218+
state_readers,
219+
public_key_x,
220+
public_key_y,
221+
)?;
222+
223+
let txs_trace: Vec<OsTransactionTrace> =
224+
snos_hint_processor.get_current_execution_helper().unwrap().os_logger.get_txs().clone();
225+
226+
Ok((generate_os_output(runner_output, snos_hint_processor)?, txs_trace))
227+
}
228+
146229
/// Run the OS with a "stateless" state reader - panics if the state is accessed for data that was
147230
/// not pre-loaded as part of the input.
148231
pub fn run_os_stateless(
@@ -153,6 +236,14 @@ pub fn run_os_stateless(
153236
run_os(layout, os_hints, vec![PanickingStateReader; n_blocks])
154237
}
155238

239+
pub fn run_os_stateless_for_testing(
240+
layout: LayoutName,
241+
os_hints: OsHints,
242+
) -> Result<(StarknetOsRunnerOutput, Vec<OsTransactionTrace>), StarknetOsError> {
243+
let n_blocks = os_hints.os_input.os_block_inputs.len();
244+
run_os_for_testing(layout, os_hints, vec![PanickingStateReader; n_blocks])
245+
}
246+
156247
/// Run the Aggregator.
157248
pub fn run_aggregator(
158249
layout: LayoutName,

0 commit comments

Comments
 (0)