Skip to content

Commit 007afff

Browse files
starknet_os: parse virtual OS output (#11434)
1 parent e4dd50e commit 007afff

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

crates/starknet_os/src/io/os_output.rs

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,31 @@ pub fn message_l1_from_output_iter<It: Iterator<Item = Felt>>(
107107
Ok(MessageToL1 { from_address, to_address, payload })
108108
}
109109

110+
/// Parses messages to L1 from an output iterator.
111+
/// Reads the segment size, parses all messages, and verifies the segment is fully consumed.
112+
pub fn parse_messages_to_l1<It: Iterator<Item = Felt>>(
113+
iter: &mut It,
114+
) -> Result<Vec<MessageToL1>, OsOutputError> {
115+
let mut messages_to_l1_segment_size: usize =
116+
wrap_missing_as(iter.next(), "messages_to_l1_segment_size")?;
117+
let mut messages_to_l1_iter = iter.take(messages_to_l1_segment_size).peekable();
118+
let mut messages_to_l1 = Vec::new();
119+
120+
while messages_to_l1_iter.peek().is_some() {
121+
let message = message_l1_from_output_iter(&mut messages_to_l1_iter)?;
122+
messages_to_l1_segment_size -= message.payload.0.len() + MESSAGE_TO_L1_CONST_FIELD_SIZE;
123+
messages_to_l1.push(message);
124+
}
125+
126+
assert_eq!(
127+
messages_to_l1_segment_size, 0,
128+
"Expected messages to L1 segment to be consumed, but {messages_to_l1_segment_size} felts \
129+
were left."
130+
);
131+
132+
Ok(messages_to_l1)
133+
}
134+
110135
// TODO(Tzahi): Replace with starknet_api struct after it is updated.
111136
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize, serde::Serialize))]
112137
#[cfg_attr(feature = "testing", derive(Clone, PartialEq))]
@@ -225,21 +250,7 @@ impl TryFromOutputIter for OutputIterParsedData {
225250
};
226251

227252
// Messages to L1 and L2.
228-
let mut messages_to_l1_segment_size =
229-
wrap_missing_as(output_iter.next(), "messages_to_l1_segment_size")?;
230-
let mut messages_to_l1_iter = output_iter.take(messages_to_l1_segment_size).peekable();
231-
let mut messages_to_l1 = Vec::<MessageToL1>::new();
232-
233-
while messages_to_l1_iter.peek().is_some() {
234-
let message = message_l1_from_output_iter(&mut messages_to_l1_iter)?;
235-
messages_to_l1_segment_size -= message.payload.0.len() + MESSAGE_TO_L1_CONST_FIELD_SIZE;
236-
messages_to_l1.push(message);
237-
}
238-
assert_eq!(
239-
messages_to_l1_segment_size, 0,
240-
"Expected messages to L1 segment to be consumed, but {messages_to_l1_segment_size} \
241-
felts were left.",
242-
);
253+
let messages_to_l1 = parse_messages_to_l1(output_iter)?;
243254

244255
let mut messages_to_l2_segment_size =
245256
wrap_missing_as(output_iter.next(), "messages_to_l2_segment_size")?;

crates/starknet_os/src/io/virtual_os_output.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
use cairo_vm::vm::runners::cairo_pie::CairoPie;
2+
use starknet_api::block::BlockNumber;
3+
use starknet_api::hash::StarkHash;
4+
use starknet_api::transaction::MessageToL1;
25
use starknet_types_core::felt::Felt;
36

7+
use crate::io::os_output::{parse_messages_to_l1, wrap_missing, wrap_missing_as, OsOutputError};
8+
9+
/// The parsed output of the virtual OS.
10+
#[derive(Debug)]
11+
pub struct VirtualOsOutput {
12+
/// The output version (currently always 0).
13+
pub version: Felt,
14+
/// The base block number.
15+
pub base_block_number: BlockNumber,
16+
/// The base block hash.
17+
pub base_block_hash: StarkHash,
18+
/// The hash of the Starknet OS config.
19+
pub starknet_os_config_hash: StarkHash,
20+
/// Messages from L2 to L1.
21+
pub messages_to_l1: Vec<MessageToL1>,
22+
}
23+
24+
impl VirtualOsOutput {
25+
/// Parses the virtual OS output from a raw output iterator.
26+
pub fn from_raw_output(raw_output: &[Felt]) -> Result<Self, OsOutputError> {
27+
let mut iter = raw_output.iter().copied();
28+
29+
let version = wrap_missing(iter.next(), "version")?;
30+
let base_block_number = BlockNumber(wrap_missing_as(iter.next(), "base_block_number")?);
31+
let base_block_hash = wrap_missing(iter.next(), "base_block_hash")?;
32+
let starknet_os_config_hash = wrap_missing(iter.next(), "starknet_os_config_hash")?;
33+
let messages_to_l1 = parse_messages_to_l1(&mut iter)?;
34+
35+
Ok(Self {
36+
version,
37+
base_block_number,
38+
base_block_hash,
39+
starknet_os_config_hash,
40+
messages_to_l1,
41+
})
42+
}
43+
}
44+
445
/// The output of the virtual OS runner.
546
#[derive(Debug)]
647
pub struct VirtualOsRunnerOutput {

0 commit comments

Comments
 (0)