Skip to content

Commit 90b30c8

Browse files
committed
starknet_os: move contract changes methods to os_output_types
1 parent f1ba3da commit 90b30c8

File tree

3 files changed

+92
-85
lines changed

3 files changed

+92
-85
lines changed

crates/starknet_os/src/io/os_output.rs

Lines changed: 5 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use starknet_api::core::{
2020
};
2121
use starknet_api::hash::StarkHash;
2222
use starknet_api::transaction::{L1ToL2Payload, L2ToL1Payload, MessageToL1};
23-
use starknet_types_core::felt::{Felt, NonZeroFelt};
23+
use starknet_types_core::felt::Felt;
2424

2525
use crate::errors::StarknetOsError;
2626
use crate::hints::hint_implementation::stateless_compression::utils::decompress;
@@ -30,26 +30,13 @@ use crate::io::os_output_types::{
3030
FullContractStorageUpdate,
3131
FullOsStateDiff,
3232
PartialCommitmentOsStateDiff,
33-
PartialContractChanges,
34-
PartialContractStorageUpdate,
3533
PartialOsStateDiff,
3634
};
3735
use crate::metrics::OsMetrics;
3836

39-
#[cfg(test)]
40-
#[path = "os_output_test.rs"]
41-
mod os_output_test;
42-
4337
// Cairo DictAccess types for concrete objects.
4438
type CompiledClassHashUpdate = (ClassHash, (Option<CompiledClassHash>, CompiledClassHash));
4539

46-
// Defined in output.cairo
47-
const N_UPDATES_BOUND: NonZeroFelt =
48-
NonZeroFelt::from_felt_unchecked(Felt::from_hex_unchecked("10000000000000000")); // 2^64.
49-
const N_UPDATES_SMALL_PACKING_BOUND: NonZeroFelt =
50-
NonZeroFelt::from_felt_unchecked(Felt::from_hex_unchecked("100")); // 2^8.
51-
const FLAG_BOUND: NonZeroFelt = NonZeroFelt::TWO;
52-
5340
const MESSAGE_TO_L1_CONST_FIELD_SIZE: usize = 3; // from_address, to_address, payload_size.
5441
// from_address, to_address, nonce, selector, payload_size.
5542
const MESSAGE_TO_L2_CONST_FIELD_SIZE: usize = 5;
@@ -67,7 +54,10 @@ pub(crate) fn wrap_missing<T>(val: Option<T>, val_name: &str) -> Result<T, OsOut
6754
val.ok_or_else(|| OsOutputError::MissingFieldInOutput(val_name.to_string()))
6855
}
6956

70-
fn try_into_custom_error<T: TryFrom<Felt>>(val: Felt, val_name: &str) -> Result<T, OsOutputError>
57+
pub(crate) fn try_into_custom_error<T: TryFrom<Felt>>(
58+
val: Felt,
59+
val_name: &str,
60+
) -> Result<T, OsOutputError>
7161
where
7262
<T as TryFrom<Felt>>::Error: std::fmt::Display,
7363
{
@@ -147,73 +137,6 @@ impl MessageToL2 {
147137
}
148138
}
149139

150-
impl FullContractChanges {
151-
pub fn from_output_iter<It: Iterator<Item = Felt> + ?Sized>(
152-
iter: &mut It,
153-
) -> Result<Self, OsOutputError> {
154-
Ok(Self {
155-
addr: wrap_missing_as(iter.next(), "addr")?,
156-
prev_nonce: Nonce(wrap_missing(iter.next(), "prev_nonce")?),
157-
new_nonce: Nonce(wrap_missing_as(iter.next(), "new_nonce")?),
158-
prev_class_hash: ClassHash(wrap_missing_as(iter.next(), "prev_class_hash")?),
159-
new_class_hash: ClassHash(wrap_missing_as(iter.next(), "new_class_hash")?),
160-
storage_changes: {
161-
let n_changes = wrap_missing_as(iter.next(), "n_storage_changes")?;
162-
let mut storage_changes = Vec::with_capacity(n_changes);
163-
for _ in 0..n_changes {
164-
storage_changes.push(FullContractStorageUpdate::from_output_iter(iter)?);
165-
}
166-
storage_changes
167-
},
168-
})
169-
}
170-
}
171-
172-
impl PartialContractChanges {
173-
pub fn from_output_iter<It: Iterator<Item = Felt> + ?Sized>(
174-
iter: &mut It,
175-
) -> Result<Self, OsOutputError> {
176-
let addr = wrap_missing_as(iter.next(), "addr")?;
177-
// Parse packed info.
178-
let nonce_n_changes_two_flags = wrap_missing(iter.next(), "nonce_n_changes_two_flags")?;
179-
180-
// Parse flags.
181-
let (nonce_n_changes_one_flag, class_updated_felt) =
182-
nonce_n_changes_two_flags.div_rem(&FLAG_BOUND);
183-
let class_updated = felt_as_bool(class_updated_felt, "class_updated")?;
184-
let (nonce_n_changes, is_n_updates_small_felt) =
185-
nonce_n_changes_one_flag.div_rem(&FLAG_BOUND);
186-
let is_n_updates_small = felt_as_bool(is_n_updates_small_felt, "is_n_updates_small")?;
187-
188-
// Parse n_changes.
189-
let n_updates_bound =
190-
if is_n_updates_small { N_UPDATES_SMALL_PACKING_BOUND } else { N_UPDATES_BOUND };
191-
let (nonce, n_changes) = nonce_n_changes.div_rem(&n_updates_bound);
192-
193-
// Parse nonce.
194-
let new_nonce = if nonce == Felt::ZERO { None } else { Some(Nonce(nonce)) };
195-
196-
let new_class_hash = if class_updated {
197-
Some(ClassHash(wrap_missing(iter.next(), "new_class_hash")?))
198-
} else {
199-
None
200-
};
201-
Ok(Self {
202-
addr,
203-
new_nonce,
204-
new_class_hash,
205-
storage_changes: {
206-
let n_changes = try_into_custom_error(n_changes, "n_changes")?;
207-
let mut storage_changes = Vec::with_capacity(n_changes);
208-
for _ in 0..n_changes {
209-
storage_changes.push(PartialContractStorageUpdate::from_output_iter(iter)?);
210-
}
211-
storage_changes
212-
},
213-
})
214-
}
215-
}
216-
217140
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize, serde::Serialize))]
218141
#[derive(Debug, PartialEq)]
219142
/// A representation of the state diff of an OS run, with 4 variants that depends on the use_kzg_da

crates/starknet_os/src/io/os_output_types.rs

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
11
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
22
use starknet_api::state::StorageKey;
3-
use starknet_types_core::felt::Felt;
4-
5-
use crate::io::os_output::{wrap_missing, wrap_missing_as, OsOutputError};
3+
use starknet_types_core::felt::{Felt, NonZeroFelt};
4+
5+
use crate::io::os_output::{
6+
felt_as_bool,
7+
try_into_custom_error,
8+
wrap_missing,
9+
wrap_missing_as,
10+
OsOutputError,
11+
};
12+
13+
#[cfg(test)]
14+
#[path = "os_output_types_test.rs"]
15+
mod os_output_types_test;
16+
17+
// Defined in output.cairo
18+
const N_UPDATES_BOUND: NonZeroFelt =
19+
NonZeroFelt::from_felt_unchecked(Felt::from_hex_unchecked("10000000000000000")); // 2^64.
20+
const N_UPDATES_SMALL_PACKING_BOUND: NonZeroFelt =
21+
NonZeroFelt::from_felt_unchecked(Felt::from_hex_unchecked("100")); // 2^8.
22+
const FLAG_BOUND: NonZeroFelt = NonZeroFelt::TWO;
623

724
// Cairo DictAccess types for concrete objects.
825

@@ -94,6 +111,28 @@ pub struct FullContractChanges {
94111
pub(crate) storage_changes: Vec<FullContractStorageUpdate>,
95112
}
96113

114+
impl FullContractChanges {
115+
pub fn from_output_iter<It: Iterator<Item = Felt> + ?Sized>(
116+
iter: &mut It,
117+
) -> Result<Self, OsOutputError> {
118+
Ok(Self {
119+
addr: wrap_missing_as(iter.next(), "addr")?,
120+
prev_nonce: Nonce(wrap_missing(iter.next(), "prev_nonce")?),
121+
new_nonce: Nonce(wrap_missing_as(iter.next(), "new_nonce")?),
122+
prev_class_hash: ClassHash(wrap_missing_as(iter.next(), "prev_class_hash")?),
123+
new_class_hash: ClassHash(wrap_missing_as(iter.next(), "new_class_hash")?),
124+
storage_changes: {
125+
let n_changes = wrap_missing_as(iter.next(), "n_storage_changes")?;
126+
let mut storage_changes = Vec::with_capacity(n_changes);
127+
for _ in 0..n_changes {
128+
storage_changes.push(FullContractStorageUpdate::from_output_iter(iter)?);
129+
}
130+
storage_changes
131+
},
132+
})
133+
}
134+
}
135+
97136
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize, serde::Serialize))]
98137
#[derive(Debug, PartialEq)]
99138
/// Represents the changes in a contract instance, in a partial format.
@@ -108,6 +147,51 @@ pub struct PartialContractChanges {
108147
pub(crate) storage_changes: Vec<PartialContractStorageUpdate>,
109148
}
110149

150+
impl PartialContractChanges {
151+
pub fn from_output_iter<It: Iterator<Item = Felt> + ?Sized>(
152+
iter: &mut It,
153+
) -> Result<Self, OsOutputError> {
154+
let addr = wrap_missing_as(iter.next(), "addr")?;
155+
// Parse packed info.
156+
let nonce_n_changes_two_flags = wrap_missing(iter.next(), "nonce_n_changes_two_flags")?;
157+
158+
// Parse flags.
159+
let (nonce_n_changes_one_flag, class_updated_felt) =
160+
nonce_n_changes_two_flags.div_rem(&FLAG_BOUND);
161+
let class_updated = felt_as_bool(class_updated_felt, "class_updated")?;
162+
let (nonce_n_changes, is_n_updates_small_felt) =
163+
nonce_n_changes_one_flag.div_rem(&FLAG_BOUND);
164+
let is_n_updates_small = felt_as_bool(is_n_updates_small_felt, "is_n_updates_small")?;
165+
166+
// Parse n_changes.
167+
let n_updates_bound =
168+
if is_n_updates_small { N_UPDATES_SMALL_PACKING_BOUND } else { N_UPDATES_BOUND };
169+
let (nonce, n_changes) = nonce_n_changes.div_rem(&n_updates_bound);
170+
171+
// Parse nonce.
172+
let new_nonce = if nonce == Felt::ZERO { None } else { Some(Nonce(nonce)) };
173+
174+
let new_class_hash = if class_updated {
175+
Some(ClassHash(wrap_missing(iter.next(), "new_class_hash")?))
176+
} else {
177+
None
178+
};
179+
Ok(Self {
180+
addr,
181+
new_nonce,
182+
new_class_hash,
183+
storage_changes: {
184+
let n_changes = try_into_custom_error(n_changes, "n_changes")?;
185+
let mut storage_changes = Vec::with_capacity(n_changes);
186+
for _ in 0..n_changes {
187+
storage_changes.push(PartialContractStorageUpdate::from_output_iter(iter)?);
188+
}
189+
storage_changes
190+
},
191+
})
192+
}
193+
}
194+
111195
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize, serde::Serialize))]
112196
#[derive(Debug, PartialEq)]
113197
// An explicit state diff (no KZG commitment applied) in the full output format (with previous

0 commit comments

Comments
 (0)