diff --git a/.gitattributes b/.gitattributes index 788b92dfeb7..9b0b1e34dc4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,3 +13,7 @@ crates/starknet_transaction_prover/resources/*.zip -diff # Starknet system tests resources - large JSON files. crates/central_systest_blobs/resources/blobs.json -diff crates/central_systest_blobs/resources/preconfirmed_block.json -diff + +# Starknet OS flow tests resources - precompiled contracts. +crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.casm.json -diff +crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.sierra.json -diff diff --git a/.github/workflows/apollo_storage_os_input_ci.yml b/.github/workflows/apollo_storage_os_input_ci.yml index 62d53a43507..6046cda16d4 100644 --- a/.github/workflows/apollo_storage_os_input_ci.yml +++ b/.github/workflows/apollo_storage_os_input_ci.yml @@ -12,6 +12,8 @@ on: - ".github/workflows/apollo_storage_os_input_ci.yml" - "Cargo.lock" - "Cargo.toml" + - "crates/apollo_committer/**" + - "crates/apollo_committer_types/**" - "crates/apollo_storage/**" - "crates/apollo_config/**" - "crates/apollo_infra_utils/**" @@ -20,6 +22,7 @@ on: - "crates/apollo_test_utils/**" - "crates/blockifier/**" - "crates/starknet_api/**" + - "crates/starknet_committer/**" env: RUSTFLAGS: "-D warnings" @@ -57,6 +60,9 @@ jobs: - uses: ./.github/actions/bootstrap with: github_token: ${{ secrets.GITHUB_TOKEN }} + - run: cargo test -p starknet_committer --features os_input + - run: cargo test -p apollo_committer_types --features os_input + - run: cargo test -p apollo_committer --features os_input - run: cargo build -p apollo_batcher --features os_input - run: cargo test -p apollo_batcher --features os_input - run: cargo test -p apollo_reverts --features os_input diff --git a/Cargo.lock b/Cargo.lock index 18b2be42cee..f497dce4f1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,6 +1119,7 @@ dependencies = [ "apollo_infra", "apollo_metrics", "async-trait", + "blockifier", "mockall", "serde", "starknet_api", @@ -1319,7 +1320,7 @@ dependencies = [ "lru 0.12.5", "mockall", "prost", - "rand 0.8.5", + "rand 0.10.1", "rstest", "serde", "starknet-types-core", @@ -1439,8 +1440,8 @@ dependencies = [ "mockito", "num-bigint", "num-rational", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.10.1", + "rand_chacha 0.10.0", "reqwest 0.12.24", "reqwest-middleware 0.4.2", "reqwest-retry", @@ -1675,7 +1676,7 @@ dependencies = [ "metrics-exporter-prometheus", "once_cell", "pretty_assertions", - "rand 0.8.5", + "rand 0.10.1", "rstest", "serde", "serde_json", @@ -1946,7 +1947,7 @@ dependencies = [ "metrics-exporter-prometheus", "mockall", "pretty_assertions", - "rand 0.8.5", + "rand 0.10.1", "reqwest 0.12.24", "reqwest-middleware 0.4.2", "reqwest-retry", @@ -1989,7 +1990,7 @@ dependencies = [ "futures", "libp2p", "mockall", - "rand_chacha 0.3.1", + "rand_chacha 0.10.0", "starknet_api", "tokio", "tracing", @@ -2162,7 +2163,7 @@ dependencies = [ "apollo_test_utils", "lazy_static", "libp2p", - "rand_chacha 0.3.1", + "rand_chacha 0.10.0", "serde", ] @@ -2280,8 +2281,8 @@ dependencies = [ "lazy_static", "mockall", "papyrus_common", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.10.1", + "rand_chacha 0.10.0", "starknet-types-core", "starknet_api", "static_assertions", @@ -2389,7 +2390,7 @@ dependencies = [ "libp2p-swarm-test", "lru 0.12.5", "prost", - "rand 0.8.5", + "rand 0.10.1", "reed-solomon-simd", "rstest", "sha2 0.10.9", @@ -2420,8 +2421,8 @@ dependencies = [ "prost", "prost-build", "protoc-prebuilt", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.10.1", + "rand_chacha 0.10.0", "rstest", "serde", "serde_json", @@ -2483,8 +2484,8 @@ dependencies = [ "papyrus_common", "pretty_assertions", "prometheus-parse", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.10.1", + "rand_chacha 0.10.0", "regex", "reqwest 0.12.24", "serde", @@ -2520,7 +2521,7 @@ dependencies = [ "mockall", "papyrus_common", "pretty_assertions", - "rand_chacha 0.3.1", + "rand_chacha 0.10.0", "serde", "serde_json", "starknet-types-core", @@ -2721,7 +2722,8 @@ dependencies = [ "libp2p", "mockall", "papyrus_common", - "rand_chacha 0.3.1", + "rand 0.10.1", + "rand_chacha 0.10.0", "starknet-types-core", "starknet_api", "tokio", @@ -2810,8 +2812,8 @@ dependencies = [ "pretty_assertions", "primitive-types", "prometheus-parse", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.10.1", + "rand_chacha 0.10.0", "reqwest 0.12.24", "rstest", "schemars 1.1.0", @@ -2853,8 +2855,8 @@ dependencies = [ "pretty_assertions", "primitive-types", "prometheus-parse", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.10.1", + "rand_chacha 0.10.0", "reqwest 0.12.24", "serde", "serde_json", @@ -3828,7 +3830,7 @@ dependencies = [ "paste", "phf", "pretty_assertions", - "rand 0.8.5", + "rand 0.10.1", "regex", "rstest", "rstest_reuse", @@ -5207,7 +5209,7 @@ version = "0.1.0" source = "git+https://github.com/starkware-libs/stwo-circuits?rev=2591775#2591775ae8fd7634eda7b77c471f87c163f65eb1" dependencies = [ "blake2", - "hashbrown 0.16.0", + "hashbrown 0.17.1", "indexmap 2.14.0", "itertools 0.12.1", "num-traits", @@ -5220,7 +5222,7 @@ version = "0.1.0" source = "git+https://github.com/starkware-libs/stwo-circuits?rev=c99a181#c99a181518259c1b3b121c2522371748b9acfa03" dependencies = [ "blake2", - "hashbrown 0.16.0", + "hashbrown 0.17.1", "indexmap 2.14.0", "itertools 0.12.1", "num-traits", @@ -5234,7 +5236,7 @@ version = "0.1.0" source = "git+https://github.com/starkware-libs/stwo-circuits?rev=2591775#2591775ae8fd7634eda7b77c471f87c163f65eb1" dependencies = [ "circuits 0.1.0 (git+https://github.com/starkware-libs/stwo-circuits?rev=2591775)", - "hashbrown 0.16.0", + "hashbrown 0.17.1", "indexmap 2.14.0", "itertools 0.12.1", "num-traits", @@ -5248,7 +5250,7 @@ version = "0.1.0" source = "git+https://github.com/starkware-libs/stwo-circuits?rev=c99a181#c99a181518259c1b3b121c2522371748b9acfa03" dependencies = [ "circuits 0.1.0 (git+https://github.com/starkware-libs/stwo-circuits?rev=c99a181)", - "hashbrown 0.16.0", + "hashbrown 0.17.1", "indexmap 2.14.0", "itertools 0.12.1", "num-traits", @@ -7053,8 +7055,6 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" dependencies = [ - "allocator-api2", - "equivalent", "foldhash 0.2.0", "serde", ] @@ -9975,7 +9975,7 @@ dependencies = [ "cairo-lang-starknet-classes", "indexmap 2.14.0", "pretty_assertions", - "rand 0.8.5", + "rand 0.10.1", "serde", "serde_json", "starknet-types-core", @@ -10978,6 +10978,16 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand_chacha" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" +dependencies = [ + "ppv-lite86", + "rand_core 0.10.1", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -11005,12 +11015,12 @@ checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] name = "rand_distr" -version = "0.4.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +checksum = "4d431c2703ccf129de4d45253c03f49ebb22b97d6ad79ee3ecfc7e3f4862c1d8" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.10.1", ] [[package]] @@ -12861,7 +12871,7 @@ dependencies = [ "paste", "pretty_assertions", "primitive-types", - "rand 0.8.5", + "rand 0.10.1", "rstest", "semver 1.0.27", "serde", @@ -12891,7 +12901,7 @@ dependencies = [ "expect-test", "hex", "pretty_assertions", - "rand 0.8.5", + "rand 0.10.1", "rand_distr", "rstest", "rstest_reuse", @@ -12929,7 +12939,7 @@ dependencies = [ "futures", "indexmap 2.14.0", "pretty_assertions", - "rand 0.8.5", + "rand 0.10.1", "rand_distr", "serde", "serde_json", @@ -12958,7 +12968,7 @@ dependencies = [ "blake2", "clap", "csv", - "rand 0.8.5", + "rand 0.10.1", "serde", "serde_json", "starknet-types-core", @@ -13004,7 +13014,7 @@ dependencies = [ "num-traits", "papyrus_common", "paste", - "rand 0.8.5", + "rand 0.10.1", "regex", "rstest", "serde", @@ -13039,8 +13049,8 @@ dependencies = [ "chrono", "expect-test", "itertools 0.12.1", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.10.1", + "rand_chacha 0.10.0", "rstest", "serde_json", "starknet-core", @@ -13064,9 +13074,8 @@ dependencies = [ "async-recursion", "derive_more", "ethnum", - "num-bigint", "pretty_assertions", - "rand 0.8.5", + "rand 0.10.1", "rstest", "serde", "serde_json", @@ -13235,7 +13244,7 @@ dependencies = [ "dashmap", "educe 0.5.11", "fnv", - "hashbrown 0.16.0", + "hashbrown 0.17.1", "hex", "indexmap 2.14.0", "itertools 0.12.1", @@ -13264,7 +13273,7 @@ dependencies = [ "dashmap", "educe 0.5.11", "fnv", - "hashbrown 0.16.0", + "hashbrown 0.17.1", "hex", "indexmap 2.14.0", "itertools 0.12.1", @@ -13444,7 +13453,7 @@ name = "stwo-constraint-framework" version = "2.1.0" source = "git+https://github.com/starkware-libs/stwo?rev=aeceb74c#aeceb74c58184d7886ebd7f34a7453fee714ca40" dependencies = [ - "hashbrown 0.16.0", + "hashbrown 0.17.1", "itertools 0.12.1", "num-traits", "rand 0.8.5", @@ -13460,7 +13469,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47aca0d5d36d4b015703fb14f162a23cb685e67f8aa08dbe7faf39bd66fe93f1" dependencies = [ - "hashbrown 0.16.0", + "hashbrown 0.17.1", "itertools 0.12.1", "num-traits", "rand 0.8.5", diff --git a/Cargo.toml b/Cargo.toml index 3bfd1eeb14f..58484b87a94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -346,9 +346,9 @@ protoc-prebuilt = "0.3.0" pyo3 = "0.19.1" pyo3-log = "0.8.1" quote = "1.0.26" -rand = "0.8.5" -rand_chacha = "0.3.1" -rand_distr = "0.4.3" +rand = "0.10.0" +rand_chacha = "0.10.0" +rand_distr = "0.6.0" reed-solomon-simd = "3.1.0" regex = "1.10.4" replace_with = "0.1.7" diff --git a/crates/apollo_committer/Cargo.toml b/crates/apollo_committer/Cargo.toml index e2f536c9cec..22e76256be4 100644 --- a/crates/apollo_committer/Cargo.toml +++ b/crates/apollo_committer/Cargo.toml @@ -7,6 +7,7 @@ license.workspace = true description = "State root commitment computation component for the Starknet sequencer." [features] +os_input = ["apollo_committer_types/os_input", "starknet_committer/os_input"] testing = [] [dependencies] diff --git a/crates/apollo_committer/src/committer.rs b/crates/apollo_committer/src/committer.rs index a0cb351f307..888b37a2f5e 100644 --- a/crates/apollo_committer/src/committer.rs +++ b/crates/apollo_committer/src/committer.rs @@ -3,6 +3,12 @@ use std::error::Error; use std::path::PathBuf; use apollo_committer_config::config::{ApolloStorage, CommitterConfig}; +#[cfg(feature = "os_input")] +use apollo_committer_types::committer_types::{ + AccessedKeys, + ReadPathsAndCommitBlockRequest, + ReadPathsAndCommitBlockResponse, +}; use apollo_committer_types::committer_types::{ CommitBlockRequest, CommitBlockResponse, @@ -14,11 +20,15 @@ use apollo_infra::component_definitions::{default_component_start_fn, ComponentS use async_trait::async_trait; use starknet_api::block::BlockNumber; use starknet_api::block_hash::state_diff_hash::calculate_state_diff_hash; +#[cfg(feature = "os_input")] +use starknet_api::core::ContractAddress; use starknet_api::core::{GlobalRoot, StateDiffCommitment}; use starknet_api::hash::PoseidonHash; use starknet_api::state::ThinStateDiff; use starknet_committer::block_committer::commit::commit_block; use starknet_committer::block_committer::input::Input; +#[cfg(feature = "os_input")] +use starknet_committer::block_committer::input::StarknetStorageKey; use starknet_committer::block_committer::measurements_util::{ Action, BlockDurations, @@ -27,12 +37,20 @@ use starknet_committer::block_committer::measurements_util::{ MeasurementsTrait, SingleBlockMeasurements, }; +#[cfg(feature = "os_input")] +use starknet_committer::db::forest_trait::forest_trait_witnesses::{ + ForestStorageWithWitnesses, + PatriciaProofsUpdate, + PatriciaProofsWrite, +}; use starknet_committer::db::forest_trait::{ EmptyInitialReadContext, ForestMetadataType, ForestStorageWithEmptyReadContext, }; use starknet_committer::db::index_db::IndexDb; +#[cfg(feature = "os_input")] +use starknet_committer::db::serde_db_utils::accessed_keys_digest; use starknet_committer::db::serde_db_utils::{ deserialize_felt_no_packing, serialize_felt_no_packing, @@ -40,8 +58,14 @@ use starknet_committer::db::serde_db_utils::{ }; use starknet_committer::forest::deleted_nodes::DeletedNodes; use starknet_committer::forest::filled_forest::FilledForest; +#[cfg(feature = "os_input")] +use starknet_committer::patricia_merkle_tree::tree::{LeavesRequest, SortedLeavesRequest}; +#[cfg(feature = "os_input")] +use starknet_patricia_storage::errors::SerializationError; use starknet_patricia_storage::map_storage::CachedStorage; use starknet_patricia_storage::rocksdb_storage::RocksDbStorage; +#[cfg(feature = "os_input")] +use starknet_patricia_storage::storage_trait::ImmutableReadOnlyStorage; use starknet_patricia_storage::storage_trait::{DbValue, Storage}; use tracing::{debug, error, info, warn}; @@ -91,6 +115,39 @@ struct CommitStateDiffOutput { pub global_root: GlobalRoot, } +/// Classification of a commit request's `height` w.r.t the committer offset. +enum CommitBlockHeightPlan { + /// `height` is already committed; return the stored global root without writing. + Historical { global_root: GlobalRoot }, + /// `height` is the next uncommitted offset; inputs are validated and ready to commit. + CommitTip { state_diff_commitment: StateDiffCommitment }, +} + +fn commit_tip_metadata_bundle( + height: BlockNumber, + global_root: GlobalRoot, + state_diff_commitment: StateDiffCommitment, +) -> (HashMap, BlockNumber) { + let next_offset = height.unchecked_next(); + ( + HashMap::from([ + ( + ForestMetadataType::CommitmentOffset, + DbValue(DbBlockNumber(next_offset).serialize().to_vec()), + ), + ( + ForestMetadataType::StateRoot(DbBlockNumber(height)), + serialize_felt_no_packing(global_root.0), + ), + ( + ForestMetadataType::StateDiffHash(DbBlockNumber(height)), + serialize_felt_no_packing(state_diff_commitment.0.0), + ), + ]), + next_offset, + ) +} + /// Apollo committer. Maintains the Starknet state tries in persistent storage. pub struct Committer where @@ -152,6 +209,50 @@ where "Received request to commit block number {height} with state diff \ {state_diff_commitment:?}" ); + + match self.commit_or_load(&state_diff, state_diff_commitment, height).await? { + CommitBlockHeightPlan::Historical { global_root } => { + Ok(CommitBlockResponse { global_root }) + } + CommitBlockHeightPlan::CommitTip { state_diff_commitment } => { + // Happy flow. Commits the state diff and returns the computed global root. + debug!( + "Committing block number {height} with state diff {state_diff_commitment:?}" + ); + let mut block_measurements = SingleBlockMeasurements::default(); + block_measurements.start_measurement(Action::EndToEnd); + let CommitStateDiffOutput { filled_forest, global_root, deleted_nodes } = + self.commit_state_diff(state_diff, &mut block_measurements).await?; + let (metadata, next_offset) = + commit_tip_metadata_bundle(height, global_root, state_diff_commitment); + info!( + "For block number {height}, writing filled forest to storage with metadata: \ + {metadata:?}, delete {} nodes", + deleted_nodes.len() + ); + block_measurements.start_measurement(Action::Write); + let n_write_entries = self + .forest_storage + .write_with_metadata(&filled_forest, metadata, deleted_nodes) + .await + .map_err(|err| self.map_internal_error(err))?; + block_measurements.attempt_to_stop_measurement(Action::Write, n_write_entries).ok(); + block_measurements.attempt_to_stop_measurement(Action::EndToEnd, 0).ok(); + update_metrics(height, &block_measurements.block_measurement); + self.update_offset(next_offset); + Ok(CommitBlockResponse { global_root }) + } + } + } + + /// Either load the committed global root for a past `height`, or validate inputs and return + /// the state-diff commitment for committing the chain tip at `self.offset`. + async fn commit_or_load( + &mut self, + state_diff: &ThinStateDiff, + state_diff_commitment: Option, + height: BlockNumber, + ) -> CommitterResult { if height > self.offset { // Request to commit a future height. // Returns an error, indicating the committer has a hole in the state diff series. @@ -164,7 +265,7 @@ where let state_diff_commitment = match state_diff_commitment { Some(commitment) => { if self.config.verify_state_diff_hash { - let calculated_commitment = calculate_state_diff_hash(&state_diff); + let calculated_commitment = calculate_state_diff_hash(state_diff); if commitment != calculated_commitment { return Err(CommitterError::StateDiffHashMismatch { provided_commitment: commitment, @@ -175,8 +276,9 @@ where } commitment } - None => calculate_state_diff_hash(&state_diff), + None => calculate_state_diff_hash(state_diff), }; + if height < self.offset { // Request to commit an old height. // Might be ok if the caller didn't get the results properly. @@ -196,46 +298,10 @@ where } // Returns the precomputed global root. let db_global_root = self.load_global_root(height).await?; - return Ok(CommitBlockResponse { global_root: db_global_root }); + return Ok(CommitBlockHeightPlan::Historical { global_root: db_global_root }); } - // Happy flow. Commits the state diff and returns the computed global root. - debug!("Committing block number {height} with state diff {state_diff_commitment:?}"); - let mut block_measurements = SingleBlockMeasurements::default(); - block_measurements.start_measurement(Action::EndToEnd); - let CommitStateDiffOutput { filled_forest, global_root, deleted_nodes } = - self.commit_state_diff(state_diff, &mut block_measurements).await?; - let next_offset = height.unchecked_next(); - let metadata = HashMap::from([ - ( - ForestMetadataType::CommitmentOffset, - DbValue(DbBlockNumber(next_offset).serialize().to_vec()), - ), - ( - ForestMetadataType::StateRoot(DbBlockNumber(height)), - serialize_felt_no_packing(global_root.0), - ), - ( - ForestMetadataType::StateDiffHash(DbBlockNumber(height)), - serialize_felt_no_packing(state_diff_commitment.0.0), - ), - ]); - info!( - "For block number {height}, writing filled forest to storage with metadata: \ - {metadata:?}, delete {} nodes", - deleted_nodes.len() - ); - block_measurements.start_measurement(Action::Write); - let n_write_entries = self - .forest_storage - .write_with_metadata(&filled_forest, metadata, deleted_nodes) - .await - .map_err(|err| self.map_internal_error(err))?; - block_measurements.attempt_to_stop_measurement(Action::Write, n_write_entries).ok(); - block_measurements.attempt_to_stop_measurement(Action::EndToEnd, 0).ok(); - update_metrics(height, &block_measurements.block_measurement); - self.update_offset(next_offset); - Ok(CommitBlockResponse { global_root }) + Ok(CommitBlockHeightPlan::CommitTip { state_diff_commitment }) } /// Applies the given state diff to revert the changes of the given height. @@ -405,9 +471,192 @@ where } fn map_internal_error(&self, err: E) -> CommitterError { + self.map_internal_error_at_height(self.offset, err) + } + + fn map_internal_error_at_height( + &self, + height: BlockNumber, + err: E, + ) -> CommitterError { let error_message = format!("{err:?}: {err}"); - error!("Error committing block number {0}. {error_message}.", self.offset); - CommitterError::Internal { height: self.offset, message: error_message } + error!("Error committing block number {height}. {error_message}."); + CommitterError::Internal { height, message: error_message } + } +} + +#[cfg(feature = "os_input")] +impl Committer +where + S: StorageConstructor + ImmutableReadOnlyStorage + 'static, + ForestDB: ForestStorageWithWitnesses, +{ + /// Commits the next block and returns merged Patricia witness facts for OS input, persisting + /// digest + payload for idempotent replay. + pub async fn read_paths_and_commit_block( + &mut self, + ReadPathsAndCommitBlockRequest { + commit: CommitBlockRequest { state_diff, state_diff_commitment, height }, + accessed_keys: AccessedKeys { storage_keys, accessed_contracts, accessed_class_hashes }, + }: ReadPathsAndCommitBlockRequest, + ) -> CommitterResult { + let class_hashes: Vec<_> = accessed_class_hashes.iter().copied().collect(); + let contract_addresses: Vec<_> = accessed_contracts.iter().copied().collect(); + let contract_storage_keys = storage_keys.iter().fold( + HashMap::>::new(), + |mut accumulator, (address, key)| { + accumulator.entry(*address).or_default().push(StarknetStorageKey(*key)); + accumulator + }, + ); + let mut leaves_request = LeavesRequest::from_accessed_leaves( + &class_hashes, + &contract_addresses, + &contract_storage_keys, + ); + info!( + "read_paths_and_commit_block: height {height}, accessed keys len {}, state diff len {}", + leaves_request.total_leaf_count(), + state_diff.len(), + ); + let sorted_leaves: SortedLeavesRequest<'_> = (&mut leaves_request).into(); + let digest = accessed_keys_digest(&sorted_leaves); + + match self.commit_or_load(&state_diff, state_diff_commitment, height).await? { + CommitBlockHeightPlan::Historical { global_root } => { + let stored_digest = self.load_witnesses_digest(height).await?; + if stored_digest != Some(digest) { + return Err(CommitterError::AccessedKeysDigestMismatch { + height, + stored: stored_digest, + expected: digest, + }); + } + let proofs = self + .forest_storage + .read_witnesses(height) + .await + .map_err(|error| self.map_internal_error_at_height(height, error))?; + let proofs = proofs.ok_or(CommitterError::MissingPatriciaPaths { height })?; + Ok(ReadPathsAndCommitBlockResponse { global_root, patricia_proofs: proofs }) + } + // Flow overview: + // 1. Fetch patricia paths for the accessed keys. + // 2. Compute the updates from the state diff (commit) but avoid updating the underlying + // DB in order to guarantee atomicity. + // 3. Fetch patricia paths for the post-commit tries, via running step 1 against a two + // layer storage composed from the underlying storage and the modifications from 2. + // 4. Merge the two sets of patricia paths and write the result to the storage. + // 5. Update the commitment offset and return the global root and the patricia proofs. + CommitBlockHeightPlan::CommitTip { state_diff_commitment } => { + let pre_roots = self + .forest_storage + .read_roots(ForestDB::InitialReadContext::create_empty()) + .await + .map_err(|e| self.map_internal_error(e))?; + let mut patricia_proofs = self + .forest_storage + .fetch_patricia_witnesses( + pre_roots.classes_trie_root_hash, + pre_roots.contracts_trie_root_hash, + sorted_leaves.class_sorted, + sorted_leaves.contract_sorted, + &sorted_leaves.storage_sorted, + None, + ) + .await + .map_err(|e| CommitterError::PatriciaPathsCollectionFailed { + height, + message: format!("pre-commit witness paths: {e:?}"), + })?; + + let mut block_measurements = SingleBlockMeasurements::default(); + block_measurements.start_measurement(Action::EndToEnd); + let CommitStateDiffOutput { filled_forest, global_root, deleted_nodes } = + self.commit_state_diff(state_diff, &mut block_measurements).await?; + let post_roots = filled_forest.state_roots(); + + let forest_updates = ForestDB::serialize_forest(&filled_forest) + .map_err(|e| self.map_internal_error(e))?; + + let proof_after = self + .forest_storage + .fetch_patricia_witnesses( + post_roots.classes_trie_root_hash, + post_roots.contracts_trie_root_hash, + sorted_leaves.class_sorted, + sorted_leaves.contract_sorted, + &sorted_leaves.storage_sorted, + Some(forest_updates), + ) + .await + .map_err(|e| CommitterError::PatriciaPathsCollectionFailed { + height, + message: format!("post-commit witness paths: {e:?}"), + })?; + + patricia_proofs.extend(proof_after); + + let (metadata, next_offset) = + commit_tip_metadata_bundle(height, global_root, state_diff_commitment); + let witness_node_count = patricia_proofs.classes_trie_proof.len() + + patricia_proofs.contracts_trie_proof.nodes.len() + + patricia_proofs.contracts_trie_proof.leaves.len() + + patricia_proofs + .contracts_trie_storage_proofs + .values() + .map(|proof| proof.len()) + .sum::(); + info!( + "For block number {height}, writing filled forest and {witness_node_count} \ + witness nodes to storage with metadata: {metadata:?}, delete {} nodes", + deleted_nodes.len() + ); + block_measurements.start_measurement(Action::Write); + let n_write_entries = self + .forest_storage + .write_with_metadata_and_witnesses( + &filled_forest, + metadata, + deleted_nodes, + PatriciaProofsUpdate::Write(PatriciaProofsWrite { + block_number: height, + keys_digest: digest, + witnesses: patricia_proofs.clone(), + }), + ) + .await + .map_err(|e: SerializationError| self.map_internal_error(e))?; + block_measurements.attempt_to_stop_measurement(Action::Write, n_write_entries).ok(); + block_measurements.attempt_to_stop_measurement(Action::EndToEnd, 0).ok(); + update_metrics(height, &block_measurements.block_measurement); + self.update_offset(next_offset); + Ok(ReadPathsAndCommitBlockResponse { global_root, patricia_proofs }) + } + } + } + + async fn load_witnesses_digest( + &mut self, + block_number: BlockNumber, + ) -> CommitterResult> { + let digest_raw = self + .forest_storage + .read_metadata(ForestMetadataType::AccessedKeysDigest(DbBlockNumber(block_number))) + .await + .map_err(|error| self.map_internal_error_at_height(block_number, error))?; + + digest_raw + .map(|digest_raw| { + digest_raw.0.as_slice().try_into().map_err(|_| CommitterError::Internal { + height: block_number, + message: format!( + "Invalid OS witnesses digest length {} (expected 32)", + digest_raw.0.len() + ), + }) + }) + .transpose() } } diff --git a/crates/apollo_committer_types/Cargo.toml b/crates/apollo_committer_types/Cargo.toml index 08010cd1578..2fbbe8d44d5 100644 --- a/crates/apollo_committer_types/Cargo.toml +++ b/crates/apollo_committer_types/Cargo.toml @@ -7,12 +7,14 @@ license.workspace = true description = "Type definitions and interfaces for the Apollo committer component." [features] +os_input = ["dep:blockifier", "starknet_committer/os_input"] testing = ["mockall", "tokio"] [dependencies] apollo_infra.workspace = true apollo_metrics.workspace = true async-trait.workspace = true +blockifier = { workspace = true, features = ["transaction_serde"], optional = true } mockall = { workspace = true, optional = true } serde.workspace = true starknet_api.workspace = true diff --git a/crates/apollo_committer_types/src/committer_types.rs b/crates/apollo_committer_types/src/committer_types.rs index ba17c250a05..f43ef92e161 100644 --- a/crates/apollo_committer_types/src/committer_types.rs +++ b/crates/apollo_committer_types/src/committer_types.rs @@ -1,7 +1,11 @@ +#[cfg(feature = "os_input")] +pub use blockifier::state::accessed_keys::AccessedKeys; use serde::{Deserialize, Serialize}; use starknet_api::block::BlockNumber; use starknet_api::core::{GlobalRoot, StateDiffCommitment}; use starknet_api::state::ThinStateDiff; +#[cfg(feature = "os_input")] +use starknet_committer::patricia_merkle_tree::types::StarknetForestProofs; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CommitBlockRequest { @@ -32,3 +36,19 @@ pub enum RevertBlockResponse { // Nothing to revert. A future block that has not been committed. Uncommitted, } + +/// Commit a block and return merged Patricia witness proofs for OS input (pre- and post-commit +/// paths). +#[cfg(feature = "os_input")] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ReadPathsAndCommitBlockRequest { + pub commit: CommitBlockRequest, + pub accessed_keys: AccessedKeys, +} + +#[cfg(feature = "os_input")] +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ReadPathsAndCommitBlockResponse { + pub global_root: GlobalRoot, + pub patricia_proofs: StarknetForestProofs, +} diff --git a/crates/apollo_committer_types/src/errors.rs b/crates/apollo_committer_types/src/errors.rs index d0cb28dd63c..5142d86cf4c 100644 --- a/crates/apollo_committer_types/src/errors.rs +++ b/crates/apollo_committer_types/src/errors.rs @@ -48,6 +48,20 @@ pub enum CommitterError { calculated_commitment: StateDiffCommitment, height: BlockNumber, }, + /// Patricia trie path collection for OS input failed. + #[cfg(feature = "os_input")] + #[error("Failed Patricia paths collection at block {height}: {message}")] + PatriciaPathsCollectionFailed { height: BlockNumber, message: String }, + /// Stored accessed-keys digest does not match the request (or no digest was stored). + #[cfg(feature = "os_input")] + #[error( + "Accessed-keys digest mismatch at block {height}: expected {expected:?}, stored {stored:?}" + )] + AccessedKeysDigestMismatch { height: BlockNumber, stored: Option<[u8; 32]>, expected: [u8; 32] }, + /// Merged Patricia witness paths are missing for replay. + #[cfg(feature = "os_input")] + #[error("Missing Patricia paths for block {height}")] + MissingPatriciaPaths { height: BlockNumber }, } pub type CommitterResult = Result; diff --git a/crates/apollo_consensus/src/simulation_test.rs b/crates/apollo_consensus/src/simulation_test.rs index 832bdcb61c3..2eb966900c6 100644 --- a/crates/apollo_consensus/src/simulation_test.rs +++ b/crates/apollo_consensus/src/simulation_test.rs @@ -14,8 +14,8 @@ use apollo_consensus_config::config::TimeoutsConfig; use apollo_protobuf::consensus::{ProposalInit, Vote, VoteType}; use lazy_static::lazy_static; use rand::rngs::StdRng; -use rand::seq::SliceRandom; -use rand::{Rng, SeedableRng}; +use rand::seq::IndexedRandom; +use rand::{RngExt, SeedableRng}; use starknet_api::block::BlockNumber; use starknet_api::crypto::utils::RawSignature; use starknet_types_core::felt::Felt; @@ -149,12 +149,12 @@ fn get_leader_index(seed: u64, total_nodes: usize, round: Round) -> usize { let round_seed = seed.wrapping_mul(31).wrapping_add(round_u64); let mut round_rng = StdRng::seed_from_u64(round_seed); - let random_value: f64 = round_rng.gen(); + let random_value: f64 = round_rng.random(); if random_value < NODE_0_LEADER_PROBABILITY { NODE_UNDER_TEST } else { - round_rng.gen_range(1..total_nodes) + round_rng.random_range(1..total_nodes) } } @@ -278,7 +278,7 @@ impl DiscreteEventSimulation { /// Other events are scheduled with probability keep_ratio. fn schedule_at_tick(&mut self, tick: u64, event: InputEvent) { let should_enqueue = - matches!(event, InputEvent::Internal(_)) || self.rng.gen_bool(self.keep_ratio); + matches!(event, InputEvent::Internal(_)) || self.rng.random_bool(self.keep_ratio); if should_enqueue { self.pending_events.push(TimedEvent { tick, event }); } @@ -295,10 +295,10 @@ impl DiscreteEventSimulation { round_start_tick: u64, ) { let round_end_tick = round_start_tick + ROUND_DURATION; - let prevote_tick = (round_start_tick + self.rng.gen_range(PREVOTE_ARRIVAL_DELAY_RANGE)) + let prevote_tick = (round_start_tick + self.rng.random_range(PREVOTE_ARRIVAL_DELAY_RANGE)) .min(round_end_tick - 1); let precommit_tick = (prevote_tick - + self.rng.gen_range(PRECOMMIT_AFTER_PREVOTE_DELAY_RANGE)) + + self.rng.random_range(PRECOMMIT_AFTER_PREVOTE_DELAY_RANGE)) .min(round_end_tick); self.schedule_at_tick( @@ -349,7 +349,7 @@ impl DiscreteEventSimulation { // 1. Proposal from leader (if not NODE_0 and leader is honest) if leader_idx < self.honest_nodes { let proposal_tick = (round_start_tick - + self.rng.gen_range(PROPOSAL_ARRIVAL_DELAY_RANGE)) + + self.rng.random_range(PROPOSAL_ARRIVAL_DELAY_RANGE)) .min(round_start_tick + ROUND_DURATION); self.schedule_at_tick( proposal_tick, @@ -566,7 +566,7 @@ impl DiscreteEventSimulation { match req { SMRequest::StartValidateProposal(init) => { - let delay = self.rng.gen_range(VALIDATION_DELAY_RANGE); + let delay = self.rng.random_range(VALIDATION_DELAY_RANGE); let validate_finish_tick = self.current_tick + delay; let proposal_commitment = Some(proposal_commitment_for_round(init.round, false)); @@ -578,7 +578,7 @@ impl DiscreteEventSimulation { self.schedule_at_tick(validate_finish_tick, InputEvent::Internal(result)); } SMRequest::StartBuildProposal(round) => { - let delay = self.rng.gen_range(BUILD_PROPOSAL_DELAY_RANGE); + let delay = self.rng.random_range(BUILD_PROPOSAL_DELAY_RANGE); let build_finish_tick = self.current_tick + delay; let proposal_commitment = Some(proposal_commitment_for_round(round, false)); let result = StateMachineEvent::FinishedBuilding(proposal_commitment, round); @@ -591,15 +591,15 @@ impl DiscreteEventSimulation { SMRequest::ScheduleTimeout(step, round) => { let (delay, event) = match step { Step::Propose => ( - self.rng.gen_range(TIMEOUT_PROPOSE_DELAY_RANGE), + self.rng.random_range(TIMEOUT_PROPOSE_DELAY_RANGE), StateMachineEvent::TimeoutPropose(round), ), Step::Prevote => ( - self.rng.gen_range(TIMEOUT_PREVOTE_DELAY_RANGE), + self.rng.random_range(TIMEOUT_PREVOTE_DELAY_RANGE), StateMachineEvent::TimeoutPrevote(round), ), Step::Precommit => ( - self.rng.gen_range(TIMEOUT_PRECOMMIT_DELAY_RANGE), + self.rng.random_range(TIMEOUT_PRECOMMIT_DELAY_RANGE), StateMachineEvent::TimeoutPrecommit(round), ), }; @@ -747,7 +747,7 @@ fn test_consensus_simulation(keep_ratio: f64, honest_nodes: usize) { if start.elapsed() >= timeout { break; } - let seed = rand::thread_rng().gen(); + let seed = rand::rng().random(); println!( "run: keep_ratio={keep_ratio}, honest_nodes={honest_nodes}, \ total_nodes={total_nodes}, num_rounds={num_rounds}, seed={seed}" diff --git a/crates/apollo_consensus_orchestrator/resources/central_blob.json b/crates/apollo_consensus_orchestrator/resources/central_blob.json index cef76c4f5d6..5f8ec5b4708 100644 --- a/crates/apollo_consensus_orchestrator/resources/central_blob.json +++ b/crates/apollo_consensus_orchestrator/resources/central_blob.json @@ -37,7 +37,7 @@ "price_in_fri": "0xd" }, "use_kzg_da": true, - "starknet_version": "0.14.3" + "starknet_version": "0.14.4" } }, "compressed_state_diff": { @@ -77,7 +77,7 @@ "price_in_fri": "0xd" }, "use_kzg_da": true, - "starknet_version": "0.14.3" + "starknet_version": "0.14.4" } }, "bouncer_weights": { diff --git a/crates/apollo_consensus_orchestrator/resources/central_blob_empty_or_none_fields.json b/crates/apollo_consensus_orchestrator/resources/central_blob_empty_or_none_fields.json index 480fd1c6dfc..83861bffb93 100644 --- a/crates/apollo_consensus_orchestrator/resources/central_blob_empty_or_none_fields.json +++ b/crates/apollo_consensus_orchestrator/resources/central_blob_empty_or_none_fields.json @@ -37,7 +37,7 @@ "price_in_fri": "0xd" }, "use_kzg_da": true, - "starknet_version": "0.14.3" + "starknet_version": "0.14.4" } }, "compressed_state_diff": null, diff --git a/crates/apollo_consensus_orchestrator/resources/central_state_diff.json b/crates/apollo_consensus_orchestrator/resources/central_state_diff.json index 1b9101dff97..7165c25def2 100644 --- a/crates/apollo_consensus_orchestrator/resources/central_state_diff.json +++ b/crates/apollo_consensus_orchestrator/resources/central_state_diff.json @@ -34,7 +34,7 @@ "price_in_fri": "0xd" }, "sequencer_address": "0x7", - "starknet_version": "0.14.3", + "starknet_version": "0.14.4", "use_kzg_da": true } } diff --git a/crates/apollo_consensus_orchestrator/src/dynamic_gas_price/test.rs b/crates/apollo_consensus_orchestrator/src/dynamic_gas_price/test.rs index 5e1305a42cd..efcaac491f0 100644 --- a/crates/apollo_consensus_orchestrator/src/dynamic_gas_price/test.rs +++ b/crates/apollo_consensus_orchestrator/src/dynamic_gas_price/test.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use apollo_versioned_constants::VersionedConstants; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use rand_chacha::ChaCha8Rng; use rstest::rstest; use starknet_api::block::{BlockNumber, GasPrice}; @@ -225,11 +225,11 @@ fn test_honest_proposer_always_passes_validation_fuzzed() { let margin_ppt = VersionedConstants::latest_constants().fee_proposal_margin_ppt; let mut rng = ChaCha8Rng::seed_from_u64(0xDEADBEEF); for _ in 0..10_000 { - let fee_actual_value = rng.gen_range(1u128..1_000_000_000_000_000_000); - let strk_usd_rate = rng.gen_range(1u128..2 * 10u128.pow(18)); + let fee_actual_value = rng.random_range(1u128..1_000_000_000_000_000_000); + let strk_usd_rate = rng.random_range(1u128..2 * 10u128.pow(18)); let fee_actual = GasPrice(fee_actual_value); let target = compute_fee_target(TARGET_ATTO_USD_PER_L2_GAS, strk_usd_rate); - let oracle_result = if rng.gen_bool(0.1) { None } else { target }; + let oracle_result = if rng.random_bool(0.1) { None } else { target }; let proposal = compute_fee_proposal(oracle_result, fee_actual, margin_ppt); assert!( validator_accepts(fee_actual, proposal, margin_ppt), diff --git a/crates/apollo_integration_tests/resources/proof_flow/proof.bin b/crates/apollo_integration_tests/resources/proof_flow/proof.bin index 9c9b6528e7b..e88e2afb776 100644 Binary files a/crates/apollo_integration_tests/resources/proof_flow/proof.bin and b/crates/apollo_integration_tests/resources/proof_flow/proof.bin differ diff --git a/crates/apollo_integration_tests/resources/proof_flow/proof_facts.json b/crates/apollo_integration_tests/resources/proof_flow/proof_facts.json index 76f4608f5b2..bb2849cefb0 100644 --- a/crates/apollo_integration_tests/resources/proof_flow/proof_facts.json +++ b/crates/apollo_integration_tests/resources/proof_flow/proof_facts.json @@ -4,7 +4,7 @@ "0x6ecb73d21c7d98ddd4148f5bcd91cc2747c65364245fbf32a63b05cca1685c2", "0x5649525455414c5f534e4f5330", "0x0", - "0x16bcf42661609d3e6095235597f329fa8e35bf79082997a40149fdb2ef6975a", + "0x71ede7bbd28575766b160412ed2a577413db7fabd4cf4fe140d55981714fb8d", "0x1ad2c853941f7f8abefca26097b05c0dfdf62626254533a118936a9939397f8", "0x0" ] \ No newline at end of file diff --git a/crates/apollo_integration_tests/src/monitoring_utils.rs b/crates/apollo_integration_tests/src/monitoring_utils.rs index 748bafa7d64..0df0f7ad1ab 100644 --- a/crates/apollo_integration_tests/src/monitoring_utils.rs +++ b/crates/apollo_integration_tests/src/monitoring_utils.rs @@ -3,7 +3,7 @@ use apollo_consensus::metrics::CONSENSUS_DECISIONS_REACHED_BY_CONSENSUS; use apollo_infra_utils::run_until::run_until; use apollo_infra_utils::tracing::{CustomLogger, TraceLevel}; use apollo_metrics::metrics::MetricDetails; -use apollo_monitoring_endpoint::test_utils::MonitoringClient; +use apollo_monitoring_endpoint::test_utils::{MonitoringClient, MonitoringClientError}; use apollo_state_sync_metrics::metrics::{ STATE_SYNC_BODY_MARKER, STATE_SYNC_CLASS_MANAGER_MARKER, @@ -204,15 +204,38 @@ pub async fn await_txs_accepted( pub async fn sequencer_num_accepted_txs(monitoring_client: &MonitoringClient) -> usize { // If the sequencer accepted txs, sync should process them and update the respective metric. - monitoring_client - .get_metric::(STATE_SYNC_PROCESSED_TRANSACTIONS.get_name()) - .await - .unwrap() + // Return 0 if the metric isn't registered yet (race with StateSyncRunner startup). + match monitoring_client.get_metric::(STATE_SYNC_PROCESSED_TRANSACTIONS.get_name()).await + { + Ok(count) => count, + Err(MonitoringClientError::MetricNotFound { .. }) => 0, + Err(e) => panic!("Failed to get processed transactions metric: {e}"), + } } pub async fn assert_no_reverted_txs(monitoring_client: &MonitoringClient, sequencer_idx: usize) { - let reverted_count = - monitoring_client.get_metric::(REVERTED_TRANSACTIONS.get_name()).await.unwrap(); + let get_metric_closure = + || async { monitoring_client.get_metric::(REVERTED_TRANSACTIONS.get_name()).await }; + let condition = |result: &Result| result.is_ok(); + let logger = CustomLogger::new( + TraceLevel::Info, + Some(format!( + "Waiting for reverted transactions metric to be registered for sequencer \ + {sequencer_idx}" + )), + ); + + let reverted_count = run_until( + INTERVAL_MS, + ATTEMPTS_FOR_VERIFY_TXS, + get_metric_closure, + condition, + Some(logger), + ) + .await + .expect("Failed to get reverted transactions metric after retries") + .expect("Metric retrieval failed"); + assert_eq!( reverted_count, 0, "Sequencer {sequencer_idx} has {reverted_count} reverted transactions" diff --git a/crates/apollo_mempool/benches/utils.rs b/crates/apollo_mempool/benches/utils.rs index cfc4dc3ba8a..a447cff08e4 100644 --- a/crates/apollo_mempool/benches/utils.rs +++ b/crates/apollo_mempool/benches/utils.rs @@ -24,7 +24,7 @@ use blockifier_test_utils::contracts::FeatureContract; use indexmap::IndexSet; use mempool_test_utils::starknet_api_test_utils::MultiAccountTransactionGenerator; use rand::rngs::StdRng; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::rpc_transaction::{ InternalRpcTransaction, @@ -194,7 +194,7 @@ impl BenchTestSetup { let mut rng = StdRng::seed_from_u64(42); let txs = (0..config.n_txs) .map(|index| { - let account_id = rng.gen_range(0..config.n_accounts); + let account_id = rng.random_range(0..config.n_accounts); tx_generator.generate_invoke(account_id, index) }) .collect(); diff --git a/crates/apollo_mempool/src/mempool.rs b/crates/apollo_mempool/src/mempool.rs index b1ae9321a6b..d441d0329ef 100644 --- a/crates/apollo_mempool/src/mempool.rs +++ b/crates/apollo_mempool/src/mempool.rs @@ -16,7 +16,7 @@ use apollo_mempool_types::mempool_types::{ }; use apollo_time::time::{Clock, DateTime}; use indexmap::IndexSet; -use rand::{thread_rng, Rng}; +use rand::{rng, RngExt}; use starknet_api::block::{GasPrice, UnixTimestamp}; use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::rpc_transaction::{ @@ -962,7 +962,7 @@ impl Mempool { if len == 0 { return None; } - let random_index = thread_rng().gen_range(0..len); + let random_index = rng().random_range(0..len); self.accounts_with_gap.get_index(random_index).copied() } diff --git a/crates/apollo_p2p_sync/src/client/class_test.rs b/crates/apollo_p2p_sync/src/client/class_test.rs index c7af6171eb9..7679ffa64b2 100644 --- a/crates/apollo_p2p_sync/src/client/class_test.rs +++ b/crates/apollo_p2p_sync/src/client/class_test.rs @@ -15,7 +15,7 @@ use apollo_test_utils::{get_rng, GetTestInstance}; use futures::FutureExt; use mockall::predicate::eq; use papyrus_common::pending_classes::ApiContractClass; -use rand::{Rng, RngCore}; +use rand::{Rng, RngExt}; use rand_chacha::ChaCha8Rng; use starknet_api::block::BlockNumber; use starknet_api::core::{ClassHash, CompiledClassHash, EntryPointSelector}; @@ -218,7 +218,7 @@ fn create_random_state_diff_chunk_with_class( rng: &mut ChaCha8Rng, ) -> (StateDiffChunk, ApiContractClass) { let class_hash = ClassHash(rng.next_u64().into()); - if rng.gen_bool(0.5) { + if rng.random_bool(0.5) { let declared_class = DeclaredClass { class_hash, compiled_class_hash: CompiledClassHash(rng.next_u64().into()), diff --git a/crates/apollo_p2p_sync/src/client/test.rs b/crates/apollo_p2p_sync/src/client/test.rs index 774c03446cb..236b02ac4b7 100644 --- a/crates/apollo_p2p_sync/src/client/test.rs +++ b/crates/apollo_p2p_sync/src/client/test.rs @@ -9,7 +9,7 @@ use apollo_storage::state::StateStorageReader; use apollo_test_utils::{get_rng, GetTestInstance}; use futures::FutureExt; use indexmap::IndexMap; -use rand::Rng; +use rand::RngExt; use rand_chacha::ChaCha8Rng; use starknet_api::block::{BlockHeaderWithoutHash, BlockNumber}; use starknet_api::block_hash::block_hash_calculator::BlockHeaderCommitments; @@ -136,7 +136,7 @@ async fn receive_blocks_out_of_order() { let state_diff_0 = sync_block_0.state_diff.clone(); // We need to forward the rng to the next generated num to make sure the blocks are different. - rng.gen::(); + rng.random::(); let account_transaction_hashes_len_1 = 3; let l1_transaction_hashes_len_1 = 1; let sync_block_1 = create_random_sync_block( diff --git a/crates/apollo_p2p_sync/src/client/test_utils.rs b/crates/apollo_p2p_sync/src/client/test_utils.rs index ddf1c39cfea..69d03aaba02 100644 --- a/crates/apollo_p2p_sync/src/client/test_utils.rs +++ b/crates/apollo_p2p_sync/src/client/test_utils.rs @@ -34,7 +34,7 @@ use futures::future::BoxFuture; use futures::{FutureExt, SinkExt, StreamExt}; use lazy_static::lazy_static; use papyrus_common::pending_classes::ApiContractClass; -use rand::{Rng, RngCore}; +use rand::{Rng, RngExt}; use rand_chacha::ChaCha8Rng; use starknet_api::block::{ BlockHash, @@ -363,8 +363,11 @@ pub fn random_header( block_number, ..GetTestInstance::get_test_instance(rng) }, - state_diff_length: Some(state_diff_length.unwrap_or_else(|| rng.gen())), - n_transactions: num_transactions.unwrap_or_else(|| rng.gen()), + state_diff_length: Some( + state_diff_length.unwrap_or_else(|| rng.random::().try_into().unwrap()), + ), + n_transactions: num_transactions + .unwrap_or_else(|| rng.random::().try_into().unwrap()), ..GetTestInstance::get_test_instance(rng) }, // TODO(shahak): Remove this once get_test_instance puts random values. diff --git a/crates/apollo_propeller/src/message_processor.rs b/crates/apollo_propeller/src/message_processor.rs index 88635897623..19f16ee2a14 100644 --- a/crates/apollo_propeller/src/message_processor.rs +++ b/crates/apollo_propeller/src/message_processor.rs @@ -262,7 +262,7 @@ impl MessageProcessor { .filter(|p| *p != self.publisher && *p != self.local_peer_id) .collect(); // TODO(AndrewL): get seeded RNG for tests. - peers.shuffle(&mut rand::thread_rng()); + peers.shuffle(&mut rand::rng()); trace!("[MSG_PROC] Broadcasting unit index={:?} to {} peers", unit.index(), peers.len()); self.engine_tx .send(EventStateManagerToEngine::SendUnitToPeers { unit: unit.clone(), peers }) diff --git a/crates/apollo_protobuf/src/converters/test_instances.rs b/crates/apollo_protobuf/src/converters/test_instances.rs index 8703a049df2..4f0ed58c902 100644 --- a/crates/apollo_protobuf/src/converters/test_instances.rs +++ b/crates/apollo_protobuf/src/converters/test_instances.rs @@ -2,7 +2,7 @@ use std::fmt::Display; use apollo_test_utils::{auto_impl_get_test_instance, get_number_of_variants, GetTestInstance}; use prost::DecodeError; -use rand::Rng; +use rand::RngExt; use starknet_api::block::{BlockNumber, GasPrice, StarknetVersion}; use starknet_api::consensus_transaction::ConsensusTransaction; use starknet_api::core::ContractAddress; @@ -134,7 +134,7 @@ impl Display for TestStreamId { // TODO(guyn): try to make the macro work with generic types. impl GetTestInstance for StreamMessage { fn get_test_instance(rng: &mut rand_chacha::ChaCha8Rng) -> Self { - let message = if rng.gen_bool(0.5) { + let message = if rng.random_bool(0.5) { StreamMessageBody::Content(ProposalPart::Transactions(TransactionBatch { transactions: vec![ConsensusTransaction::get_test_instance(rng)], })) diff --git a/crates/apollo_rpc/src/v0_8/api/test.rs b/crates/apollo_rpc/src/v0_8/api/test.rs index 576990301c5..3cb22969888 100644 --- a/crates/apollo_rpc/src/v0_8/api/test.rs +++ b/crates/apollo_rpc/src/v0_8/api/test.rs @@ -68,7 +68,7 @@ use lazy_static::lazy_static; use mockall::predicate::eq; use papyrus_common::pending_classes::{ApiContractClass, PendingClassesTrait}; use pretty_assertions::assert_eq; -use rand::{random, RngCore}; +use rand::{random, Rng}; use rand_chacha::ChaCha8Rng; use reqwest::StatusCode; use serde::{Deserialize, Serialize}; diff --git a/crates/apollo_starknet_client/resources/reader/block_post_0_14_2.json b/crates/apollo_starknet_client/resources/reader/block_post_0_14_2.json index 7648069c192..7ae854d2811 100644 --- a/crates/apollo_starknet_client/resources/reader/block_post_0_14_2.json +++ b/crates/apollo_starknet_client/resources/reader/block_post_0_14_2.json @@ -1185,7 +1185,7 @@ "actual_fee": "0x87077fd6af8a400" } ], - "starknet_version": "0.14.3", + "starknet_version": "0.14.4", "l2_gas_consumed": 988191555, "next_l2_gas_price": "0x1dcd65000" } diff --git a/crates/apollo_starknet_client/resources/reader/block_post_0_14_3.json b/crates/apollo_starknet_client/resources/reader/block_post_0_14_3.json index 2b54e8932f5..c8c3fa8e407 100644 --- a/crates/apollo_starknet_client/resources/reader/block_post_0_14_3.json +++ b/crates/apollo_starknet_client/resources/reader/block_post_0_14_3.json @@ -1185,7 +1185,7 @@ "actual_fee": "0x87077fd6af8a400" } ], - "starknet_version": "0.14.3", + "starknet_version": "0.14.4", "l2_gas_consumed": 988191555, "next_l2_gas_price": "0x1dcd65000", "fee_proposal_fri": "0x1dcd66000" diff --git a/crates/apollo_state_sync/Cargo.toml b/crates/apollo_state_sync/Cargo.toml index 0d83fa4eb5a..3428e1fb3f0 100644 --- a/crates/apollo_state_sync/Cargo.toml +++ b/crates/apollo_state_sync/Cargo.toml @@ -47,4 +47,5 @@ apollo_test_utils.workspace = true indexmap = { workspace = true, features = ["serde"] } libp2p.workspace = true mockall.workspace = true +rand.workspace = true rand_chacha.workspace = true diff --git a/crates/apollo_state_sync/src/test.rs b/crates/apollo_state_sync/src/test.rs index 0dcce16ca4a..df0117ffac9 100644 --- a/crates/apollo_state_sync/src/test.rs +++ b/crates/apollo_state_sync/src/test.rs @@ -15,7 +15,7 @@ use apollo_test_utils::{get_rng, get_test_block, get_test_state_diff, GetTestIns use futures::channel::mpsc::channel; use indexmap::IndexMap; use mockall::predicate; -use rand_chacha::rand_core::RngCore; +use rand::Rng; use starknet_api::block::{Block, BlockHash, BlockHeader, BlockNumber}; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; use starknet_api::hash::StarkHash; diff --git a/crates/apollo_storage/src/db/table_types/test_utils.rs b/crates/apollo_storage/src/db/table_types/test_utils.rs index 775fd244516..a118cea8607 100644 --- a/crates/apollo_storage/src/db/table_types/test_utils.rs +++ b/crates/apollo_storage/src/db/table_types/test_utils.rs @@ -1,6 +1,6 @@ use assert_matches::assert_matches; use rand::rngs::ThreadRng; -use rand::Rng; +use rand::RngExt; use tracing::debug; use super::{Table, TableType}; @@ -305,14 +305,14 @@ pub(crate) fn random_table_test( let rtxn = reader.begin_ro_txn().unwrap(); let first_table = rtxn.open_table(&first_table_id).unwrap(); let second_table = rtxn.open_table(&second_table_id).unwrap(); - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); for iter in 0..ITERS { debug!("iteration: {iter:?}"); let wtxn = writer.begin_rw_txn().unwrap(); - let random_op = rng.gen_range(0..4); + let random_op = rng.random_range(0..4); let key = get_random_key(&mut rng); - let value = rng.gen_range(0..MAX_VALUE); + let value = rng.random_range(0..MAX_VALUE); // Insert, upsert, or delete a random key. if random_op == 0 { @@ -386,7 +386,7 @@ pub(crate) fn random_table_test( ); for _ in 0..CURSOR_OPS_NUM { - let random_op = rng.gen_range(0..2); + let random_op = rng.random_range(0..2); if random_op == 0 { // Next debug!("next: {key:?}"); @@ -414,5 +414,5 @@ pub(crate) fn random_table_test( } fn get_random_key(rng: &mut ThreadRng) -> TableKey { - (rng.gen_range(0..MAIN_KEY_MAX_VALUE), rng.gen_range(0..SUB_KEY_MAX_VALUE)) + (rng.random_range(0..MAIN_KEY_MAX_VALUE), rng.random_range(0..SUB_KEY_MAX_VALUE)) } diff --git a/crates/apollo_storage/src/mmap_file/mmap_file_test.rs b/crates/apollo_storage/src/mmap_file/mmap_file_test.rs index 870bb5aa17f..ee8c0c390ae 100644 --- a/crates/apollo_storage/src/mmap_file/mmap_file_test.rs +++ b/crates/apollo_storage/src/mmap_file/mmap_file_test.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use apollo_test_utils::get_rng; use pretty_assertions::assert_eq; -use rand::Rng; +use rand::RngExt; use tempfile::tempdir; use tokio::sync::{Barrier, RwLock}; @@ -222,7 +222,7 @@ async fn write_read_different_locations() { { round = *lock.read().await; } - let read_offset = 3 * rand::thread_rng().gen_range(0..round + 1); + let read_offset = 3 * rand::rng().random_range(0..round + 1); let read_location = LocationInFile { offset: read_offset, len: LEN }; let read_value = reader.get(read_location).unwrap().unwrap(); let first_expected_value: u8 = (read_offset / 3 * 2).try_into().unwrap(); diff --git a/crates/apollo_storage/src/serialization/serializers.rs b/crates/apollo_storage/src/serialization/serializers.rs index b0bbdbfebc0..f4be21ca10e 100644 --- a/crates/apollo_storage/src/serialization/serializers.rs +++ b/crates/apollo_storage/src/serialization/serializers.rs @@ -454,6 +454,7 @@ auto_storage_serde! { V0_14_1 = 24, V0_14_2 = 25, V0_14_3 = 26, + V0_14_4 = 27, } pub struct StateDiffCommitment(pub PoseidonHash); pub struct Tip(pub u64); diff --git a/crates/apollo_storage/src/version_test.rs b/crates/apollo_storage/src/version_test.rs index 164a8ac8bda..a5eb5944dda 100644 --- a/crates/apollo_storage/src/version_test.rs +++ b/crates/apollo_storage/src/version_test.rs @@ -1,6 +1,6 @@ use assert_matches::assert_matches; use pretty_assertions::assert_eq; -use rand::Rng; +use rand::RngExt; use crate::db::table_types::Table; use crate::test_utils::{ @@ -211,11 +211,11 @@ fn change_storage_version(writer: &mut StorageWriter, version_key: &str, version // Returns a random version with a different major version than the given one. fn get_different_major_version(version: Version) -> Version { - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); // The multiplication by two is to make the randomized version to be // with a high enough probability to be less and more than the current version. - let minor = rng.gen_range(0..=2 * version.minor); - let mut major = rng.gen_range(0..=2 * version.major); + let minor = rng.random_range(0..=2 * version.minor); + let mut major = rng.random_range(0..=2 * version.major); if major == version.major { major += 1; } diff --git a/crates/apollo_test_utils/src/lib.rs b/crates/apollo_test_utils/src/lib.rs index 149e163458a..03937d83fec 100644 --- a/crates/apollo_test_utils/src/lib.rs +++ b/crates/apollo_test_utils/src/lib.rs @@ -34,7 +34,7 @@ use primitive_types::H160; use prometheus_parse::Value; // Re-export for use in downstream crates. pub use rand; -use rand::{Rng, RngCore, SeedableRng}; +use rand::{Rng, RngExt, SeedableRng}; // Re-export for use in downstream crates. pub use rand_chacha; use rand_chacha::ChaCha8Rng; @@ -213,7 +213,7 @@ pub fn validate_load_and_dump Deserialize<'a>>(path_in_re pub fn get_rng() -> ChaCha8Rng { let seed: u64 = match env::var("SEED") { Ok(seed_str) => seed_str.parse().unwrap(), - _ => rand::thread_rng().gen(), + _ => rand::rng().random(), }; // Will be printed if the test failed. println!("Testing with seed: {seed:?}"); @@ -315,14 +315,14 @@ fn get_rand_test_body_with_events( let mut events = vec![]; for _ in 0..events_per_tx { let from_address = if let Some(ref options) = from_addresses { - *options.index(rng.gen_range(0..options.len())) + *options.index(rng.random_range(0..options.len())) } else { ContractAddress::default() }; let final_keys = if let Some(ref options) = keys { let mut chosen_keys = vec![]; for options_per_i in options { - let key = options_per_i.index(rng.gen_range(0..options_per_i.len())).clone(); + let key = options_per_i.index(rng.random_range(0..options_per_i.len())).clone(); chosen_keys.push(key); } chosen_keys @@ -530,6 +530,7 @@ auto_impl_get_test_instance! { V0_14_1 = 24, V0_14_2 = 25, V0_14_3 = 26, + V0_14_4 = 27, } pub struct Calldata(pub Arc>); @@ -1064,8 +1065,8 @@ macro_rules! auto_impl_get_test_instance { ($(pub)? enum $name:ident { $($variant:ident $( ($ty:ty) )? = $num:expr ,)* } $($rest:tt)*) => { impl GetTestInstance for $name { fn get_test_instance(rng: &mut $crate::rand_chacha::ChaCha8Rng) -> Self { - use $crate::rand::Rng; - let variant = rng.gen_range(0..get_number_of_variants!(enum $name { $($variant $( ($ty) )? = $num ,)* })); + use $crate::rand::RngExt; + let variant = rng.random_range(0..get_number_of_variants!(enum $name { $($variant $( ($ty) )? = $num ,)* })); match variant { $( $num => { diff --git a/crates/apollo_versioned_constants/resources/orchestrator_versioned_constants_0_14_4.json b/crates/apollo_versioned_constants/resources/orchestrator_versioned_constants_0_14_4.json new file mode 100644 index 00000000000..6f0ea481524 --- /dev/null +++ b/crates/apollo_versioned_constants/resources/orchestrator_versioned_constants_0_14_4.json @@ -0,0 +1,9 @@ +{ + "fee_proposal_margin_ppt": 2, + "fee_proposal_window_size": 10, + "gas_price_max_change_denominator": 48, + "gas_target": 1040000000, + "max_block_size": 5800000000, + "min_gas_price": "0x1dcd65000", + "l1_gas_price_margin_percent": 10 +} diff --git a/crates/apollo_versioned_constants/resources/versioned_constants_diff_regression/0.14.3_0.14.4.txt b/crates/apollo_versioned_constants/resources/versioned_constants_diff_regression/0.14.3_0.14.4.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/crates/apollo_versioned_constants/resources/versioned_constants_diff_regression/0.14.3_0.14.4.txt @@ -0,0 +1 @@ + diff --git a/crates/apollo_versioned_constants/src/lib.rs b/crates/apollo_versioned_constants/src/lib.rs index 32341eeef6e..c1f8b9dac41 100644 --- a/crates/apollo_versioned_constants/src/lib.rs +++ b/crates/apollo_versioned_constants/src/lib.rs @@ -39,6 +39,7 @@ define_versioned_constants!( (V0_14_1, "../resources/orchestrator_versioned_constants_0_14_1.json"), (V0_14_2, "../resources/orchestrator_versioned_constants_0_14_2.json"), (V0_14_3, "../resources/orchestrator_versioned_constants_0_14_3.json"), + (V0_14_4, "../resources/orchestrator_versioned_constants_0_14_4.json"), ); /// Error type for the Consensus' versioned constants. diff --git a/crates/blockifier/resources/blockifier_versioned_constants_0_14_4.json b/crates/blockifier/resources/blockifier_versioned_constants_0_14_4.json new file mode 100644 index 00000000000..df21e397f16 --- /dev/null +++ b/crates/blockifier/resources/blockifier_versioned_constants_0_14_4.json @@ -0,0 +1,572 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920, + "max_proof_size": 480000 + }, + "invoke_tx_max_n_steps": 10000000, + "validate_max_n_steps": 1000000, + "max_recursion_depth": 50, + "deprecated_l2_resource_gas_costs": { + "gas_per_data_felt": [ + 128, + 1000 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 32, + 1000 + ], + "gas_per_proof": [ + 0, + 1 + ] + }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 1280, + 1 + ], + "gas_per_proof": [ + 75000000, + 1 + ] + }, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 32, + "l2_gas": 402000 + }, + "gas_cost": { + "l1_gas": 551, + "l1_data_gas": 0, + "l2_gas": 402000 + } + }, + "vm_resource_fee_cost": { + "n_steps": [ + 25, + 10000 + ], + "builtins": { + "add_mod_builtin": [ + 4, + 100 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 4, + 100 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check96_builtin": [ + 4, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ] + } + }, + "disable_cairo0_redeclaration": true, + "enable_stateful_compression": true, + "comprehensive_state_diff": true, + "block_direct_execute_call": true, + "ignore_inner_event_resources": false, + "disable_deploy_in_validation_mode": true, + "enable_reverts": true, + "enable_casm_hash_migration": true, + "block_casm_hash_v1_declares": true, + "min_sierra_version_for_sierra_gas": "1.7.0", + "enable_tip": true, + "segment_arena_cells": false, + "os_constants": { + "allowed_virtual_os_program_hashes": [ + "0x3e98c2d7703b03a7edb73ed7f075f97f1dcbaa8f717cdf6e1a57bf058265473", + "0x6ecb73d21c7d98ddd4148f5bcd91cc2747c65364245fbf32a63b05cca1685c2" + ], + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "default_entry_point_selector": "0x0", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "entry_point_type_constructor": 2, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + }, + "validated": "VALID", + "execute_max_sierra_gas": 1110000000, + "validate_max_sierra_gas": 100000000, + "error_block_number_out_of_range": "Block number out of range", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", + "l1_gas": "L1_GAS", + "l2_gas": "L2_GAS", + "l1_data_gas": "L1_DATA", + "l1_gas_index": 0, + "l1_data_gas_index": 2, + "l2_gas_index": 1, + "memory_hole_gas_cost": 10, + "builtin_gas_costs": { + "range_check": 70, + "range_check96": 56, + "keccak": 136189, + "pedersen": 4050, + "bitwise": 583, + "ecop": 4085, + "poseidon": 491, + "add_mod": 230, + "mul_mod": 604, + "ecdsa": 10561, + "blake": 3334 + }, + "step_gas_cost": 100, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "default_initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "l1_handler_version": 0, + "l1_handler_max_amount_bounds": { + "l1_gas": 40000, + "l1_data_gas": 20000, + "l2_gas": 100000000 + }, + "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, + "sierra_array_len_bound": 4294967296, + "stored_block_hash_buffer": 10, + "v1_bound_accounts_cairo0": [ + "0x6d706cfbac9b8262d601c38251c5fbe0497c3a96cc91a92b08d91b61d9e70c4", + "0x309c042d3729173c7f2f91a34f04d8c509c1b292d334679ef1aabf8da0899cc", + "0x1a7820094feaf82d53f53f214b81292d717e7bb9a92bb2488092cd306f3993f", + "0x33434ad846cdd5f23eb73ff09fe6fddd568284a0fb7d1be20ee482f044dabe2", + "0x41cb0280ebadaa75f996d8d92c6f265f6d040bb3ba442e5f86a554f1765244e", + "0x3530cc4759d78042f1b543bf797f5f3d647cde0388c33734cf91b7f7b9314a9" + ], + "v1_bound_accounts_cairo1": [ + "0x1a736d6ed154502257f02b1ccdf4d9d1089f80811cd6acad48e6b6a9d1f2003", + "0x737ee2f87ce571a58c6c8da558ec18a07ceb64a6172d5ec46171fbc80077a48", + "0x5400e90f7e0ae78bd02c77cd75527280470e2fe19c54970dd79dc37a9d3645c", + "0x4c6d6cf894f8bc96bb9c525e6853e5483177841f7388f74a46cfda6f028c755", + "0x1c0bb51e2ce73dc007601a1e7725453627254016c28f118251a71bbb0507fcb", + "0x251830adc3d8b4d818c2c309d71f1958308e8c745212480c26e01120c69ee49", + "0x251cac7b2f45d255b83b7a06dcdef70c8a8752f00ea776517c1c2243c7a06e5" + ], + "v1_bound_accounts_max_tip": "0x746a5288000", + "data_gas_accounts": [ + "0x2c8c7e6fbcfb3e8e15a46648e8914c6aa1fc506fc1e7fb3d1e19630716174bc", + "0x816dd0297efc55dc1e7559020a3a825e81ef734b558f03c83325d4da7e6253", + "0x41bf1e71792aecb9df3e9d04e1540091c5e13122a731e02bec588f71dc1a5c3", + "0x6d612cac7690e6620055c617a83a5a0b43b9758d9d30f281ddbc77be1651a70" + ] + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 903, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 18 + } + }, + "DelegateCall": { + "n_steps": 713, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 19 + } + }, + "DelegateL1Handler": { + "n_steps": 692, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 15 + } + }, + "Deploy": { + "constant": { + "n_steps": 1173, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 21, + "pedersen_builtin": 7 + } + }, + "calldata_factor": { + "n_steps": 8, + "n_memory_holes": 0, + "builtin_instance_counter": { + "pedersen_builtin": 1 + } + } + }, + "EmitEvent": { + "n_steps": 61, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 1 + } + }, + "GetBlockHash": { + "n_steps": 107, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 2 + } + }, + "GetBlockNumber": { + "n_steps": 40, + "n_memory_holes": 0, + "builtin_instance_counter": {} + }, + "GetBlockTimestamp": { + "n_steps": 38, + "n_memory_holes": 0, + "builtin_instance_counter": {} + }, + "GetCallerAddress": { + "n_steps": 125, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 2 + } + }, + "GetClassHashAt": { + "n_steps": 89, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 1 + } + }, + "GetContractAddress": { + "n_steps": 125, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 2 + } + }, + "GetExecutionInfo": { + "n_steps": 125, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 2 + } + }, + "GetSequencerAddress": { + "n_steps": 34, + "n_memory_holes": 0, + "builtin_instance_counter": {} + }, + "GetTxInfo": { + "n_steps": 125, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 2 + } + }, + "GetTxSignature": { + "n_steps": 44, + "n_memory_holes": 0, + "builtin_instance_counter": {} + }, + "Keccak": { + "n_steps": 100, + "n_memory_holes": 0, + "builtin_instance_counter": {} + }, + "KeccakRound": { + "n_steps": 281, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 56, + "keccak_builtin": 1, + "bitwise_builtin": 6 + } + }, + "LibraryCall": { + "n_steps": 879, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 18 + } + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 15 + } + }, + "MetaTxV0": { + "constant": { + "n_steps": 1301, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 20, + "pedersen_builtin": 9 + } + }, + "calldata_factor": { + "n_steps": 8, + "n_memory_holes": 0, + "builtin_instance_counter": { + "pedersen_builtin": 1 + } + } + }, + "ReplaceClass": { + "n_steps": 106, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 1 + } + }, + "Secp256k1Add": { + "n_steps": 412, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 29 + } + }, + "Secp256k1GetPointFromX": { + "n_steps": 397, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 30 + } + }, + "Secp256k1GetXy": { + "n_steps": 209, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 11 + } + }, + "Secp256k1Mul": { + "n_steps": 76507, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 7045 + } + }, + "Secp256k1New": { + "n_steps": 463, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 35 + } + }, + "Secp256r1Add": { + "n_steps": 595, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 57 + } + }, + "Secp256r1GetPointFromX": { + "n_steps": 516, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 44 + } + }, + "Secp256r1GetXy": { + "n_steps": 211, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 11 + } + }, + "Secp256r1Mul": { + "n_steps": 125346, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 13961 + } + }, + "Secp256r1New": { + "n_steps": 582, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 49 + } + }, + "SendMessageToL1": { + "n_steps": 144, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 1 + } + }, + "Sha256ProcessBlock": { + "n_steps": 1867, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + } + }, + "Sha512ProcessBlock": { + "n_steps": 4737, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 3320 + } + }, + "StorageRead": { + "n_steps": 240, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 1 + } + }, + "StorageWrite": { + "n_steps": 599, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 1 + } + } + }, + "execute_txs_inner": { + "Declare": { + "n_steps": 3523, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 72, + "pedersen_builtin": 4, + "poseidon_builtin": 15 + } + }, + "DeployAccount": { + "constant": { + "n_steps": 4583, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 93, + "pedersen_builtin": 11, + "poseidon_builtin": 11 + } + }, + "calldata_factor": { + "resources": { + "n_steps": 37, + "n_memory_holes": 0, + "builtin_instance_counter": { + "pedersen_builtin": 2, + "poseidon_builtin": 1 + } + }, + "scaling_factor": 2 + } + }, + "InvokeFunction": { + "constant": { + "n_steps": 4348, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 90, + "pedersen_builtin": 4, + "poseidon_builtin": 12 + } + }, + "calldata_factor": { + "resources": { + "n_steps": 11, + "n_memory_holes": 0, + "builtin_instance_counter": { + "poseidon_builtin": 1 + } + }, + "scaling_factor": 2 + } + }, + "L1Handler": { + "constant": { + "n_steps": 1315, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 19, + "pedersen_builtin": 11 + } + }, + "calldata_factor": { + "n_steps": 13, + "n_memory_holes": 0, + "builtin_instance_counter": { + "pedersen_builtin": 1 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "n_memory_holes": 0, + "builtin_instance_counter": { + "range_check_builtin": 17 + } + } + } +} diff --git a/crates/blockifier/resources/versioned_constants_diff_regression/0.14.3_0.14.4.txt b/crates/blockifier/resources/versioned_constants_diff_regression/0.14.3_0.14.4.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/crates/blockifier/resources/versioned_constants_diff_regression/0.14.3_0.14.4.txt @@ -0,0 +1 @@ + diff --git a/crates/blockifier/src/blockifier_versioned_constants.rs b/crates/blockifier/src/blockifier_versioned_constants.rs index 9ce5598d126..90b8edfab63 100644 --- a/crates/blockifier/src/blockifier_versioned_constants.rs +++ b/crates/blockifier/src/blockifier_versioned_constants.rs @@ -55,6 +55,7 @@ define_versioned_constants!( (V0_14_1, "../resources/blockifier_versioned_constants_0_14_1.json"), (V0_14_2, "../resources/blockifier_versioned_constants_0_14_2.json"), (V0_14_3, "../resources/blockifier_versioned_constants_0_14_3.json"), + (V0_14_4, "../resources/blockifier_versioned_constants_0_14_4.json"), ); pub type SyscallGasCostsMap = BTreeMap; diff --git a/crates/blockifier/src/test_utils/transfers_generator.rs b/crates/blockifier/src/test_utils/transfers_generator.rs index b3609b40ada..ff79b2ec833 100644 --- a/crates/blockifier/src/test_utils/transfers_generator.rs +++ b/crates/blockifier/src/test_utils/transfers_generator.rs @@ -4,7 +4,7 @@ use std::time::{Duration, Instant}; use blockifier_test_utils::cairo_versions::CairoVersion; use blockifier_test_utils::contracts::FeatureContract; use rand::rngs::StdRng; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use starknet_api::abi::abi_utils::selector_from_name; use starknet_api::block::BlockInfo; use starknet_api::core::ContractAddress; @@ -156,7 +156,7 @@ impl TransfersGenerator { RecipientGeneratorType::Random => { let random_recipient_generator = self.random_recipient_generator.as_mut().unwrap(); let recipient_index = - random_recipient_generator.gen_range(0..self.account_addresses.len()); + random_recipient_generator.random_range(0..self.account_addresses.len()); self.account_addresses[recipient_index] } RecipientGeneratorType::RoundRobin => { diff --git a/crates/central_systest_blobs/resources/blob_file_generation b/crates/central_systest_blobs/resources/blob_file_generation index cabf43b5ddf..978b4e8e518 100644 --- a/crates/central_systest_blobs/resources/blob_file_generation +++ b/crates/central_systest_blobs/resources/blob_file_generation @@ -1 +1 @@ -24 \ No newline at end of file +26 \ No newline at end of file diff --git a/crates/central_systest_blobs/resources/preconfirmed_block.json b/crates/central_systest_blobs/resources/preconfirmed_block.json index 992a05a67cf..4c209c68704 100644 --- a/crates/central_systest_blobs/resources/preconfirmed_block.json +++ b/crates/central_systest_blobs/resources/preconfirmed_block.json @@ -15,7 +15,7 @@ "price_in_wei": "0x1" }, "sequencer_address": "0x1000", - "starknet_version": "0.14.3", + "starknet_version": "0.14.4", "status": "PRE_CONFIRMED", "timestamp": 1013, "transaction_receipts": [ diff --git a/crates/papyrus_common/src/state.rs b/crates/papyrus_common/src/state.rs index bfa4a6e5dce..e6acc42b9f6 100644 --- a/crates/papyrus_common/src/state.rs +++ b/crates/papyrus_common/src/state.rs @@ -1,5 +1,5 @@ use indexmap::indexmap; -use rand::RngCore; +use rand::Rng; use serde::{Deserialize, Serialize}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::{StorageKey, ThinStateDiff}; @@ -36,7 +36,7 @@ pub struct ReplacedClass { } // TODO(Shahak): move to used crate -pub fn create_random_state_diff(rng: &mut impl RngCore) -> ThinStateDiff { +pub fn create_random_state_diff(rng: &mut impl Rng) -> ThinStateDiff { let contract0 = ContractAddress::from(rng.next_u64()); let contract1 = ContractAddress::from(rng.next_u64()); let contract2 = ContractAddress::from(rng.next_u64()); diff --git a/crates/starknet_api/src/block.rs b/crates/starknet_api/src/block.rs index 611cf21df22..ddf5c76c49d 100644 --- a/crates/starknet_api/src/block.rs +++ b/crates/starknet_api/src/block.rs @@ -123,7 +123,8 @@ starknet_version_enum! { (V0_14_1, 0, 14, 1), (V0_14_2, 0, 14, 2), (V0_14_3, 0, 14, 3), - V0_14_3 + (V0_14_4, 0, 14, 4), + V0_14_4 } impl Default for StarknetVersion { diff --git a/crates/starknet_api/src/transaction.rs b/crates/starknet_api/src/transaction.rs index df8b7231855..38cc2272f42 100644 --- a/crates/starknet_api/src/transaction.rs +++ b/crates/starknet_api/src/transaction.rs @@ -2,6 +2,8 @@ use std::sync::LazyLock; use apollo_sizeof::SizeOf; use num_bigint::BigUint; +#[cfg(any(feature = "testing", test))] +use rand::RngExt; use serde::{Deserialize, Serialize}; use starknet_types_core::felt::Felt; @@ -907,7 +909,7 @@ impl TransactionHash { pub fn random(rng: &mut impl rand::Rng) -> Self { let mut byte_vec = vec![]; for _ in 0..32 { - byte_vec.push(rng.gen::()); + byte_vec.push(rng.random::()); } let byte_array = byte_vec.try_into().expect("Expected a Vec of length 32"); TransactionHash(StarkHash::from_bytes_be(&byte_array)) diff --git a/crates/starknet_committer/src/block_committer/commit.rs b/crates/starknet_committer/src/block_committer/commit.rs index e0446507947..e7b42f67ce9 100644 --- a/crates/starknet_committer/src/block_committer/commit.rs +++ b/crates/starknet_committer/src/block_committer/commit.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; +use starknet_patricia::patricia_merkle_tree::node_data::leaf::LeafModifications; use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices}; use starknet_types_core::felt::Felt; use tracing::{debug, warn}; @@ -8,6 +9,8 @@ use tracing::{debug, warn}; use crate::block_committer::errors::BlockCommitmentError; use crate::block_committer::input::{ contract_address_into_node_index, + skeleton_storage_updates, + skeleton_trie_updates, Input, StarknetStorageValue, StateDiff, @@ -21,11 +24,11 @@ use crate::db::forest_trait::ForestReader; use crate::forest::deleted_nodes::{find_deleted_nodes, DeletedNodes}; use crate::forest::filled_forest::FilledForest; use crate::forest::forest_errors::ForestError; -use crate::forest::original_skeleton_forest::ForestSortedIndices; +use crate::forest::original_skeleton_forest::{ForestSortedIndices, OriginalSkeletonForest}; use crate::forest::updated_skeleton_forest::UpdatedSkeletonForest; use crate::hash_function::hash::TreeHashFunctionImpl; use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState; -use crate::patricia_merkle_tree::types::class_hash_into_node_index; +use crate::patricia_merkle_tree::types::{class_hash_into_node_index, CompiledClassHash}; pub type BlockCommitmentResult = Result; @@ -54,16 +57,51 @@ pub async fn commit_block( + input: &Input, + actual_storage_updates: &HashMap>, + actual_classes_updates: &LeafModifications, + forest_sorted_indices: &'a ForestSortedIndices<'a>, + trie_reader: &mut Reader, + measurements: &mut M, +) -> BlockCommitmentResult<(OriginalSkeletonForest<'a>, HashMap)> { measurements.start_measurement(Action::Read); - let roots = - trie_reader.read_roots(input.initial_read_context).await.map_err(ForestError::from)?; + let roots = trie_reader + .read_roots(input.initial_read_context.clone()) + .await + .map_err(ForestError::from)?; let (original_forest, original_contracts_trie_leaves) = trie_reader .read( roots, - &actual_storage_updates, - &actual_classes_updates, - &forest_sorted_indices, + actual_storage_updates, + actual_classes_updates, + forest_sorted_indices, input.config.clone(), ) .await?; @@ -79,15 +117,29 @@ pub async fn commit_block( + original_forest: OriginalSkeletonForest<'_>, + original_contracts_trie_leaves: HashMap, + actual_storage_updates: HashMap>, + actual_classes_updates: LeafModifications, + address_to_class_hash: &HashMap, + address_to_nonce: &HashMap, + measurements: &mut M, +) -> BlockCommitmentResult<(FilledForest, DeletedNodes)> { measurements.start_measurement(Action::Compute); + + // Compute the new topology. let updated_forest = UpdatedSkeletonForest::create( &original_forest, - &input.state_diff.skeleton_classes_updates(), - &input.state_diff.skeleton_storage_updates(), + &skeleton_trie_updates(&actual_classes_updates), + &skeleton_storage_updates(&actual_storage_updates), &original_contracts_trie_leaves, - &input.state_diff.address_to_class_hash, - &input.state_diff.address_to_nonce, + address_to_class_hash, + address_to_nonce, )?; debug!("Updated skeleton forest created successfully."); @@ -106,8 +158,8 @@ pub async fn commit_block for StarknetStorageKey { #[derive(Clone, Copy, Default, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct StarknetStorageValue(pub Felt); +impl From for SkeletonLeaf { + fn from(value: StarknetStorageValue) -> Self { + SkeletonLeaf::from(value.0) + } +} + #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct StateDiff { pub address_to_class_hash: HashMap, @@ -264,33 +270,6 @@ impl StateDiff { } /// For each modified contract calculates it's actual storage updates. - pub(crate) fn skeleton_storage_updates( - &self, - ) -> HashMap> { - self.accessed_addresses() - .iter() - .map(|address| { - let updates = match self.storage_updates.get(address) { - Some(inner_updates) => inner_updates - .iter() - .map(|(key, value)| (key.into(), SkeletonLeaf::from(value.0))) - .collect(), - None => HashMap::new(), - }; - (**address, updates) - }) - .collect() - } - - pub(crate) fn skeleton_classes_updates(&self) -> LeafModifications { - self.class_hash_to_compiled_class_hash - .iter() - .map(|(class_hash, compiled_class_hash)| { - (class_hash_into_node_index(class_hash), SkeletonLeaf::from(compiled_class_hash.0)) - }) - .collect() - } - pub(crate) fn actual_storage_updates( &self, ) -> HashMap> { @@ -317,3 +296,21 @@ impl StateDiff { .collect() } } + +/// Reduces a single trie's actual leaf updates to skeleton updates (whether each leaf is zero or +/// non-zero). +pub(crate) fn skeleton_trie_updates>( + actual_updates: &LeafModifications, +) -> LeafModifications { + actual_updates.iter().map(|(&index, &value)| (index, value.into())).collect() +} + +/// Reduces the actual storage updates to skeleton updates. +pub(crate) fn skeleton_storage_updates( + actual_storage_updates: &HashMap>, +) -> HashMap> { + actual_storage_updates + .iter() + .map(|(address, updates)| (*address, skeleton_trie_updates(updates))) + .collect() +} diff --git a/crates/starknet_committer/src/db/facts_db/db.rs b/crates/starknet_committer/src/db/facts_db/db.rs index b11eb0f7582..eed078677a1 100644 --- a/crates/starknet_committer/src/db/facts_db/db.rs +++ b/crates/starknet_committer/src/db/facts_db/db.rs @@ -125,8 +125,8 @@ impl ForestReader for FactsDb { async fn read<'a>( &mut self, roots: StateRoots, - storage_updates: &'a HashMap>, - classes_updates: &'a LeafModifications, + storage_updates: &HashMap>, + classes_updates: &LeafModifications, forest_sorted_indices: &'a ForestSortedIndices<'a>, config: ReaderConfig, ) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap)> { diff --git a/crates/starknet_committer/src/db/forest_trait.rs b/crates/starknet_committer/src/db/forest_trait.rs index 702a9c8de6f..1806f106c5e 100644 --- a/crates/starknet_committer/src/db/forest_trait.rs +++ b/crates/starknet_committer/src/db/forest_trait.rs @@ -30,11 +30,18 @@ use crate::forest::original_skeleton_forest::{ForestSortedIndices, OriginalSkele use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState; use crate::patricia_merkle_tree::types::CompiledClassHash; +#[cfg(feature = "os_input")] +#[path = "forest_trait_witnesses.rs"] +pub mod forest_trait_witnesses; + #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Hash, Serialize)] pub enum ForestMetadataType { CommitmentOffset, StateDiffHash(DbBlockNumber), StateRoot(DbBlockNumber), + /// BLAKE2s digest of the canonical accessed-keys set for the block. + #[cfg(feature = "os_input")] + AccessedKeysDigest(DbBlockNumber), } #[async_trait] @@ -70,13 +77,13 @@ pub trait ForestMetadata { #[async_trait] pub trait ForestReader { /// Input required to start reading the storage trie. - type InitialReadContext: InputContext + Send; + type InitialReadContext: InputContext + Send + Sync; async fn read<'a>( &mut self, roots: StateRoots, - storage_updates: &'a HashMap>, - classes_updates: &'a LeafModifications, + storage_updates: &HashMap>, + classes_updates: &LeafModifications, forest_sorted_indices: &'a ForestSortedIndices<'a>, config: ReaderConfig, ) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap)>; @@ -91,8 +98,8 @@ pub trait ForestReader { pub(crate) async fn read_forest<'a, S, Layout>( storage: &mut S, roots: StateRoots, - storage_updates: &'a HashMap>, - classes_updates: &'a LeafModifications, + storage_updates: &HashMap>, + classes_updates: &LeafModifications, forest_sorted_indices: &'a ForestSortedIndices<'a>, config: ReaderConfig, ) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap)> @@ -178,6 +185,24 @@ pub trait ForestWriterWithMetadata: ForestWriter + ForestMetadata { /// Serializes deleted nodes into a vector of database keys. fn serialize_deleted_nodes(deleted_nodes: DeletedNodes) -> Vec; + /// Appends serialized forest nodes, metadata entries, and deleted nodes to + /// `operations`. + fn append_forest_and_metadata( + operations: &mut DbOperationMap, + filled_forest: &FilledForest, + metadata: HashMap, + deleted_nodes: DeletedNodes, + ) -> SerializationResult<()> { + for key in Self::serialize_deleted_nodes(deleted_nodes) { + operations.insert(key, DbOperation::Delete); + } + operations.extend(updates_to_set_operations(Self::serialize_forest(filled_forest)?)); + for (metadata_type, value) in metadata { + operations.insert(Self::metadata_key(metadata_type), DbOperation::Set(value)); + } + Ok(()) + } + /// Writes only metadata entries to storage, without a filled forest. /// Returns an error if any of the metadata keys are already set. /// May overwrite existing metadata in case of a write race (existence check and writing are not @@ -205,16 +230,8 @@ pub trait ForestWriterWithMetadata: ForestWriter + ForestMetadata { metadata: HashMap, deleted_nodes: DeletedNodes, ) -> SerializationResult { - let mut updates = Self::serialize_forest(filled_forest)?; - for (metadata_type, value) in metadata { - Self::insert_metadata(&mut updates, metadata_type, value); - } - let keys_to_delete = Self::serialize_deleted_nodes(deleted_nodes); - let operations = keys_to_delete - .into_iter() - .map(|key| (key, DbOperation::Delete)) - .chain(updates_to_set_operations(updates)) - .collect(); + let mut operations = DbOperationMap::new(); + Self::append_forest_and_metadata(&mut operations, filled_forest, metadata, deleted_nodes)?; Ok(self.write_updates(operations).await) } } diff --git a/crates/starknet_committer/src/db/forest_trait_witnesses.rs b/crates/starknet_committer/src/db/forest_trait_witnesses.rs new file mode 100644 index 00000000000..7e8fbe5de03 --- /dev/null +++ b/crates/starknet_committer/src/db/forest_trait_witnesses.rs @@ -0,0 +1,85 @@ +use std::collections::HashMap; + +use async_trait::async_trait; +use starknet_api::block::BlockNumber; +use starknet_api::hash::HashOutput; +use starknet_patricia::patricia_merkle_tree::traversal::TraversalResult; +use starknet_patricia::patricia_merkle_tree::types::NodeIndex; +use starknet_patricia_storage::errors::SerializationResult; +use starknet_patricia_storage::storage_trait::{DbHashMap, DbValue}; + +use super::{ + EmptyInitialReadContext, + ForestMetadataType, + ForestReader, + ForestWriterWithMetadata, + StorageInitializer, +}; +use crate::forest::deleted_nodes::DeletedNodes; +use crate::forest::filled_forest::FilledForest; +use crate::forest::forest_errors::ForestResult; +use crate::patricia_merkle_tree::tree::SortedLeafIndices; +use crate::patricia_merkle_tree::types::StarknetForestProofs; + +/// The information required to write Patricia proofs to the database. +pub struct PatriciaProofsWrite { + pub block_number: BlockNumber, + pub keys_digest: [u8; 32], + pub witnesses: StarknetForestProofs, +} + +/// Patricia proofs DB operation, which can be either delete or write. +/// Expected by [ForestWriterWithMetadataAndWitnesses::write_with_metadata_and_witnesses], which +/// accumulates all DB operations to guarantee atomicity. +pub enum PatriciaProofsUpdate { + Write(PatriciaProofsWrite), + Delete(BlockNumber), +} + +/// Reads committed OS-input witness payload (structured [`StarknetForestProofs`]) for a block +/// height. +#[async_trait] +pub trait ForestReaderWithWitnesses: + ForestReader + Send +{ + async fn read_witnesses( + &mut self, + height: BlockNumber, + ) -> ForestResult>; + + /// Fetches Patricia witness paths for OS input, optionally staging serialized trie node KVs on + /// an in-memory overlay so reads match post-commit state before the forest is persisted. + async fn fetch_patricia_witnesses( + &mut self, + classes_trie_root_hash: HashOutput, + contracts_trie_root_hash: HashOutput, + class_sorted_leaf_indices: SortedLeafIndices<'_>, + contract_sorted_leaf_indices: SortedLeafIndices<'_>, + contract_storage_sorted_leaf_indices: &HashMap>, + staged_serialized_forest: Option, + ) -> TraversalResult; +} + +/// Writes forest + metadata + deleted nodes, and applies [`PatriciaProofsUpdate`] in the same +/// batch. +#[async_trait] +pub trait ForestWriterWithMetadataAndWitnesses: ForestWriterWithMetadata + Send { + async fn write_with_metadata_and_witnesses( + &mut self, + filled_forest: &FilledForest, + metadata: HashMap, + deleted_nodes: DeletedNodes, + patricia_proofs_update: PatriciaProofsUpdate, + ) -> SerializationResult; +} + +/// Forest storage with empty [`ForestReader::InitialReadContext`] plus OS-input witness read/write. +pub trait ForestStorageWithWitnesses: + ForestReaderWithWitnesses + ForestWriterWithMetadataAndWitnesses + StorageInitializer +{ +} + +impl ForestStorageWithWitnesses for T where + T: ForestReaderWithWitnesses + ForestWriterWithMetadataAndWitnesses + StorageInitializer +{ +} diff --git a/crates/starknet_committer/src/db/index_db/db.rs b/crates/starknet_committer/src/db/index_db/db.rs index ef600a296ab..21ad8066a70 100644 --- a/crates/starknet_committer/src/db/index_db/db.rs +++ b/crates/starknet_committer/src/db/index_db/db.rs @@ -3,17 +3,29 @@ use std::marker::PhantomData; use std::sync::LazyLock; use async_trait::async_trait; +#[cfg(feature = "os_input")] +use starknet_api::block::BlockNumber; use starknet_api::core::{ContractAddress, PATRICIA_KEY_UPPER_BOUND_FELT}; use starknet_api::hash::{HashOutput, StateRoots}; use starknet_patricia::db_layout::{NodeLayout, NodeLayoutFor}; use starknet_patricia::patricia_merkle_tree::filled_tree::node::FilledNode; use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications}; +#[cfg(feature = "os_input")] +use starknet_patricia::patricia_merkle_tree::traversal::TraversalResult; use starknet_patricia::patricia_merkle_tree::types::NodeIndex; use starknet_patricia::patricia_merkle_tree::updated_skeleton_tree::hash_function::TreeHashFunction; use starknet_patricia_storage::db_object::{DBObject, EmptyKeyContext, HasStaticPrefix}; use starknet_patricia_storage::errors::{DeserializationError, SerializationResult}; +#[cfg(feature = "os_input")] +use starknet_patricia_storage::map_storage::MapStorage; #[cfg(any(feature = "testing", test))] use starknet_patricia_storage::storage_trait::AsyncStorage; +#[cfg(feature = "os_input")] +use starknet_patricia_storage::storage_trait::DbOperation; +#[cfg(feature = "os_input")] +use starknet_patricia_storage::storage_trait::ImmutableReadOnlyStorage; +#[cfg(feature = "os_input")] +use starknet_patricia_storage::storage_trait::PatriciaStorageError; use starknet_patricia_storage::storage_trait::{ DbHashMap, DbKey, @@ -22,10 +34,19 @@ use starknet_patricia_storage::storage_trait::{ PatriciaStorageResult, Storage, }; +#[cfg(feature = "os_input")] +use starknet_patricia_storage::two_layer_storage::TwoLayerStorage; use starknet_types_core::felt::Felt; use crate::block_committer::input::{InputContext, ReaderConfig, StarknetStorageValue}; use crate::db::db_layout::DbLayout; +#[cfg(feature = "os_input")] +use crate::db::forest_trait::forest_trait_witnesses::{ + ForestReaderWithWitnesses, + ForestWriterWithMetadataAndWitnesses, + PatriciaProofsUpdate, + PatriciaProofsWrite, +}; use crate::db::forest_trait::{ read_forest, serialize_forest, @@ -50,13 +71,20 @@ use crate::db::index_db::types::{ IndexLayoutSubTree, IndexNodeContext, }; +use crate::db::serde_db_utils::DbBlockNumber; use crate::forest::deleted_nodes::DeletedNodes; use crate::forest::filled_forest::FilledForest; +#[cfg(feature = "os_input")] +use crate::forest::forest_errors::ForestError; use crate::forest::forest_errors::ForestResult; use crate::forest::original_skeleton_forest::{ForestSortedIndices, OriginalSkeletonForest}; use crate::hash_function::hash::TreeHashFunctionImpl; use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState; +#[cfg(feature = "os_input")] +use crate::patricia_merkle_tree::tree::{fetch_all_patricia_paths, SortedLeafIndices}; use crate::patricia_merkle_tree::types::CompiledClassHash; +#[cfg(feature = "os_input")] +use crate::patricia_merkle_tree::types::StarknetForestProofs; /// Set to 2^251 + 1 to avoid collisions with contract addresses prefixes. pub(crate) static FIRST_AVAILABLE_PREFIX_FELT: LazyLock = @@ -84,6 +112,16 @@ static STATE_ROOT_METADATA_PREFIX: LazyLock<[u8; 32]> = LazyLock::new(|| { (Felt::from_bytes_be(&STATE_DIFF_HASH_METADATA_PREFIX) + Felt::ONE).to_bytes_be() }); +/// Prefix for accessed-keys digest metadata (committed per block). +pub(crate) static ACCESSED_KEYS_DIGEST_METADATA_PREFIX: LazyLock<[u8; 32]> = + LazyLock::new(|| (Felt::from_bytes_be(&STATE_ROOT_METADATA_PREFIX) + Felt::ONE).to_bytes_be()); + +/// Prefix for Patricia proofs payload (per block). +#[cfg_attr(not(feature = "os_input"), expect(dead_code))] +pub(crate) static PATRICIA_PATHS_PREFIX: LazyLock<[u8; 32]> = LazyLock::new(|| { + (Felt::from_bytes_be(&ACCESSED_KEYS_DIGEST_METADATA_PREFIX) + Felt::ONE).to_bytes_be() +}); + pub struct IndexDb { storage: S, phantom: PhantomData, @@ -212,8 +250,8 @@ where async fn read<'a>( &mut self, roots: StateRoots, - storage_updates: &'a HashMap>, - classes_updates: &'a LeafModifications, + storage_updates: &HashMap>, + classes_updates: &LeafModifications, forest_sorted_indices: &'a ForestSortedIndices<'a>, config: ReaderConfig, ) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap)> { @@ -267,28 +305,26 @@ impl ForestWriter for IndexDb { #[async_trait] impl ForestMetadata for IndexDb { fn metadata_key(metadata_type: ForestMetadataType) -> DbKey { - let mut key = Vec::with_capacity(64); - match metadata_type { - // Padding to 64byte keys to keep the 32byte prefix aligned between metadata and - // patricia nodes. + // Padding to 64byte keys to keep the 32byte prefix aligned between metadata and + // patricia nodes. + DbKey(match metadata_type { ForestMetadataType::CommitmentOffset => { + let mut key = Vec::with_capacity(64); key.extend_from_slice(&*COMMITMENT_OFFSET_METADATA_PREFIX); key.extend_from_slice(&[0u8; 32]); + key } ForestMetadataType::StateDiffHash(block_number) => { - key.extend_from_slice(&*STATE_DIFF_HASH_METADATA_PREFIX); - let block_number_bytes: [u8; 8] = block_number.serialize(); - key.extend_from_slice(&block_number_bytes); - key.extend_from_slice(&[0u8; 24]); + block_number_based_key(&STATE_DIFF_HASH_METADATA_PREFIX, block_number) } ForestMetadataType::StateRoot(block_number) => { - key.extend_from_slice(&*STATE_ROOT_METADATA_PREFIX); - let block_number_bytes: [u8; 8] = block_number.serialize(); - key.extend_from_slice(&block_number_bytes); - key.extend_from_slice(&[0u8; 24]); + block_number_based_key(&STATE_ROOT_METADATA_PREFIX, block_number) } - } - DbKey(key) + #[cfg(feature = "os_input")] + ForestMetadataType::AccessedKeysDigest(block_number) => { + block_number_based_key(&ACCESSED_KEYS_DIGEST_METADATA_PREFIX, block_number) + } + }) } async fn get_from_storage(&mut self, db_key: DbKey) -> ForestResult> { @@ -320,6 +356,127 @@ impl ForestWriterWithMetadata for IndexDb { } } +fn block_number_based_key(prefix: &[u8; 32], block_number: DbBlockNumber) -> Vec { + let mut key = Vec::with_capacity(64); + key.extend_from_slice(prefix); + key.extend_from_slice(&block_number.serialize()); + key.extend_from_slice(&[0u8; 24]); + key +} + +#[cfg(feature = "os_input")] +#[async_trait] +impl ForestReaderWithWitnesses + for IndexDb +{ + async fn read_witnesses( + &mut self, + height: BlockNumber, + ) -> ForestResult> { + let db_key = DbKey(block_number_based_key(&PATRICIA_PATHS_PREFIX, DbBlockNumber(height))); + + Ok(match self.get_from_storage(db_key).await? { + None => None, + Some(DbValue(bytes)) => { + Some(StarknetForestProofs::deserialize(&DbValue(bytes)).map_err(|e| { + ForestError::PatriciaStorage(PatriciaStorageError::Deserialization(e)) + })?) + } + }) + } + + async fn fetch_patricia_witnesses( + &mut self, + classes_trie_root_hash: HashOutput, + contracts_trie_root_hash: HashOutput, + class_sorted_leaf_indices: SortedLeafIndices<'_>, + contract_sorted_leaf_indices: SortedLeafIndices<'_>, + contract_storage_sorted_leaf_indices: &HashMap>, + staged_serialized_forest: Option, + ) -> TraversalResult { + match staged_serialized_forest { + None => { + fetch_all_patricia_paths::( + &mut self.storage, + classes_trie_root_hash, + contracts_trie_root_hash, + class_sorted_leaf_indices, + contract_sorted_leaf_indices, + contract_storage_sorted_leaf_indices, + ) + .await + } + Some(modifications) => { + let mut overlay = MapStorage::default(); + overlay.mset(modifications).await?; + let mut layered = TwoLayerStorage::new(overlay, &self.storage); + fetch_all_patricia_paths::( + &mut layered, + classes_trie_root_hash, + contracts_trie_root_hash, + class_sorted_leaf_indices, + contract_sorted_leaf_indices, + contract_storage_sorted_leaf_indices, + ) + .await + } + } + } +} + +#[cfg(feature = "os_input")] +#[async_trait] +impl ForestWriterWithMetadataAndWitnesses for IndexDb { + async fn write_with_metadata_and_witnesses( + &mut self, + filled_forest: &FilledForest, + metadata: HashMap, + deleted_nodes: DeletedNodes, + patricia_proofs_update: PatriciaProofsUpdate, + ) -> SerializationResult { + let mut operations = DbOperationMap::new(); + Self::append_forest_and_metadata(&mut operations, filled_forest, metadata, deleted_nodes)?; + match patricia_proofs_update { + PatriciaProofsUpdate::Delete(block_number) => { + operations.insert( + Self::metadata_key(ForestMetadataType::AccessedKeysDigest(DbBlockNumber( + block_number, + ))), + DbOperation::Delete, + ); + operations.insert( + DbKey(block_number_based_key( + &PATRICIA_PATHS_PREFIX, + DbBlockNumber(block_number), + )), + DbOperation::Delete, + ); + } + PatriciaProofsUpdate::Write(PatriciaProofsWrite { + block_number, + keys_digest, + witnesses, + }) => { + let encoded = witnesses.serialize()?; + operations.insert( + Self::metadata_key(ForestMetadataType::AccessedKeysDigest(DbBlockNumber( + block_number, + ))), + DbOperation::Set(DbValue(keys_digest.to_vec())), + ); + operations.insert( + DbKey(block_number_based_key( + &PATRICIA_PATHS_PREFIX, + DbBlockNumber(block_number), + )), + DbOperation::Set(encoded), + ); + } + } + Ok(self.write_updates(operations).await) + } +} + fn extract_root_hash(root: &Option) -> Result where TreeHashFunctionImpl: TreeHashFunction, diff --git a/crates/starknet_committer/src/db/trie_traversal.rs b/crates/starknet_committer/src/db/trie_traversal.rs index 13a1e0a2e35..cc9ad0c2761 100644 --- a/crates/starknet_committer/src/db/trie_traversal.rs +++ b/crates/starknet_committer/src/db/trie_traversal.rs @@ -662,7 +662,7 @@ pub async fn create_original_skeleton_tree<'a, L: Leaf, Layout: NodeLayout<'a, L /// sequentially. pub async fn create_storage_tries<'a, Layout>( storage: &mut impl Storage, - actual_storage_updates: &'a HashMap>, + actual_storage_updates: &HashMap>, original_contracts_trie_leaves: &HashMap, config: &ReaderConfig, storage_tries_sorted_indices: &'a HashMap>, @@ -796,33 +796,47 @@ where } /// Holds all data needed to build one storage trie concurrently. -/// Implements [StorageTask] so that [GatherableStorage::gather] can drive it. -struct TrieReadTask<'a, Layout: NodeLayoutFor> { +/// +/// Two distinct lifetimes are needed: +/// - `'indices` is the lifetime of the caller-owned index vectors that produced +/// `sorted_leaf_indices`. +/// - `'updates` is the borrow of `updates`, used only during construction of the original skeleton +/// tree, but does not retain a reference into the output `OriginalSkeletonTreeImpl<'indices>`. +/// +/// Unifying the lifetimes would make the returned `OriginalSkeletonForest<'indices>` to +/// borrow the storage update maps too, which would prevent `commit_block` from later moving those +/// maps by value into the compute phase. +struct TrieReadTask<'indices, 'updates, Layout: NodeLayoutFor> { address: ContractAddress, - updates: &'a LeafModifications, + updates: &'updates LeafModifications, storage_root_hash: HashOutput, - sorted_leaf_indices: SortedLeafIndices<'a>, + sorted_leaf_indices: SortedLeafIndices<'indices>, warn_on_trivial_modifications: bool, _layout: PhantomData, } -impl<'a, S, Layout> StorageTaskOutput for TrieReadTask<'a, Layout> +impl<'indices, 'updates, S, Layout> StorageTaskOutput + for TrieReadTask<'indices, 'updates, Layout> where S: ImmutableReadOnlyStorage, Layout: NodeLayoutFor + Send + 'static, { - type Output = ForestResult<(ContractAddress, OriginalSkeletonTreeImpl<'a>)>; + type Output = ForestResult<(ContractAddress, OriginalSkeletonTreeImpl<'indices>)>; } #[async_trait] -impl<'a, 's, S, Layout> StorageTask<'s, S> for TrieReadTask<'a, Layout> +impl<'indices, 'updates, 'storage, S, Layout> StorageTask<'storage, S> + for TrieReadTask<'indices, 'updates, Layout> where - S: ImmutableReadOnlyStorage + 's, + S: ImmutableReadOnlyStorage + 'storage, Layout: NodeLayoutFor + Send + 'static, >::DbLeaf: HasStaticPrefix, { - async fn run_with_storage(self, storage: &mut ReadsCollectorStorage<'s, S>) -> Self::Output { + async fn run_with_storage( + self, + storage: &mut ReadsCollectorStorage<'storage, S>, + ) -> Self::Output { let skeleton = create_storage_trie::( storage, self.address, @@ -838,7 +852,7 @@ where async fn create_storage_tries_concurrently<'a, S, Layout>( storage: &mut S, - actual_storage_updates: &'a HashMap>, + actual_storage_updates: &HashMap>, original_contracts_trie_leaves: &HashMap, warn_on_trivial_modifications: bool, storage_tries_sorted_indices: &'a HashMap>, diff --git a/crates/starknet_committer/src/patricia_merkle_tree/starknet_forest_proofs_serde.rs b/crates/starknet_committer/src/patricia_merkle_tree/starknet_forest_proofs_serde.rs index 9b1997af6ea..63a398d72dc 100644 --- a/crates/starknet_committer/src/patricia_merkle_tree/starknet_forest_proofs_serde.rs +++ b/crates/starknet_committer/src/patricia_merkle_tree/starknet_forest_proofs_serde.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use serde::de::Error as DeError; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; use starknet_api::hash::HashOutput; use starknet_patricia::patricia_merkle_tree::node_data::inner_node::{ @@ -125,6 +126,26 @@ impl StarknetForestProofs { } } +impl serde::Serialize for StarknetForestProofs { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let encoded = Self::serialize(self).map_err(serde::ser::Error::custom)?; + encoded.0.serialize(serializer) + } +} + +impl<'de> serde::Deserialize<'de> for StarknetForestProofs { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let bytes = Vec::::deserialize(deserializer)?; + Self::deserialize(&DbValue(bytes)).map_err(DeError::custom) + } +} + fn bincode_ser_err(error: bincode::Error) -> SerializationError { SerializationError::IOSerialize(std::io::Error::other(error)) } diff --git a/crates/starknet_committer/src/patricia_merkle_tree/tree.rs b/crates/starknet_committer/src/patricia_merkle_tree/tree.rs index dcfade54499..843fa487c03 100644 --- a/crates/starknet_committer/src/patricia_merkle_tree/tree.rs +++ b/crates/starknet_committer/src/patricia_merkle_tree/tree.rs @@ -91,6 +91,16 @@ impl LeavesRequest { contract_storage_leaf_indices, } } + + /// Total number of trie leaves requested (classes, contracts, and storage slots). + pub fn total_leaf_count(&self) -> usize { + self.class_leaf_indices.len() + + self.contract_leaf_indices.len() + + self + .contract_storage_leaf_indices + .values() + .fold(0, |count, leaf_indices| count + leaf_indices.len()) + } } impl<'a> From<&'a mut LeavesRequest> for SortedLeavesRequest<'a> { diff --git a/crates/starknet_committer/src/patricia_merkle_tree/types.rs b/crates/starknet_committer/src/patricia_merkle_tree/types.rs index a515d914800..b9a6a946965 100644 --- a/crates/starknet_committer/src/patricia_merkle_tree/types.rs +++ b/crates/starknet_committer/src/patricia_merkle_tree/types.rs @@ -6,6 +6,7 @@ use starknet_api::hash::HashOutput; use starknet_patricia::impl_from_hex_for_felt_wrapper; use starknet_patricia::patricia_merkle_tree::filled_tree::tree::FilledTreeImpl; use starknet_patricia::patricia_merkle_tree::node_data::inner_node::PreimageMap; +use starknet_patricia::patricia_merkle_tree::node_data::leaf::SkeletonLeaf; use starknet_patricia::patricia_merkle_tree::types::NodeIndex; use starknet_types_core::felt::{Felt, FromStrError}; @@ -23,6 +24,12 @@ pub fn class_hash_into_node_index(class_hash: &ClassHash) -> NodeIndex { #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct CompiledClassHash(pub Felt); +impl From for SkeletonLeaf { + fn from(compiled_class_hash: CompiledClassHash) -> Self { + SkeletonLeaf::from(compiled_class_hash.0) + } +} + impl AsRef for CompiledClassHash { fn as_ref(&self) -> &CompiledClassHash { self @@ -36,13 +43,13 @@ pub type ClassesTrie = FilledTreeImpl; pub type ContractsTrie = FilledTreeImpl; pub type StorageTrieMap = HashMap; -#[derive(Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct ContractsTrieProof { pub nodes: PreimageMap, pub leaves: HashMap, } -#[derive(Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct StarknetForestProofs { pub classes_trie_proof: PreimageMap, pub contracts_trie_proof: ContractsTrieProof, diff --git a/crates/starknet_committer_and_os_cli/src/committer_cli/tests/python_tests.rs b/crates/starknet_committer_and_os_cli/src/committer_cli/tests/python_tests.rs index a1db9718a1b..3200201fb05 100644 --- a/crates/starknet_committer_and_os_cli/src/committer_cli/tests/python_tests.rs +++ b/crates/starknet_committer_and_os_cli/src/committer_cli/tests/python_tests.rs @@ -682,7 +682,7 @@ async fn test_storage_node(data: HashMap) -> CommitterPythonTest /// Generates a dummy random filled forest and serializes it to a JSON string. pub(crate) async fn filled_forest_output_test() -> CommitterPythonTestResult { - let dummy_forest = SerializedForest(FilledForest::dummy_random(&mut rand::thread_rng(), None)); + let dummy_forest = SerializedForest(FilledForest::dummy_random(&mut rand::rng(), None)); let output = dummy_forest.forest_to_output().await.map_err(|error| { PythonTestError::SpecificError(CommitterSpecificTestError::Serialization(error)) })?; diff --git a/crates/starknet_committer_cli/src/commands.rs b/crates/starknet_committer_cli/src/commands.rs index 35896132118..aae338b0f61 100644 --- a/crates/starknet_committer_cli/src/commands.rs +++ b/crates/starknet_committer_cli/src/commands.rs @@ -12,10 +12,10 @@ use apollo_storage::state::StateStorageReader; use apollo_storage::{open_storage, StorageConfig, StorageReader, StorageScope}; use blake2::digest::consts::U31; use blake2::{Blake2s, Digest}; -use rand::distributions::Uniform; +use rand::distr::Uniform; use rand::prelude::IteratorRandom; use rand::rngs::SmallRng; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use starknet_api::block::BlockNumber; use starknet_api::core::ChainId; use starknet_api::hash::HashOutput; @@ -181,8 +181,7 @@ impl BenchmarkFlavor { // most recent leaves. let start_index = total_leaves - (FLAVOR_OVERLAP_WARMUP_BLOCKS * n_updates_arg); let n_overlap_leaves = n_updates_arg - twenty_percent; - let updated_keys = - (start_index..total_leaves).choose_multiple(rng, n_overlap_leaves); + let updated_keys = (start_index..total_leaves).sample(rng, n_overlap_leaves); let new_keys = (total_leaves..(total_leaves + twenty_percent)).collect(); [updated_keys, new_keys].concat() }) @@ -397,7 +396,7 @@ fn apply_interference( // Avoid creating an iterator over the entire range - select random leaves, with // possible repetition. Probability of repitition will decrease as the number of // leaves increases. - let dist = Uniform::new(0, total_leaves); + let dist = Uniform::new(0, total_leaves).unwrap(); let preimages = (0..INTERFERENCE_READ_1K_EVERY_BLOCK_N_READS) .map(|_| rng.sample(dist)) .collect::>(); diff --git a/crates/starknet_os/Cargo.toml b/crates/starknet_os/Cargo.toml index dd0878e49b9..680a72c8789 100644 --- a/crates/starknet_os/Cargo.toml +++ b/crates/starknet_os/Cargo.toml @@ -79,7 +79,7 @@ cairo-lang-utils.workspace = true ethnum.workspace = true expect-test.workspace = true itertools.workspace = true -num-bigint = { workspace = true, features = ["rand"] } +num-bigint.workspace = true rstest.workspace = true starknet_committer.workspace = true starknet_patricia = { workspace = true, features = ["testing"] } diff --git a/crates/starknet_os/src/hint_processor/aggregator_hint_processor.rs b/crates/starknet_os/src/hint_processor/aggregator_hint_processor.rs index fbf6ea4cc43..33fb67d66f4 100644 --- a/crates/starknet_os/src/hint_processor/aggregator_hint_processor.rs +++ b/crates/starknet_os/src/hint_processor/aggregator_hint_processor.rs @@ -3,7 +3,7 @@ use std::boxed::Box; use std::path::PathBuf; use cairo_lang_casm::hints::{CoreHint, CoreHintBase, Hint as Cairo1Hint, StarknetHint}; -use cairo_lang_runner::casm_run::{cell_ref_to_relocatable, execute_core_hint_base}; +use cairo_lang_runner::casm_run::execute_core_hint_base; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::{ BuiltinHintProcessor, HintProcessorData as Cairo0Hint, @@ -14,7 +14,6 @@ use cairo_vm::types::program::Program; use cairo_vm::vm::errors::hint_errors::HintError as VmHintError; use cairo_vm::vm::runners::cairo_runner::ResourceTracker; use cairo_vm::vm::vm_core::VirtualMachine; -use rand::Rng; use serde::Deserialize; use starknet_types_core::felt::Felt; use tracing::level_filters::LevelFilter; diff --git a/crates/starknet_os/src/hint_processor/common_hint_processor.rs b/crates/starknet_os/src/hint_processor/common_hint_processor.rs index 82eef02c1b3..2ad53c17787 100644 --- a/crates/starknet_os/src/hint_processor/common_hint_processor.rs +++ b/crates/starknet_os/src/hint_processor/common_hint_processor.rs @@ -105,25 +105,7 @@ macro_rules! impl_common_hint_processor_logic { // Override the [CoreHint::RandomEcPoint] implementation to make the output // deterministic (using seeded randomness). Cairo1Hint::Core(CoreHintBase::Core(CoreHint::RandomEcPoint { x, y })) => { - // TODO(Dori): use the random_ec_point function from the compiler repo when - // available, instead of inlining the implementation. - /// The Beta value of the Starkware elliptic curve. - pub const BETA: Felt = Felt::from_hex_unchecked( - "0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89", - ); - // Use the seeded randomness. - let rng = self.get_rng(); - let (random_x, random_y) = loop { - // Randomizing 31 bytes to make sure it is in range. - let x_bytes: [u8; 31] = rng.gen(); - let random_x = Felt::from_bytes_be_slice(&x_bytes); - let random_y_squared = random_x * random_x * random_x + random_x + BETA; - if let Some(random_y) = random_y_squared.sqrt() { - break (random_x, random_y); - } - }; - cairo_lang_runner::insert_value_to_cellref!(vm, x, random_x)?; - cairo_lang_runner::insert_value_to_cellref!(vm, y, random_y)?; + cairo_lang_runner::casm_run::random_ec_point(vm, x, y, self.get_rng())?; Ok(HintExtension::default()) } Cairo1Hint::Core(hint) => { diff --git a/crates/starknet_os/src/hint_processor/snos_hint_processor.rs b/crates/starknet_os/src/hint_processor/snos_hint_processor.rs index 6d10b757ce6..b76fb95eb6b 100644 --- a/crates/starknet_os/src/hint_processor/snos_hint_processor.rs +++ b/crates/starknet_os/src/hint_processor/snos_hint_processor.rs @@ -9,7 +9,7 @@ use blockifier::state::state_api::StateReader; #[cfg(any(feature = "testing", test))] use blockifier::test_utils::dict_state_reader::DictStateReader; use cairo_lang_casm::hints::{CoreHint, CoreHintBase, Hint as Cairo1Hint, StarknetHint}; -use cairo_lang_runner::casm_run::{cell_ref_to_relocatable, execute_core_hint_base}; +use cairo_lang_runner::casm_run::execute_core_hint_base; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::{ BuiltinHintProcessor, @@ -22,7 +22,7 @@ use cairo_vm::types::relocatable::Relocatable; use cairo_vm::vm::errors::hint_errors::HintError as VmHintError; use cairo_vm::vm::runners::cairo_runner::ResourceTracker; use cairo_vm::vm::vm_core::VirtualMachine; -use rand::{Rng, SeedableRng}; +use rand::SeedableRng; use starknet_api::core::{ClassHash, CompiledClassHash}; use starknet_api::deprecated_contract_class::ContractClass; use starknet_types_core::felt::Felt; diff --git a/crates/starknet_os/src/hints/hint_implementation/bls_field/tests.rs b/crates/starknet_os/src/hints/hint_implementation/bls_field/tests.rs index 34ae9b03856..c2c4f775155 100644 --- a/crates/starknet_os/src/hints/hint_implementation/bls_field/tests.rs +++ b/crates/starknet_os/src/hints/hint_implementation/bls_field/tests.rs @@ -7,9 +7,9 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::types::program::Program; use cairo_vm::types::relocatable::MaybeRelocatable; use ethnum::U256; -use num_bigint::{BigInt, BigUint, RandBigInt, RandomBits, Sign, ToBigInt}; +use num_bigint::{BigInt, BigUint, Sign, ToBigInt}; use num_integer::Integer; -use rand::Rng; +use rand::RngExt; use rstest::rstest; use starknet_types_core::felt::Felt; @@ -62,7 +62,7 @@ fn run_reduced_mul_test(a_split: &[Felt], b_split: &[Felt]) { #[test] fn test_bigint3_to_uint256() { let mut rng = seeded_random_prng(); - let random_u256_big_uint: BigUint = rng.sample(RandomBits::new(256)); + let random_u256_big_uint = BigUint::from_bytes_be(&rng.random::<[u8; 32]>()); let random_u256_bigint = BigInt::from_biguint(Sign::Plus, random_u256_big_uint); let cairo_bigin3 = EndpointArg::Value(ValueArg::Array( split_bigint3(random_u256_bigint.clone()) @@ -140,13 +140,13 @@ fn test_horner_eval(#[values(0, 100, 4096)] n_coefficients: usize) { let mut explicit_args: Vec = vec![]; explicit_args.push(n_coefficients.into()); let coefficients: Vec = (0..n_coefficients) - .map(|_| Felt::from(RandBigInt::gen_bigint_range(&mut rng, &0.into(), &DEFAULT_PRIME))) + .map(|_| Felt::from_bytes_be_slice(rng.random::<[u8; 30]>().as_slice())) .collect(); explicit_args.push(EndpointArg::Pointer(PointerArg::Array( coefficients.iter().cloned().map(MaybeRelocatable::from).collect(), ))); - let point = RandBigInt::gen_bigint_range(&mut rng, &0.into(), &BLS_PRIME.to_bigint().unwrap()); + let point: BigInt = BigUint::from_bytes_be(rng.random::<[u8; 30]>().as_slice()).into(); explicit_args.push(EndpointArg::Value(ValueArg::Array( split_bigint3(point.clone()).unwrap().iter().map(MaybeRelocatable::from).collect(), ))); @@ -219,10 +219,10 @@ fn test_reduced_mul_random() { // Generate a,b in (-REDUCED_MUL_LIMB_LIMIT, REDUCED_MUL_LIMB_LIMIT). let mut rng = seeded_random_prng(); let a_split = (0..3) - .map(|_| rng.gen_range(-REDUCED_MUL_LIMB_BOUND + 1..REDUCED_MUL_LIMB_BOUND).into()) + .map(|_| rng.random_range(-REDUCED_MUL_LIMB_BOUND + 1..REDUCED_MUL_LIMB_BOUND).into()) .collect::>(); let b_split = (0..3) - .map(|_| rng.gen_range(-REDUCED_MUL_LIMB_BOUND + 1..REDUCED_MUL_LIMB_BOUND).into()) + .map(|_| rng.random_range(-REDUCED_MUL_LIMB_BOUND + 1..REDUCED_MUL_LIMB_BOUND).into()) .collect::>(); run_reduced_mul_test(&a_split, &b_split) diff --git a/crates/starknet_os/src/hints/hint_implementation/kzg/test_utils.rs b/crates/starknet_os/src/hints/hint_implementation/kzg/test_utils.rs index 8d6d5f37cec..a3659010d85 100644 --- a/crates/starknet_os/src/hints/hint_implementation/kzg/test_utils.rs +++ b/crates/starknet_os/src/hints/hint_implementation/kzg/test_utils.rs @@ -7,9 +7,9 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::types::layout_name::LayoutName; use cairo_vm::types::relocatable::MaybeRelocatable; use cairo_vm::vm::runners::cairo_runner::{CairoRunner, ExecutionResources}; -use num_bigint::{BigUint, RandBigInt}; +use num_bigint::BigUint; use rand::rngs::SmallRng; -use rand::SeedableRng; +use rand::{RngExt, SeedableRng}; use starknet_types_core::felt::Felt; use crate::hint_processor::common_hint_processor::CommonHintProcessor; @@ -78,11 +78,12 @@ pub fn run_compute_os_kzg_commitment_info(n: usize) -> (CairoRunner, Option().as_slice())) + }) .collect::>(); let MaybeRelocatable::RelocatableValue(start_ptr) = runner.vm.gen_arg(&data).unwrap() else { panic!("Failed to generate start pointer"); diff --git a/crates/starknet_os/src/hints/hint_implementation/output.rs b/crates/starknet_os/src/hints/hint_implementation/output.rs index d2e07875859..03d97cb22a2 100644 --- a/crates/starknet_os/src/hints/hint_implementation/output.rs +++ b/crates/starknet_os/src/hints/hint_implementation/output.rs @@ -2,8 +2,8 @@ use std::cmp::min; use cairo_vm::hint_processor::hint_processor_utils::felt_to_usize; use cairo_vm::types::relocatable::MaybeRelocatable; -use rand::rngs::OsRng; -use rand::RngCore; +use rand::rngs::SysRng; +use rand::TryRng; use sha2::{Digest, Sha256}; use starknet_types_core::felt::Felt; @@ -149,7 +149,7 @@ pub(crate) fn set_n_updates_small(mut ctx: HintContext<'_>) -> OsHintResult { pub(crate) fn calculate_keys_using_sha256_hash(mut ctx: HintContext<'_>) -> OsHintResult { // Generate a cryptographically secure random seed. let mut random_bytes = [0u8; 32]; - OsRng.fill_bytes(&mut random_bytes); + SysRng.try_fill_bytes(&mut random_bytes).expect("OS RNG should not fail"); let mut hasher = Sha256::new(); hasher.update(random_bytes); diff --git a/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/state_diff_encryption_test.rs b/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/state_diff_encryption_test.rs index 5a65e04439d..c1f3b25102a 100644 --- a/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/state_diff_encryption_test.rs +++ b/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/state_diff_encryption_test.rs @@ -6,9 +6,8 @@ use cairo_vm::types::layout_name::LayoutName; use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable}; use cairo_vm::vm::runners::cairo_runner::CairoRunner; use itertools::Itertools; -use num_bigint::BigUint; use rand::rngs::StdRng; -use rand::{Rng, SeedableRng}; +use rand::{RngExt, SeedableRng}; use rstest::rstest; use starknet_types_core::felt::Felt; @@ -79,7 +78,7 @@ fn generate_committee_private_keys_and_symmetric_key( ) -> (Vec, Felt) { let mut rng = StdRng::seed_from_u64(seed); let mut get_random_nonzero_felt = - || Felt::from(rng.gen_range(BigUint::new(vec![1])..Felt::prime())); + || Felt::from_bytes_be_slice(rng.random::<[u8; 30]>().as_slice()) + Felt::ONE; let private_keys = (0..num_keys).map(|_| get_random_nonzero_felt()).collect(); diff --git a/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/utils_test.rs b/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/utils_test.rs index 2591c799d2f..ff2448b98c5 100644 --- a/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/utils_test.rs +++ b/crates/starknet_os/src/hints/hint_implementation/state_diff_encryption/utils_test.rs @@ -1,5 +1,5 @@ use ark_bls12_381::Fr; -use rand::Rng; +use rand::RngExt; use starknet_types_core::curve::AffinePoint; use starknet_types_core::felt::Felt; @@ -18,16 +18,16 @@ use crate::io::os_output_types::{PartialOsStateDiff, TryFromOutputIter}; #[test] fn test_encrypt_decrypt_roundtrip_random() { - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); // Random number of keys. - let n_keys: usize = rng.gen_range(1..=5); + let n_keys: usize = rng.random_range(1..=5); // Generate private keys and corresponding public key x-coordinates. let mut private_keys: Vec = Vec::with_capacity(n_keys); let mut public_keys: Vec = Vec::with_capacity(n_keys); for _ in 0..n_keys { - let private_key = Felt::from(rng.gen_range(1..=1_000_000)); + let private_key = Felt::from(rng.random_range(1..=1_000_000)); let public_key_x = (&AffinePoint::generator() * private_key).x(); private_keys.push(private_key); public_keys.push(public_key_x); @@ -36,18 +36,18 @@ fn test_encrypt_decrypt_roundtrip_random() { // Generate SN private keys. let mut sn_private_keys: Vec = Vec::with_capacity(n_keys); for _ in 0..n_keys { - let sn_priv_scalar: u64 = rng.gen_range(1..=1_000_000); + let sn_priv_scalar: u64 = rng.random_range(1..=1_000_000); sn_private_keys.push(Felt::from(sn_priv_scalar)); } // Random symmetric key. - let symmetric_key = Felt::from_bytes_be(&rng.gen::<[u8; 32]>()); + let symmetric_key = Felt::from_bytes_be(&rng.random::<[u8; 32]>()); // Random state diff. - let state_diff_length: usize = rng.gen_range(0..=20); + let state_diff_length: usize = rng.random_range(0..=20); let mut state_diff: Vec = Vec::with_capacity(state_diff_length); for _ in 0..state_diff_length { - state_diff.push(Felt::from_bytes_be(&rng.gen::<[u8; 32]>())) + state_diff.push(Felt::from_bytes_be(&rng.random::<[u8; 32]>())) } // Encrypt and then decrypt with every keypair. @@ -69,7 +69,7 @@ fn test_encrypt_decrypt_roundtrip_random() { #[test] fn test_decrypt_state_diff_from_blobs() { - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); // Unencrypted DA segment of output with `full_output=false` and `use_kzg_da=true`. let da_segment = vec![ @@ -97,13 +97,13 @@ fn test_decrypt_state_diff_from_blobs() { .expect("Failed to parse DA segment into PartialOsStateDiff"); // Random number of keys. - let n_keys: usize = rng.gen_range(1..=5); + let n_keys: usize = rng.random_range(1..=5); // Generate private keys and corresponding public key x-coordinates. let mut private_keys: Vec = Vec::with_capacity(n_keys); let mut public_keys: Vec = Vec::with_capacity(n_keys); for _ in 0..n_keys { - let private_key = Felt::from(rng.gen_range(1..=1_000_000)); + let private_key = Felt::from(rng.random_range(1..=1_000_000)); let public_key_x = (&AffinePoint::generator() * private_key).x(); private_keys.push(private_key); public_keys.push(public_key_x); @@ -112,12 +112,12 @@ fn test_decrypt_state_diff_from_blobs() { // Generate SN private keys. let mut sn_private_keys: Vec = Vec::with_capacity(n_keys); for _ in 0..n_keys { - let sn_priv_scalar: u64 = rng.gen_range(1..=1_000_000); + let sn_priv_scalar: u64 = rng.random_range(1..=1_000_000); sn_private_keys.push(Felt::from(sn_priv_scalar)); } // Random symmetric key. - let symmetric_key = Felt::from_bytes_be(&rng.gen::<[u8; 32]>()); + let symmetric_key = Felt::from_bytes_be(&rng.random::<[u8; 32]>()); // Encrypt the DA segment let encrypted_state_diff = encrypt_state_diff(symmetric_key, &da_segment); diff --git a/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.cairo b/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.cairo new file mode 100644 index 00000000000..f843d73a0d6 --- /dev/null +++ b/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.cairo @@ -0,0 +1,43 @@ +/// Dummy deployable account contract for deterministic deployment resource measurement. +/// Originally compiled with compiler v2.17.0-rc.4. +#[starknet::contract(account)] +mod DeployableForResourceMeasurement { + #[storage] + struct Storage {} + + #[external(v0)] + fn __validate__(self: @ContractState) -> felt252 { + starknet::VALIDATED + } + + #[external(v0)] + fn __validate_deploy__( + self: @ContractState, + class_hash: felt252, + contract_address_salt: felt252, + some_args: Span, + ) -> felt252 { + starknet::VALIDATED + } + + #[external(v0)] + fn __execute__(ref self: ContractState) {} + + /// Constructor accepting variable calldata length. + #[constructor] + fn constructor(ref self: ContractState, some_args: Span) {} + + /// Dummy function to effect the compiled sierra and change the contract address. + #[external(v0)] + fn get_salt(self: @ContractState) -> felt252 { + 0 + } + + /// External endpoint accepting variable calldata length. + #[external(v0)] + fn external(self: @ContractState, some_args: Span) {} + + /// L1 handler accepting variable calldata length. + #[l1_handler] + fn l1_handler(self: @ContractState, from_address: felt252, some_args: Span) {} +} diff --git a/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.casm.json b/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.casm.json new file mode 100644 index 00000000000..6486b870106 --- /dev/null +++ b/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.casm.json @@ -0,0 +1,2062 @@ +{ + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "compiler_version": "2.17.0", + "bytecode": [ + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x3c", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xd", + "0x1104800180018000", + "0x3ef", + "0x482680017ff98000", + "0x1", + "0x48127ff57fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x404", + "0x482480017fff8000", + "0x403", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff9", + "0x0", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280017ff97fff", + "0x10780017fff7fff", + "0x15", + "0x4824800180007ff9", + "0x0", + "0x400280017ff97fff", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x56414c4944", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x2", + "0x482480017ffc8000", + "0x1dec", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x2", + "0x482480017ff68000", + "0x19a0", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x1", + "0x482680017ffa8000", + "0x1e96", + "0x1104800180018000", + "0x3be", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0xcd", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xba", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0x48307ffe80007fff", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa7", + "0x482480017ffd8000", + "0x1", + "0x48127ffd7fff8000", + "0x48307ffe80007fff", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x91", + "0x480080007ffd8000", + "0x482480017ffc8000", + "0x1", + "0x48127ffc7fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffc", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480280017ff97fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480280027ff97fff", + "0x400280037ff97ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0x77", + "0x402780017fff7fff", + "0x1", + "0x400280017ff97ffc", + "0x482480017ffc8000", + "0xffffffffffffffffffffffff00000000", + "0x400280027ff97fff", + "0x480680017fff8000", + "0x0", + "0x48307ffb80007ffc", + "0x48307ff97ffe8000", + "0xa0680017fff8000", + "0x8", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400280037ff97fff", + "0x10780017fff7fff", + "0x5f", + "0x48307ffe80007ffd", + "0x400280037ff97fff", + "0x48307ff780007ff8", + "0x48307ff580017fff", + "0xa0680017fff7fff", + "0x7", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280047ff97fff", + "0x10780017fff7fff", + "0x4e", + "0x400280047ff97fff", + "0x48307ff480007ff5", + "0x48307ffe7ff28000", + "0xa0680017fff8000", + "0x8", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400280057ff97fff", + "0x10780017fff7fff", + "0x3d", + "0x48307ffe80007ffd", + "0x400280057ff97fff", + "0x48307fef7ff08000", + "0x48307ffc7fef8000", + "0x48307ffe80007fff", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xd", + "0x1104800180018000", + "0x34b", + "0x482680017ff98000", + "0x6", + "0x48127fdb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x360", + "0x482480017fff8000", + "0x35f", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007fdf", + "0x0", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280067ff97fff", + "0x10780017fff7fff", + "0x15", + "0x4824800180007fdf", + "0x0", + "0x400280067ff97fff", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x56414c4944", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x7", + "0x482480017ffc8000", + "0xf46", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x7", + "0x482480017fdc8000", + "0xafa", + "0x10780017fff7fff", + "0x42", + "0x482680017ff98000", + "0x6", + "0x482480017fe58000", + "0xf8c", + "0x10780017fff7fff", + "0x12", + "0x482680017ff98000", + "0x5", + "0x482480017fe98000", + "0x11c6", + "0x10780017fff7fff", + "0xc", + "0x482680017ff98000", + "0x4", + "0x482480017fec8000", + "0x139c", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x4", + "0x482480017fed8000", + "0x14c8", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x1", + "0x482480017ff78000", + "0x1aae", + "0x1104800180018000", + "0x307", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x302", + "0x482680017ff98000", + "0x1", + "0x48127ff27fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x2fc", + "0x482680017ff98000", + "0x1", + "0x48127ff57fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x1", + "0x482680017ffa8000", + "0x1e96", + "0x1104800180018000", + "0x2de", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x38", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xd", + "0x1104800180018000", + "0x2c0", + "0x482680017ff98000", + "0x1", + "0x48127ff57fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x2d5", + "0x482480017fff8000", + "0x2d4", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff9", + "0x0", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280017ff97fff", + "0x10780017fff7fff", + "0x11", + "0x4824800180007ff9", + "0x0", + "0x400280017ff97fff", + "0x40780017fff7fff", + "0x1", + "0x482680017ff98000", + "0x2", + "0x482480017ffd8000", + "0x1eb4", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x2", + "0x482480017ff68000", + "0x19a0", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x1", + "0x482680017ffa8000", + "0x1e96", + "0x1104800180018000", + "0x293", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x3c", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xd", + "0x1104800180018000", + "0x275", + "0x482680017ff98000", + "0x1", + "0x48127ff57fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x28a", + "0x482480017fff8000", + "0x289", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff9", + "0x0", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280017ff97fff", + "0x10780017fff7fff", + "0x15", + "0x4824800180007ff9", + "0x0", + "0x400280017ff97fff", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x0", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x2", + "0x482480017ffc8000", + "0x1dec", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x2", + "0x482480017ff68000", + "0x19a0", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x1", + "0x482680017ffa8000", + "0x1e96", + "0x1104800180018000", + "0x244", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0xa3", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x8d", + "0x480280007ffc8000", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffc", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480280017ff97fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480280027ff97fff", + "0x400280037ff97ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0x73", + "0x402780017fff7fff", + "0x1", + "0x400280017ff97ffc", + "0x482480017ffc8000", + "0xffffffffffffffffffffffff00000000", + "0x400280027ff97fff", + "0x480680017fff8000", + "0x0", + "0x48307ffb80007ffc", + "0x48307ff97ffe8000", + "0xa0680017fff8000", + "0x8", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400280037ff97fff", + "0x10780017fff7fff", + "0x5b", + "0x48307ffe80007ffd", + "0x400280037ff97fff", + "0x48307ff780007ff8", + "0x48307ff580017fff", + "0xa0680017fff7fff", + "0x7", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280047ff97fff", + "0x10780017fff7fff", + "0x4a", + "0x400280047ff97fff", + "0x48307ff480007ff5", + "0x48307ffe7ff28000", + "0xa0680017fff8000", + "0x8", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400280057ff97fff", + "0x10780017fff7fff", + "0x39", + "0x48307ffe80007ffd", + "0x400280057ff97fff", + "0x48307fef7ff08000", + "0x48307ffc7fef8000", + "0x48307ffe80007fff", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xd", + "0x1104800180018000", + "0x1e1", + "0x482680017ff98000", + "0x6", + "0x48127fe17fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x1f6", + "0x482480017fff8000", + "0x1f5", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007fe5", + "0x0", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280067ff97fff", + "0x10780017fff7fff", + "0x11", + "0x4824800180007fe5", + "0x0", + "0x400280067ff97fff", + "0x40780017fff7fff", + "0x1", + "0x482680017ff98000", + "0x7", + "0x482480017ffd8000", + "0x132e", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x7", + "0x482480017fe28000", + "0xe1a", + "0x10780017fff7fff", + "0x2c", + "0x482680017ff98000", + "0x6", + "0x482480017feb8000", + "0x12ac", + "0x10780017fff7fff", + "0x12", + "0x482680017ff98000", + "0x5", + "0x482480017fef8000", + "0x14e6", + "0x10780017fff7fff", + "0xc", + "0x482680017ff98000", + "0x4", + "0x482480017ff28000", + "0x16bc", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x4", + "0x482480017ff38000", + "0x17e8", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x1", + "0x482480017ffd8000", + "0x1dce", + "0x1104800180018000", + "0x1ab", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x1", + "0x482680017ffa8000", + "0x1e96", + "0x1104800180018000", + "0x18e", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0xb6", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa3", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0x48307ffe80007fff", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x8d", + "0x480080007ffd8000", + "0x482480017ffc8000", + "0x1", + "0x48127ffc7fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffc", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480280017ff97fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480280027ff97fff", + "0x400280037ff97ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0x73", + "0x402780017fff7fff", + "0x1", + "0x400280017ff97ffc", + "0x482480017ffc8000", + "0xffffffffffffffffffffffff00000000", + "0x400280027ff97fff", + "0x480680017fff8000", + "0x0", + "0x48307ffb80007ffc", + "0x48307ff97ffe8000", + "0xa0680017fff8000", + "0x8", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400280037ff97fff", + "0x10780017fff7fff", + "0x5b", + "0x48307ffe80007ffd", + "0x400280037ff97fff", + "0x48307ff780007ff8", + "0x48307ff580017fff", + "0xa0680017fff7fff", + "0x7", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280047ff97fff", + "0x10780017fff7fff", + "0x4a", + "0x400280047ff97fff", + "0x48307ff480007ff5", + "0x48307ffe7ff28000", + "0xa0680017fff8000", + "0x8", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400280057ff97fff", + "0x10780017fff7fff", + "0x39", + "0x48307ffe80007ffd", + "0x400280057ff97fff", + "0x48307fef7ff08000", + "0x48307ffc7fef8000", + "0x48307ffe80007fff", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xd", + "0x1104800180018000", + "0x123", + "0x482680017ff98000", + "0x6", + "0x48127fde7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x138", + "0x482480017fff8000", + "0x137", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007fe2", + "0x0", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280067ff97fff", + "0x10780017fff7fff", + "0x11", + "0x4824800180007fe2", + "0x0", + "0x400280067ff97fff", + "0x40780017fff7fff", + "0x1", + "0x482680017ff98000", + "0x7", + "0x482480017ffd8000", + "0x119e", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x7", + "0x482480017fdf8000", + "0xc8a", + "0x10780017fff7fff", + "0x37", + "0x482680017ff98000", + "0x6", + "0x482480017fe88000", + "0x111c", + "0x10780017fff7fff", + "0x12", + "0x482680017ff98000", + "0x5", + "0x482480017fec8000", + "0x1356", + "0x10780017fff7fff", + "0xc", + "0x482680017ff98000", + "0x4", + "0x482480017fef8000", + "0x152c", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x4", + "0x482480017ff08000", + "0x1658", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x1", + "0x482480017ffa8000", + "0x1c3e", + "0x1104800180018000", + "0xe8", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0xe3", + "0x482680017ff98000", + "0x1", + "0x48127ff57fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x1", + "0x482680017ffa8000", + "0x1e96", + "0x1104800180018000", + "0xc5", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0xa3", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x8d", + "0x480280007ffc8000", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffc", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480280017ff97fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480280027ff97fff", + "0x400280037ff97ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0x73", + "0x402780017fff7fff", + "0x1", + "0x400280017ff97ffc", + "0x482480017ffc8000", + "0xffffffffffffffffffffffff00000000", + "0x400280027ff97fff", + "0x480680017fff8000", + "0x0", + "0x48307ffb80007ffc", + "0x48307ff97ffe8000", + "0xa0680017fff8000", + "0x8", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400280037ff97fff", + "0x10780017fff7fff", + "0x5b", + "0x48307ffe80007ffd", + "0x400280037ff97fff", + "0x48307ff780007ff8", + "0x48307ff580017fff", + "0xa0680017fff7fff", + "0x7", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280047ff97fff", + "0x10780017fff7fff", + "0x4a", + "0x400280047ff97fff", + "0x48307ff480007ff5", + "0x48307ffe7ff28000", + "0xa0680017fff8000", + "0x8", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400280057ff97fff", + "0x10780017fff7fff", + "0x39", + "0x48307ffe80007ffd", + "0x400280057ff97fff", + "0x48307fef7ff08000", + "0x48307ffc7fef8000", + "0x48307ffe80007fff", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xd", + "0x1104800180018000", + "0x62", + "0x482680017ff98000", + "0x6", + "0x48127fe17fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x77", + "0x482480017fff8000", + "0x76", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007fe5", + "0x0", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280067ff97fff", + "0x10780017fff7fff", + "0x11", + "0x4824800180007fe5", + "0x0", + "0x400280067ff97fff", + "0x40780017fff7fff", + "0x1", + "0x482680017ff98000", + "0x7", + "0x482480017ffd8000", + "0x132e", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x7", + "0x482480017fe28000", + "0xe1a", + "0x10780017fff7fff", + "0x2c", + "0x482680017ff98000", + "0x6", + "0x482480017feb8000", + "0x12ac", + "0x10780017fff7fff", + "0x12", + "0x482680017ff98000", + "0x5", + "0x482480017fef8000", + "0x14e6", + "0x10780017fff7fff", + "0xc", + "0x482680017ff98000", + "0x4", + "0x482480017ff28000", + "0x16bc", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x4", + "0x482480017ff38000", + "0x17e8", + "0x10780017fff7fff", + "0x6", + "0x482680017ff98000", + "0x1", + "0x482480017ffd8000", + "0x1dce", + "0x1104800180018000", + "0x2c", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x1", + "0x482680017ffa8000", + "0x1e96", + "0x1104800180018000", + "0xf", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x1104800180018000", + "0x17", + "0x208b7fff7fff7ffe", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x1104800180018000", + "0x12", + "0x208b7fff7fff7ffe", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x1104800180018000", + "0xd", + "0x208b7fff7fff7ffe", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x1104800180018000", + "0x8", + "0x208b7fff7fff7ffe", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x1104800180018000", + "0x3", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x400180007fff7ffd", + "0x48127fff7fff8000", + "0x482480017ffe8000", + "0x1", + "0x208b7fff7fff7ffe" + ], + "bytecode_segment_lengths": [ + 79, + 224, + 75, + 79, + 182, + 201, + 182, + 5, + 5, + 5, + 5, + 5, + 7 + ], + "hints": [ + [ + 0, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 31, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 43, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 79, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 114, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -3 + }, + "b": { + "Immediate": "0x0" + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 118, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "scalar": { + "Immediate": "0x8000000000000110000000000000000" + }, + "max_x": { + "Immediate": "0xfffffffffffffffffffffffffffffffe" + }, + "x": { + "register": "AP", + "offset": 0 + }, + "y": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 140, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 152, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 162, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 195, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -32 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 207, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 303, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 334, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 346, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 378, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 409, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 421, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 457, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 476, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -3 + }, + "b": { + "Immediate": "0x0" + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 480, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "scalar": { + "Immediate": "0x8000000000000110000000000000000" + }, + "max_x": { + "Immediate": "0xfffffffffffffffffffffffffffffffe" + }, + "x": { + "register": "AP", + "offset": 0 + }, + "y": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 502, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 514, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 524, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 557, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -26 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 569, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 639, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 666, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -3 + }, + "b": { + "Immediate": "0x0" + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 670, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "scalar": { + "Immediate": "0x8000000000000110000000000000000" + }, + "max_x": { + "Immediate": "0xfffffffffffffffffffffffffffffffe" + }, + "x": { + "register": "AP", + "offset": 0 + }, + "y": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 692, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 704, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 714, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 747, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -29 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 759, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 840, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 859, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -3 + }, + "b": { + "Immediate": "0x0" + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 863, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "scalar": { + "Immediate": "0x8000000000000110000000000000000" + }, + "max_x": { + "Immediate": "0xfffffffffffffffffffffffffffffffe" + }, + "x": { + "register": "AP", + "offset": 0 + }, + "y": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 885, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 897, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 907, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 940, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x0" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -26 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 952, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 1047, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ] + ], + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0xd3748737d66b52a90ed3c1798b3f51d9a9266e607fdbc86e44f659bb173acd", + "offset": 378, + "builtins": [ + "range_check" + ] + }, + { + "selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "offset": 303, + "builtins": [ + "range_check" + ] + }, + { + "selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "offset": 0, + "builtins": [ + "range_check" + ] + }, + { + "selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "offset": 79, + "builtins": [ + "range_check" + ] + }, + { + "selector": "0x3ee3b73373acd583a130924aad6dc38cfdc44ba0555ba94ce2ff63980ea0632", + "offset": 457, + "builtins": [ + "range_check" + ] + } + ], + "L1_HANDLER": [ + { + "selector": "0xc10b615ab0621b7ae6a538821d80b200471946eb24ab7e4663f81aead3a0f", + "offset": 639, + "builtins": [ + "range_check" + ] + } + ], + "CONSTRUCTOR": [ + { + "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "offset": 840, + "builtins": [ + "range_check" + ] + } + ] + } +} \ No newline at end of file diff --git a/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.sierra.json b/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.sierra.json new file mode 100644 index 00000000000..18422499f37 --- /dev/null +++ b/crates/starknet_os_flow_tests/resources/deployable_for_resource_measurement.sierra.json @@ -0,0 +1,551 @@ +{ + "sierra_program": [ + "0x1", + "0x8", + "0x0", + "0x2", + "0x11", + "0x0", + "0xca", + "0x36", + "0x16", + "0x52616e6765436865636b", + "0x800000000000000100000000000000000000000000000000", + "0x537472756374", + "0x800000000000000f00000000000000000000000000000001", + "0x0", + "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", + "0x436f6e7374", + "0x800000000000000000000000000000000000000000000002", + "0x1", + "0x13", + "0x2", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x4f7574206f6620676173", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x9", + "0x753332", + "0x800000000000000700000000000000000000000000000000", + "0x4172726179", + "0x800000000000000300000000000000000000000000000001", + "0x536e617073686f74", + "0x800000000000000700000000000000000000000000000001", + "0xa", + "0x800000000000000700000000000000000000000000000002", + "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", + "0xb", + "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", + "0xc", + "0x56414c4944", + "0x4275696c74696e436f737473", + "0x53797374656d", + "0x800000000000000300000000000000000000000000000003", + "0x456e756d", + "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", + "0xd", + "0x11", + "0x66656c74323532", + "0x426f78", + "0x4761734275696c74696e", + "0x38", + "0x7265766f6b655f61705f747261636b696e67", + "0x77697468647261775f676173", + "0x6272616e63685f616c69676e", + "0x7374727563745f6465636f6e737472756374", + "0x61727261795f736e617073686f745f706f705f66726f6e74", + "0x64726f70", + "0x14", + "0x66756e6374696f6e5f63616c6c", + "0x3", + "0x7", + "0x656e756d5f696e6974", + "0x12", + "0x73746f72655f74656d70", + "0x15", + "0x10", + "0x6765745f6275696c74696e5f636f737473", + "0xf", + "0x77697468647261775f6761735f616c6c", + "0x72656465706f7369745f676173", + "0x636f6e73745f61735f696d6d656469617465", + "0xe", + "0x61727261795f6e6577", + "0x61727261795f617070656e64", + "0x736e617073686f745f74616b65", + "0x7374727563745f636f6e737472756374", + "0x6a756d70", + "0x8", + "0x756e626f78", + "0x72656e616d65", + "0x7533325f7472795f66726f6d5f66656c74323532", + "0x647570", + "0x61727261795f736c696365", + "0x61727261795f6c656e", + "0x7533325f6f766572666c6f77696e675f737562", + "0x6", + "0x5", + "0x4", + "0x2a8", + "0xffffffffffffffff", + "0x29", + "0x24", + "0x17", + "0x18", + "0x19", + "0x1a", + "0x1b", + "0x1c", + "0x1d", + "0x1e", + "0x2e", + "0x1f", + "0x20", + "0x21", + "0xb8", + "0xaf", + "0xa6", + "0x9a", + "0x92", + "0x22", + "0x23", + "0x25", + "0x8b", + "0x26", + "0x27", + "0x83", + "0x7e", + "0x28", + "0x64", + "0x2a", + "0x2b", + "0x2c", + "0x2d", + "0x79", + "0x2f", + "0x30", + "0x31", + "0x32", + "0x33", + "0x34", + "0x35", + "0x36", + "0x37", + "0x39", + "0x3a", + "0x3b", + "0x3c", + "0xbd", + "0x3d", + "0x3e", + "0x3f", + "0x97", + "0x40", + "0x41", + "0x42", + "0x43", + "0x44", + "0x9f", + "0x45", + "0x46", + "0x47", + "0x48", + "0x49", + "0x4a", + "0x4b", + "0x4c", + "0x4d", + "0x4e", + "0xea", + "0xd3", + "0xe5", + "0xef", + "0x11f", + "0x105", + "0x11a", + "0x124", + "0x191", + "0x185", + "0x17d", + "0x176", + "0x16e", + "0x169", + "0x152", + "0x164", + "0x196", + "0x182", + "0x18a", + "0x210", + "0x207", + "0x1fb", + "0x1f3", + "0x1ec", + "0x1e4", + "0x1df", + "0x1c8", + "0x1da", + "0x215", + "0x1f8", + "0x200", + "0x282", + "0x276", + "0x26e", + "0x267", + "0x25f", + "0x25a", + "0x243", + "0x255", + "0x287", + "0x273", + "0x27b", + "0xc4", + "0xf6", + "0x12b", + "0x19d", + "0x21c", + "0x28e", + "0x292", + "0x296", + "0x29a", + "0x29e", + "0x2a2", + "0x165c", + "0xf0b0a0908070e0b0a0908070d0b0a0908070c0b0a09080706050403020100", + "0x51903180917160a0915141312050b11090807050b0a090807100b0a090807", + "0x23052122180909091c0521030220131f1e0b0a0908071d091c0519031b091a", + "0x1b09092f0a09092e1d09092d052c052b052a2902280a091727132625092409", + "0x3935090936380909363709093605090936090b35090b34333209313009092f", + "0x92f180909410a0909400a0909360a09093f3e09093d053c053b3a09093605", + "0x451b090936443209311d09092f0543050b35090b34240909421d0909421809", + "0x94a0a09094911090936110909481b0909484409093d05470a0909460a0909", + "0x9093d1b320931183209311132093137090946050909461109092f054b0a09", + "0x942090909420b09093d3209093d4e09093d4d09093d1d3209314c09093d33", + "0x9050b05334c0b514d4e0b500b09050b09050550090505054f250909362509", + "0x94d05055009050b051b093a18110b500b44094e0544095009320932050550", + "0x94e091105240950091d0944051d09500905330505500918094c0505500911", + "0x4d4e4e092409500924091d050b0950090b091b054d0950094d0918054e0950", + "0x53e0950093e093e053e0950090524050550091b094d05055009050b05240b", + "0x525050a09500938093805055009050b0535250b52383a0b500b3e4d4e323a", + "0x937050009500930370b30053009500930090a053709500905350530095009", + "0x5505560950095509540555095009540953050550095309000554530b500900", + "0x50b0950090b091b050a0950090a0918053a0950093a091105570950095609", + "0x250911055809500935093805055009050b05570b0a3a4e095709500957091d", + "0x5500932095705055009050b05055b090556055a0950095809180559095009", + "0x5d0950090558055a0950095c091805590950094c0911055c09500933093805", + "0x950090b091b055a0950095a09180559095009590911055e0950095d094405", + "0x4d4e0b500b09050b09050550090505055e0b5a594e095e0950095e091d050b", + "0x51b096018110b500b44094e054409500932093205055009050b05334c0b5f", + "0x961241d0b500b11094e05110950091109590505500918094c05055009050b", + "0x383a0b500b1d094e051d0950091d09590505500924094c05055009050b053e", + "0x50090a090a050a09500935095c053509500938095a05055009050b05250962", + "0x5e05055009050b0500096337300b500b0a4e0b5d053a0950093a0959050a09", + "0x530950095309520555370b500937096505543a0b50093a0964055309500905", + "0x9640505500957094d05055009050b0558096757560b500b555354304e6605", + "0x5a0950095a0952055c370b5009370965055a09500959096805593a0b50093a", + "0xb500b5e373a5d4e6605055009050b0565640b6a5e5d0b500b5c5a56326905", + "0x51096d6c690b500b66094e056609500966095905055009050b0568096b6652", + "0x6e0944056e0950090533050550096c094c0505500969094d05055009050b05", + "0x91d050b0950090b091b054d0950094d09180552095009520911056f095009", + "0x7009500905240505500951094d05055009050b056f0b4d524e096f0950096f", + "0x3805055009050b0574730b725b710b500b704d52323a057009500970093e05", + "0xb30057609500976090a057709500905350576095009052505750950095b09", + "0x57b0950097a095305055009790900057a790b500978093705780950097677", + "0x750950097509180571095009710911057c09500929095505290950097b0954", + "0x93805055009050b057c0b75714e097c0950097c091d050b0950090b091b05", + "0x9050b050580090556057f0950097d0918057e095009730911057d09500974", + "0x840905560583095009810918058209500968091105810950094d0938050550", + "0x9380505500937096c050550093a094d0505500965096c05055009050b0505", + "0x9050b0505840905560583095009850918058209500964091105850950094d", + "0x9500958091105860950094d09380505500937096c050550093a094d050550", + "0x938050550093a094d05055009050b05058409055605830950098609180582", + "0x6e05880950098209510583095009870918058209500900091105870950094d", + "0x50094d09380505500925094d05055009050b05058a09055605890950098309", + "0x50098c0944058c095009056f05890950098b091805880950094e0911058b09", + "0x98d091d050b0950090b091b05890950098909180588095009880911058d09", + "0x44058e0950090570050550093e094d05055009050b058d0b89884e098d0950", + "0x50b0950090b091b054d0950094d0918054e0950094e0911058f0950098e09", + "0x50090571050550091b094d05055009050b058f0b4d4e4e098f0950098f091d", + "0x90b091b054d0950094d0918054e0950094e09110591095009900944059009", + "0x505500932095705055009050b05910b4d4e4e099109500991091d050b0950", + "0x5930950090558057f095009920918057e0950094c09110592095009330938", + "0xb0950090b091b057f0950097f0918057e0950097e09110594095009930944", + "0x954d4e0b500b09050b0905055009050505940b7f7e4e099409500994091d05", + "0xb051b099618110b500b44094e054409500932093205055009050b05334c0b", + "0x50091d0944051d09500905330505500918094c0505500911094d0505500905", + "0x924091d050b0950090b091b054d0950094d0918054e0950094e0911052409", + "0x3e053e0950090524050550091b094d05055009050b05240b4d4e4e09240950", + "0x38093805055009050b0535250b97383a0b500b3e4d4e323a053e0950093e09", + "0x953050550093709000500370b500930093705300950090535050a095009", + "0x918053a0950093a0911055509500954095505540950095309540553095009", + "0x9050b05550b0a3a4e095509500955091d050b0950090b091b050a0950090a", + "0x98090556055809500956091805570950092509110556095009350938050550", + "0x5570950094c091105590950093309380505500932095705055009050b0505", + "0x557095009570911055c0950095a0944055a09500905580558095009590918", + "0x5055c0b58574e095c0950095c091d050b0950090b091b0558095009580918", + "0x9500932093205055009050b05334c0b994d4e0b500b09050b090505500905", + "0x918094c0505500911094d05055009050b051b099a18110b500b44094e0544", + "0x50094d0918054e0950094e091105240950091d0944051d0950090533050550", + "0x5055009050b05240b4d4e4e092409500924091d050b0950090b091b054d09", + "0x3a0b500b3e4d4e323a053e0950093e093e053e0950090524050550091b094d", + "0x500905350530095009055b050a09500938093805055009050b0535250b9b38", + "0x9000554530b5009000937050009500930370b30053009500930090a053709", + "0x9110557095009560955055609500955095405550950095409530505500953", + "0x4e095709500957091d050b0950090b091b050a0950090a0918053a0950093a", + "0x95809180559095009250911055809500935093805055009050b05570b0a3a", + "0x55c0950093309380505500932095705055009050b05059c090556055a0950", + "0x55e0950095d0944055d0950090558055a0950095c091805590950094c0911", + "0x5e0950095e091d050b0950090b091b055a0950095a09180559095009590911", + "0x5009050b05334c0b9d4d4e0b500b09050b09050550090505055e0b5a594e09", + "0x18095a05055009050b051b099e18110b500b44094e05440950093209320505", + "0xb5d0511095009110959052409500924090a05240950091d095c051d095009", + "0x110b50091109640525095009055e05055009050b0538099f3a3e0b500b244e", + "0xa037300b500b0a25353e4e660525095009250952050a3a0b50093a09650535", + "0x950095309680553110b50091109640505500937094d05055009050b050009", + "0xba157560b500b5554303269055409500954095205553a0b50093a09650554", + "0x5905055009050b055d09a25c5a0b500b573a11564e6605055009050b055958", + "0x550095e094d05055009050b056509a3645e0b500b5c094e055c0950095c09", + "0x55a0950095a09110566095009520944055209500905330505500964094c05", + "0xb05660b4d5a4e096609500966091d050b0950090b091b054d0950094d0918", + "0x4d5a323a056809500968093e056809500905240505500965094d0505500905", + "0x700950090535056f0950096c093805055009050b056e510ba46c690b500b68", + "0x9500973095405730950095b095305055009710900055b710b500970093705", + "0x50090b091b056f0950096f0918056909500969091105750950097409550574", + "0x5760950096e093805055009050b05750b6f694e097509500975091d050b09", + "0x4d093805055009050b0505a509055605780950097609180577095009510911", + "0x5009050b0505a6090556057b095009790918057a0950095d09110579095009", + "0x5290950094d0938050550093a096c0505500911094d0505500959096c0505", + "0x11094d05055009050b0505a6090556057b095009290918057a095009580911", + "0x97c0918057a095009000911057c0950094d0938050550093a096c05055009", + "0x57d0950094d09380505500911094d05055009050b0505a6090556057b0950", + "0x7f0950097b096e057e0950097a0951057b0950097d0918057a095009380911", + "0x4e091105810950094d0938050550091b094d05055009050b0505a709055605", + "0x7e0911058309500982094405820950090571057f095009810918057e095009", + "0x7e4e098309500983091d050b0950090b091b057f0950097f0918057e095009", + "0x950094c091105850950093309380505500932095705055009050b05830b7f", + "0x9500977091105870950098609440586095009055805780950098509180577", + "0x870b78774e098709500987091d050b0950090b091b05780950097809180577", + "0x932093205055009050b05334c0ba84d4e0b500b09050b0905055009050505", + "0x9590505500918094c05055009050b051b09a918110b500b44094e05440950", + "0x3a09500924095a05055009050b053e09aa241d0b500b11094e051109500911", + "0x500b384e0b5d051d0950091d0959053809500938090a05380950093a095c05", + "0x96505371d0b50091d09640530095009055e05055009050b050a09ab35250b", + "0xb055509ac54530b500b003037254e6605300950093009520500350b500935", + "0x965055709500956096805561d0b50091d09640505500954094d0505500905", + "0xb055d5c0bad5a590b500b585753326905570950095709520558350b500935", + "0x500964095905055009050b056509ae645e0b500b5a351d594e660505500905", + "0x66094c0505500952094d05055009050b056809af66520b500b64094e056409", + "0x94d0918055e0950095e0911056c0950096909440569095009053305055009", + "0x55009050b056c0b4d5e4e096c0950096c091d050b0950090b091b054d0950", + "0xb500b514d5e323a055109500951093e055109500905240505500968094d05", + "0x73093705730950090535055b0950096f093805055009050b0571700bb06f6e", + "0x95505770950097609540576095009750953050550097409000575740b5009", + "0x1d050b0950090b091b055b0950095b0918056e0950096e0911057809500977", + "0x9700911057909500971093805055009050b05780b5b6e4e09780950097809", + "0x290950094d093805055009050b0505b1090556057b095009790918057a0950", + "0x96c05055009050b0505b2090556057d095009290918057c09500965091105", + "0x95c0911057e0950094d09380505500935096c050550091d094d050550095d", + "0x50550091d094d05055009050b0505b2090556057d0950097e0918057c0950", + "0x57d0950097f0918057c095009550911057f0950094d09380505500935096c", + "0x90a091105810950094d0938050550091d094d05055009050b0505b2090556", + "0x9055605830950097d096e05820950097c0951057d095009810918057c0950", + "0x820950094e091105850950094d0938050550093e094d05055009050b0505b3", + "0x82095009820911058709500986094405860950090570058309500985091805", + "0x5870b83824e098709500987091d050b0950090b091b058309500983091805", + "0x4e0911058909500988094405880950090571050550091b094d05055009050b", + "0x4e4e098909500989091d050b0950090b091b054d0950094d0918054e095009", + "0x950094c0911058b0950093309380505500932095705055009050b05890b4d", + "0x950097a0911058d0950098c0944058c0950090558057b0950098b0918057a", + "0x8d0b7b7a4e098d0950098d091d050b0950090b091b057b0950097b0918057a", + "0x932093205055009050b05334c0bb44d4e0b500b09050b0905055009050505", + "0x5c051d09500918095a05055009050b051b09b518110b500b44094e05440950", + "0x3e0b500b244e0b5d0511095009110959052409500924090a05240950091d09", + "0x93a09650535110b50091109640525095009055e05055009050b053809b63a", + "0x9050b050009b737300b500b0a25353e4e660525095009250952050a3a0b50", + "0x93a096505540950095309680553110b50091109640505500937094d050550", + "0x9050b0559580bb857560b500b5554303269055409500954095205553a0b50", + "0x5c0950095c095905055009050b055d09b95c5a0b500b573a11564e66050550", + "0x500964094c050550095e094d05055009050b056509ba645e0b500b5c094e05", + "0x950094d0918055a0950095a09110566095009520944055209500905330505", + "0x4d05055009050b05660b4d5a4e096609500966091d050b0950090b091b054d", + "0x6c690b500b684d5a323a056809500968093e05680950090524050550096509", + "0x500970093705700950090535056f0950096c093805055009050b056e510bbb", + "0x9740955057409500973095405730950095b095305055009710900055b710b", + "0x75091d050b0950090b091b056f0950096f0918056909500969091105750950", + "0x9500951091105760950096e093805055009050b05750b6f694e0975095009", + "0x1105790950094d093805055009050b0505bc09055605780950097609180577", + "0x959096c05055009050b0505bd090556057b095009790918057a0950095d09", + "0x9500958091105290950094d0938050550093a096c0505500911094d050550", + "0x96c0505500911094d05055009050b0505bd090556057b095009290918057a", + "0x556057b0950097c0918057a095009000911057c0950094d0938050550093a", + "0x95009380911057d0950094d09380505500911094d05055009050b0505bd09", + "0x5be090556057f0950097b096e057e0950097a0951057b0950097d0918057a", + "0x18057e0950094e091105810950094d0938050550091b094d05055009050b05", + "0x18057e0950097e0911058309500982094405820950090571057f0950098109", + "0x50b05830b7f7e4e098309500983091d050b0950090b091b057f0950097f09", + "0x985091805770950094c091105850950093309380505500932095705055009", + "0x9780918057709500977091105870950098609440586095009055805780950", + "0x95009057305870b78774e098709500987091d050b0950090b091b05780950", + "0x5090a050509500905750509090909095009050974050509500905090a0505", + "0x50509500905090a0505095009057605090909090950090509740505095009", + "0x5009050974050509500905090a050509500905770509090909095009050974", + "0x9090909095009050974050509500905090a05050950090578050909090909", + "0x950090b320b7a05320950090579050b09500905090b300509095009053505", + "0x37054e05320b0905353837054e1d3837054e244e09094e0950094e097b054e", + "0x3837054ebf320b0905353837054e1d3837054e79320b0905353837054e1d38", + "0x1d3837054ec1320b0905353837054e1d3837054ec0320b0905353837054e1d", + "0x905c4250905c3320b0905353837054e1d3837054ec2320b0905353837054e", + "0xc90525090a09c8250905c7250905c6250905c525" + ], + "sierra_program_debug_info": { + "type_names": [], + "libfunc_names": [], + "user_func_names": [] + }, + "contract_class_version": "0.1.0", + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0xd3748737d66b52a90ed3c1798b3f51d9a9266e607fdbc86e44f659bb173acd", + "function_idx": 3 + }, + { + "selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "function_idx": 2 + }, + { + "selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "function_idx": 0 + }, + { + "selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "function_idx": 1 + }, + { + "selector": "0x3ee3b73373acd583a130924aad6dc38cfdc44ba0555ba94ce2ff63980ea0632", + "function_idx": 4 + } + ], + "L1_HANDLER": [ + { + "selector": "0xc10b615ab0621b7ae6a538821d80b200471946eb24ab7e4663f81aead3a0f", + "function_idx": 5 + } + ], + "CONSTRUCTOR": [ + { + "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "function_idx": 6 + } + ] + }, + "abi": [ + { + "type": "function", + "name": "__validate__", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "function", + "name": "__validate_deploy__", + "inputs": [ + { + "name": "class_hash", + "type": "core::felt252" + }, + { + "name": "contract_address_salt", + "type": "core::felt252" + }, + { + "name": "some_args", + "type": "core::array::Span::" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "__execute__", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "constructor", + "name": "constructor", + "inputs": [ + { + "name": "some_args", + "type": "core::array::Span::" + } + ] + }, + { + "type": "function", + "name": "get_salt", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "external", + "inputs": [ + { + "name": "some_args", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "l1_handler", + "name": "l1_handler", + "inputs": [ + { + "name": "from_address", + "type": "core::felt252" + }, + { + "name": "some_args", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "event", + "name": "deployable_for_resource_measurement::deployable_for_resource_measurement::DeployableForResourceMeasurement::Event", + "kind": "enum", + "variants": [] + } + ] +} \ No newline at end of file diff --git a/crates/starknet_os_flow_tests/src/special_contracts.rs b/crates/starknet_os_flow_tests/src/special_contracts.rs index 4745da548c1..c1128c8f832 100644 --- a/crates/starknet_os_flow_tests/src/special_contracts.rs +++ b/crates/starknet_os_flow_tests/src/special_contracts.rs @@ -1,6 +1,7 @@ use std::sync::LazyLock; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; +use cairo_lang_starknet_classes::contract_class::ContractClass as CompilerContractClass; use starknet_api::deprecated_contract_class::ContractClass as DeprecatedContractClass; use starknet_api::state::SierraContractClass; @@ -11,7 +12,7 @@ pub(crate) static V1_BOUND_CAIRO0_CONTRACT: LazyLock = pub(crate) static V1_BOUND_CAIRO1_CONTRACT_SIERRA: LazyLock = LazyLock::new(|| { - let compiler_contract_class: cairo_lang_starknet_classes::contract_class::ContractClass = + let compiler_contract_class: CompilerContractClass = serde_json::from_str(include_str!("../resources/v1_bound_cairo1_account.sierra.json")) .unwrap(); SierraContractClass::from(compiler_contract_class) @@ -25,7 +26,7 @@ pub(crate) static V1_BOUND_CAIRO1_CONTRACT_CASM: LazyLock = pub(crate) static DATA_GAS_ACCOUNT_CONTRACT_SIERRA: LazyLock = LazyLock::new(|| { - let compiler_contract_class: cairo_lang_starknet_classes::contract_class::ContractClass = + let compiler_contract_class: CompilerContractClass = serde_json::from_str(include_str!("../resources/data_gas_account.sierra.json")) .unwrap(); SierraContractClass::from(compiler_contract_class) @@ -35,3 +36,23 @@ pub(crate) static DATA_GAS_ACCOUNT_CONTRACT_CASM: LazyLock = LazyLock::new(|| { serde_json::from_str(include_str!("../resources/data_gas_account.casm.json")).unwrap() }); + +#[expect(dead_code)] +pub(crate) static DEPLOYABLE_FOR_RESOURCE_MEASUREMENT_CONTRACT_SIERRA: LazyLock< + SierraContractClass, +> = LazyLock::new(|| { + let compiler_contract_class: CompilerContractClass = serde_json::from_str(include_str!( + "../resources/deployable_for_resource_measurement.sierra.json" + )) + .unwrap(); + SierraContractClass::from(compiler_contract_class) +}); + +#[expect(dead_code)] +pub(crate) static DEPLOYABLE_FOR_RESOURCE_MEASUREMENT_CONTRACT_CASM: LazyLock = + LazyLock::new(|| { + serde_json::from_str(include_str!( + "../resources/deployable_for_resource_measurement.casm.json" + )) + .unwrap() + }); diff --git a/crates/starknet_os_flow_tests/src/test_manager.rs b/crates/starknet_os_flow_tests/src/test_manager.rs index 29f32cf207c..11b435a8f34 100644 --- a/crates/starknet_os_flow_tests/src/test_manager.rs +++ b/crates/starknet_os_flow_tests/src/test_manager.rs @@ -19,6 +19,7 @@ use blockifier::transaction::objects::{ use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction; use blockifier_test_utils::calldata::create_calldata; use blockifier_test_utils::contracts::FeatureContract; +use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use cairo_vm::types::builtin_name::BuiltinName; use itertools::Itertools; use starknet_api::abi::abi_utils::{get_fee_token_var_address, selector_from_name}; @@ -29,7 +30,7 @@ use starknet_api::block_hash::block_hash_calculator::{ PartialBlockHashComponents, }; use starknet_api::contract_class::compiled_class_hash::{HashVersion, HashableCompiledClass}; -use starknet_api::contract_class::ContractClass; +use starknet_api::contract_class::{ClassInfo, ContractClass}; use starknet_api::core::{ ChainId, ClassHash, @@ -48,13 +49,14 @@ use starknet_api::executable_transaction::{ Transaction as ExecutableTransaction, }; use starknet_api::hash::StateRoots; -use starknet_api::invoke_tx_args; use starknet_api::state::{SierraContractClass, StorageKey}; +use starknet_api::test_utils::declare::{declare_tx, DeclareTxArgs}; use starknet_api::test_utils::invoke::{invoke_tx, InvokeTxArgs}; use starknet_api::test_utils::{NonceManager, CHAIN_ID_FOR_TESTS, TEST_SEQUENCER_ADDRESS}; use starknet_api::transaction::constants::TRANSFER_EVENT_NAME; use starknet_api::transaction::fields::{snos_block_number_from_proof_facts, Calldata, Fee, Tip}; use starknet_api::transaction::{Event, L1HandlerTransaction, L1ToL2Payload, MessageToL1}; +use starknet_api::{declare_tx_args, invoke_tx_args}; use starknet_committer::block_committer::input::{ IsSubset, StarknetStorageKey, @@ -571,6 +573,29 @@ impl TestBuilder { self.execution_contracts.executed.contracts.insert(compiled_class_hash, casm.clone()); } + /// Given sierra and CASM, add an explicit declare transaction. + pub(crate) fn add_explicit_cairo1_declare_tx( + &mut self, + sierra: &SierraContractClass, + casm: CasmContractClass, + extra_args: DeclareTxArgs, + chain_id: &ChainId, + ) { + let class_hash = sierra.calculate_class_hash(); + let compiled_class_hash = casm.hash(&HashVersion::V2); + let declare_args = declare_tx_args! { class_hash, compiled_class_hash, ..extra_args }; + let account_declare_tx = declare_tx(declare_args); + let sierra_version = sierra.get_sierra_version().unwrap(); + let class_info = ClassInfo { + contract_class: ContractClass::V1((casm, sierra_version.clone())), + sierra_program_length: sierra.sierra_program.len(), + abi_length: sierra.abi.len(), + sierra_version, + }; + let tx = DeclareTransaction::create(account_declare_tx, class_info, chain_id).unwrap(); + self.add_cairo1_declare_tx(tx, sierra); + } + pub(crate) fn add_invoke_tx( &mut self, tx: InvokeTransaction, diff --git a/crates/starknet_os_flow_tests/src/tests.rs b/crates/starknet_os_flow_tests/src/tests.rs index ff163d7dd4d..98ad0f384dc 100644 --- a/crates/starknet_os_flow_tests/src/tests.rs +++ b/crates/starknet_os_flow_tests/src/tests.rs @@ -17,7 +17,7 @@ use expect_test::expect; use rstest::rstest; use starknet_api::abi::abi_utils::{get_storage_var_address, selector_from_name}; use starknet_api::block::{BlockInfo, BlockNumber, BlockTimestamp, GasPrice}; -use starknet_api::contract_class::compiled_class_hash::{HashVersion, HashableCompiledClass}; +use starknet_api::contract_class::compiled_class_hash::HashVersion; use starknet_api::contract_class::{ClassInfo, ContractClass, SierraVersion}; use starknet_api::core::{ calculate_contract_address, @@ -1023,7 +1023,6 @@ async fn test_v1_bound_accounts_cairo1() { let test_contract_sierra = &V1_BOUND_CAIRO1_CONTRACT_SIERRA; let test_contract_casm = &V1_BOUND_CAIRO1_CONTRACT_CASM; let class_hash = test_contract_sierra.calculate_class_hash(); - let compiled_class_hash = test_contract_casm.hash(&HashVersion::V2); let vc = VersionedConstants::latest_constants(); let max_tip = vc.os_constants.v1_bound_accounts_max_tip; assert!(vc.os_constants.v1_bound_accounts_cairo1.contains(&class_hash)); @@ -1031,23 +1030,17 @@ async fn test_v1_bound_accounts_cairo1() { let chain_id = &test_builder.chain_id(); // Declare the V1-bound account. - let declare_args = declare_tx_args! { + let extra_declare_args = declare_tx_args! { sender_address: *FUNDED_ACCOUNT_ADDRESS, nonce: test_builder.next_nonce(*FUNDED_ACCOUNT_ADDRESS), - class_hash, - compiled_class_hash, resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS, }; - let account_declare_tx = declare_tx(declare_args); - let sierra_version = test_contract_sierra.get_sierra_version().unwrap(); - let class_info = ClassInfo { - contract_class: ContractClass::V1(((**test_contract_casm).clone(), sierra_version.clone())), - sierra_program_length: test_contract_sierra.sierra_program.len(), - abi_length: test_contract_sierra.abi.len(), - sierra_version, - }; - let tx = DeclareTransaction::create(account_declare_tx, class_info, chain_id).unwrap(); - test_builder.add_cairo1_declare_tx(tx, test_contract_sierra); + test_builder.add_explicit_cairo1_declare_tx( + test_contract_sierra, + (**test_contract_casm).clone(), + extra_declare_args, + chain_id, + ); // Deploy it (from funded account). let private_key = Felt::ONE; @@ -2497,7 +2490,6 @@ async fn test_data_gas_accounts() { let test_contract_sierra = &DATA_GAS_ACCOUNT_CONTRACT_SIERRA; let test_contract_casm = &DATA_GAS_ACCOUNT_CONTRACT_CASM; let class_hash = test_contract_sierra.calculate_class_hash(); - let compiled_class_hash = test_contract_casm.hash(&HashVersion::V2); assert!( VersionedConstants::latest_constants().os_constants.data_gas_accounts.contains(&class_hash) ); @@ -2505,23 +2497,17 @@ async fn test_data_gas_accounts() { let chain_id = &test_builder.chain_id(); // Declare the data gas account. - let declare_args = declare_tx_args! { + let extra_declare_args = declare_tx_args! { sender_address: *FUNDED_ACCOUNT_ADDRESS, nonce: test_builder.next_nonce(*FUNDED_ACCOUNT_ADDRESS), - class_hash, - compiled_class_hash, resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS, }; - let account_declare_tx = declare_tx(declare_args); - let sierra_version = test_contract_sierra.get_sierra_version().unwrap(); - let class_info = ClassInfo { - contract_class: ContractClass::V1(((**test_contract_casm).clone(), sierra_version.clone())), - sierra_program_length: test_contract_sierra.sierra_program.len(), - abi_length: test_contract_sierra.abi.len(), - sierra_version, - }; - let tx = DeclareTransaction::create(account_declare_tx, class_info, chain_id).unwrap(); - test_builder.add_cairo1_declare_tx(tx, test_contract_sierra); + test_builder.add_explicit_cairo1_declare_tx( + test_contract_sierra, + (**test_contract_casm).clone(), + extra_declare_args, + chain_id, + ); // Deploy it (from funded account). let salt = ContractAddressSalt(Felt::ZERO); diff --git a/crates/starknet_patricia/Cargo.toml b/crates/starknet_patricia/Cargo.toml index 9997301faff..f15fae30946 100644 --- a/crates/starknet_patricia/Cargo.toml +++ b/crates/starknet_patricia/Cargo.toml @@ -11,10 +11,9 @@ workspace = true [features] deserialize = [] -testing = ["dep:num-bigint"] +testing = [] [dev-dependencies] -num-bigint = { workspace = true, features = ["rand"] } pretty_assertions.workspace = true rand.workspace = true rstest.workspace = true @@ -23,7 +22,6 @@ rstest.workspace = true async-recursion.workspace = true derive_more = { workspace = true, features = ["add", "display"] } ethnum.workspace = true -num-bigint = { workspace = true, optional = true } rand.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true diff --git a/crates/starknet_patricia/src/patricia_merkle_tree/external_test_utils.rs b/crates/starknet_patricia/src/patricia_merkle_tree/external_test_utils.rs index 6f68a732c6d..9c9e79e3f21 100644 --- a/crates/starknet_patricia/src/patricia_merkle_tree/external_test_utils.rs +++ b/crates/starknet_patricia/src/patricia_merkle_tree/external_test_utils.rs @@ -1,8 +1,7 @@ use std::collections::HashMap; use ethnum::U256; -use num_bigint::{BigUint, RandBigInt}; -use rand::Rng; +use rand::{Rng, RngExt}; use starknet_api::hash::HashOutput; use starknet_patricia_storage::db_object::{ DBObject, @@ -85,12 +84,21 @@ pub fn u256_try_into_felt(value: &U256) -> Result> { /// Panics if low >= high pub fn get_random_u256(rng: &mut R, low: U256, high: U256) -> U256 { assert!(low < high, "low must be less than or equal to high. actual: {low} > {high}"); - - let delta = BigUint::from_bytes_be(&(high - low).to_be_bytes()); - let rand = rng.gen_biguint_below(&(delta)).to_bytes_be(); - let mut padded_rand = [0u8; 32]; - padded_rand[32 - rand.len()..].copy_from_slice(&rand); - low + U256::from_be_bytes(padded_rand) + let delta = high - low; + + // Use rejection-sampling to generate a random U256 number less than delta. + // To keep expected number of rejections under 2, mask each sampled U256 to the bit length of + // delta. + let bit_len = 256 - delta.leading_zeros(); + let mask = if bit_len == 256 { U256::MAX } else { (U256::ONE << bit_len) - U256::ONE }; + let rand_u256 = loop { + let bytes: [u8; 32] = rng.random(); + let candidate = U256::from_be_bytes(bytes) & mask; + if candidate < delta { + break candidate; + } + }; + low + rand_u256 } pub struct AdditionHash; diff --git a/crates/starknet_patricia/src/patricia_merkle_tree/internal_test_utils.rs b/crates/starknet_patricia/src/patricia_merkle_tree/internal_test_utils.rs index 8b4aef9e6fc..0cda2a1e790 100644 --- a/crates/starknet_patricia/src/patricia_merkle_tree/internal_test_utils.rs +++ b/crates/starknet_patricia/src/patricia_merkle_tree/internal_test_utils.rs @@ -62,7 +62,7 @@ impl From<&str> for PathToBottom { #[fixture] pub(crate) fn random() -> ThreadRng { - rand::thread_rng() + rand::rng() } #[rstest] diff --git a/crates/starknet_patricia/src/patricia_merkle_tree/types_test.rs b/crates/starknet_patricia/src/patricia_merkle_tree/types_test.rs index ffacc3773e9..18ba3345fe6 100644 --- a/crates/starknet_patricia/src/patricia_merkle_tree/types_test.rs +++ b/crates/starknet_patricia/src/patricia_merkle_tree/types_test.rs @@ -1,6 +1,6 @@ use ethnum::{uint, U256}; use rand::rngs::ThreadRng; -use rand::Rng; +use rand::RngExt; use rstest::rstest; use starknet_types_core::felt::Felt; @@ -68,7 +68,7 @@ fn test_get_lca_big(mut random: ThreadRng) { let right_child = left_child + 1; let mut random_extension = |index: NodeIndex| { let extension_bits = index.leading_zeros(); - let extension: u128 = random.gen_range(0..(1 << extension_bits)); + let extension: u128 = random.random_range(0..(1 << extension_bits)); (index << extension_bits) + NodeIndex::new(U256::from(extension)) }; @@ -101,9 +101,9 @@ fn test_get_path_to_descendant( #[rstest] fn test_get_path_to_descendant_big() { - let root_index = NodeIndex::new(U256::from(rand::thread_rng().gen::())); + let root_index = NodeIndex::new(U256::from(rand::rng().random::())); let max_bits = NodeIndex::BITS - 128; - let extension: u128 = rand::thread_rng().gen_range(0..1 << max_bits); + let extension: u128 = rand::rng().random_range(0..1 << max_bits); let extension_index = NodeIndex::new(U256::from(extension)); let descendant = (root_index << extension_index.bit_length()) + extension_index; diff --git a/crates/starknet_transaction_prover/resources/rpc_records/test_execute_with_prefetch.json b/crates/starknet_transaction_prover/resources/rpc_records/test_execute_with_prefetch.json index ba9abe2c1c2..5593c5d7766 100644 --- a/crates/starknet_transaction_prover/resources/rpc_records/test_execute_with_prefetch.json +++ b/crates/starknet_transaction_prover/resources/rpc_records/test_execute_with_prefetch.json @@ -30,7 +30,7 @@ "parent_hash": "0x5172a5354ac1402a5070817c2cd922be776529a42db43519de5b9e64f470331", "receipt_commitment": "0x0", "sequencer_address": "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", - "starknet_version": "0.14.3", + "starknet_version": "0.14.4", "state_diff_commitment": "0xbbf3e6d4b17a34d5f754866feb02b08232f027edeb05b89de369fda230dbd0", "state_diff_length": 1, "status": "ACCEPTED_ON_L2", diff --git a/deployments/sequencer/src/constructs/deployment.py b/deployments/sequencer/src/constructs/deployment.py index 10475073380..848fac89287 100644 --- a/deployments/sequencer/src/constructs/deployment.py +++ b/deployments/sequencer/src/constructs/deployment.py @@ -29,7 +29,7 @@ def _create_deployment(self) -> k8s.KubeDeployment: self.monitoring_endpoint_port, ) - selector_labels = {"service": self.labels["service"]} + selector_labels = {"app": "sequencer", "service": self.labels["service"]} return k8s.KubeDeployment( self, diff --git a/deployments/sequencer/src/constructs/statefulset.py b/deployments/sequencer/src/constructs/statefulset.py index 1fdc9f0d87f..34237114914 100644 --- a/deployments/sequencer/src/constructs/statefulset.py +++ b/deployments/sequencer/src/constructs/statefulset.py @@ -69,7 +69,7 @@ def _create_statefulset(self) -> k8s.KubeStatefulSet: self.monitoring_endpoint_port, ) - selector_labels = {"service": statefulset_labels["service"]} + selector_labels = {"app": "sequencer", "service": statefulset_labels["service"]} return k8s.KubeStatefulSet( self, diff --git a/scripts/install_llvm19.sh b/scripts/install_llvm19.sh index b350564360b..f3a82bd1da4 100755 --- a/scripts/install_llvm19.sh +++ b/scripts/install_llvm19.sh @@ -7,25 +7,6 @@ set -e -# Pinned SHA-256 of https://apt.llvm.org/llvm.sh. Recorded 2026-05-14. -# -# Why pin: llvm.sh runs as root in our CI / Docker builds. TLS authenticates the -# server, but not the *content* — an apt.llvm.org compromise, hijacked DNS, or -# even an accidental upstream regression could quietly serve a different script. -# Pinning a SHA means we trust this specific reviewed version, not "whatever the -# URL serves today". -# -# If sha256sum -c fails (loud build break), one of two things happened: -# 1. apt.llvm.org legitimately updated llvm.sh. Read the new file, review the -# diff (compare against the previous pinned commit's version), confirm it's -# safe, then bump LLVM_SH_SHA256 below in a reviewed commit. This is the -# change-control event we want. -# 2. The upstream or network is compromised. Do NOT bump the SHA until the -# cause is investigated. -# -# Same supply-chain hygiene as Cargo.lock pinning crate hashes. -LLVM_SH_SHA256="14a4eda1349f23acf9dc0b564ed44b21bce3bd1703c78b5f7488870d7c6fe68f" - [[ ${UID} == "0" ]] || SUDO="sudo" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)" @@ -62,8 +43,6 @@ function install_llvm19() { trap 'rm -rf "$workdir"' RETURN echo "Downloading LLVM installation script..." curl --proto "=https" --tlsv1.2 --fail -L -o "$llvm_sh" https://apt.llvm.org/llvm.sh - echo "Verifying llvm.sh checksum..." - echo "${LLVM_SH_SHA256} ${llvm_sh}" | sha256sum -c - echo "Running LLVM 19 installation script..." $SUDO bash "$llvm_sh" 19 all echo "Installing LLVM-related packages (MLIR, Polly, etc.)..." diff --git a/scripts/parent_branch.txt b/scripts/parent_branch.txt index 50924bc7b4f..ba2906d0666 100644 --- a/scripts/parent_branch.txt +++ b/scripts/parent_branch.txt @@ -1 +1 @@ -main-v0.14.3 +main