diff --git a/crates/pathfinder/src/state.rs b/crates/pathfinder/src/state.rs index 20fb1e6089..fa4a2c26ec 100644 --- a/crates/pathfinder/src/state.rs +++ b/crates/pathfinder/src/state.rs @@ -1,4 +1,13 @@ pub mod block_hash; mod sync; -pub use sync::{l1, l2, revert, sync, update_starknet_state, Gossiper, SyncContext}; +pub use sync::{ + l1, + l2, + revert, + sync, + update_starknet_state, + Gossiper, + StarknetStateUpdate, + SyncContext, +}; diff --git a/crates/pathfinder/src/state/sync.rs b/crates/pathfinder/src/state/sync.rs index 0c753deb47..c6a7336494 100644 --- a/crates/pathfinder/src/state/sync.rs +++ b/crates/pathfinder/src/state/sync.rs @@ -4,12 +4,14 @@ pub mod l2; mod pending; pub mod revert; +use std::collections::HashMap; use std::future::Future; use std::sync::Arc; use std::time::{Duration, Instant}; use anyhow::Context; use pathfinder_common::prelude::*; +use pathfinder_common::state_update::{ContractUpdate, SystemContractUpdate}; use pathfinder_common::{ BlockCommitmentSignature, Chain, @@ -839,7 +841,11 @@ async fn l2_update( .context("Create database transaction")?; let (storage_commitment, class_commitment) = update_starknet_state( &transaction, - &state_update, + StarknetStateUpdate { + contract_updates: &state_update.contract_updates, + system_contract_updates: &state_update.system_contract_updates, + declared_sierra_classes: &state_update.declared_sierra_classes, + }, verify_tree_hashes, block.block_number, storage, @@ -1043,9 +1049,15 @@ async fn l2_reorg(connection: &mut Connection, reorg_tail: BlockNumber) -> anyho }) } +pub struct StarknetStateUpdate<'a> { + pub contract_updates: &'a HashMap, + pub system_contract_updates: &'a HashMap, + pub declared_sierra_classes: &'a HashMap, +} + pub fn update_starknet_state( transaction: &Transaction<'_>, - state_update: &StateUpdate, + state_update: StarknetStateUpdate<'_>, verify_hashes: bool, block: BlockNumber, // we need this so that we can create extra read-only transactions for @@ -1109,7 +1121,7 @@ pub fn update_starknet_state( .context("Inserting contract update result")?; } - for (contract, update) in &state_update.system_contract_updates { + for (contract, update) in state_update.system_contract_updates { let update_result = update_contract_state( *contract, &update.storage, @@ -1151,7 +1163,7 @@ pub fn update_starknet_state( } .with_verify_hashes(verify_hashes); - for (sierra, casm) in &state_update.declared_sierra_classes { + for (sierra, casm) in state_update.declared_sierra_classes { let leaf_hash = pathfinder_common::calculate_class_commitment_leaf_hash(*casm); transaction diff --git a/crates/pathfinder/src/sync/state_updates.rs b/crates/pathfinder/src/sync/state_updates.rs index 49f963ec17..7d23ac094b 100644 --- a/crates/pathfinder/src/sync/state_updates.rs +++ b/crates/pathfinder/src/sync/state_updates.rs @@ -21,7 +21,7 @@ use pathfinder_merkle_tree::StorageCommitmentTree; use pathfinder_storage::{Storage, TrieUpdate}; use tokio::task::spawn_blocking; -use crate::state::update_starknet_state; +use crate::state::{update_starknet_state, StarknetStateUpdate}; use crate::sync::error::{SyncError, SyncError2}; use crate::sync::stream::ProcessStage; @@ -151,44 +151,32 @@ impl ProcessStage for UpdateStarknetState { let tail = self.current_block; - let header = db - .block_header(tail.into()) - .context("Querying block header")? - .context("Block header not found")?; - let parent_state_commitment = match self.current_block.parent() { - Some(parent) => db - .state_commitment(parent.into()) - .context("Querying parent block header")? - .context("Parent block header not found")?, - None => StateCommitment::default(), - }; - let state_update = StateUpdate { - block_hash: header.hash, - parent_state_commitment, - state_commitment: header.state_commitment, - contract_updates: state_update.contract_updates, - system_contract_updates: state_update.system_contract_updates, - declared_cairo_classes: state_update.declared_cairo_classes, - declared_sierra_classes: state_update.declared_sierra_classes, - }; - let (storage_commitment, class_commitment) = update_starknet_state( &db, - &state_update, + StarknetStateUpdate { + contract_updates: &state_update.contract_updates, + system_contract_updates: &state_update.system_contract_updates, + declared_sierra_classes: &state_update.declared_sierra_classes, + }, self.verify_tree_hashes, - header.number, + self.current_block, self.storage.clone(), ) .context("Updating Starknet state")?; - let state_commitment = StateCommitment::calculate(storage_commitment, class_commitment); + // Ensure that roots match. - if state_commitment != header.state_commitment { + let state_commitment = StateCommitment::calculate(storage_commitment, class_commitment); + let expected_state_commitment = db + .state_commitment(self.current_block.into()) + .context("Querying state commitment")? + .context("State commitment not found")?; + if state_commitment != expected_state_commitment { return Err(SyncError2::StateRootMismatch); } db.update_storage_and_class_commitments(tail, storage_commitment, class_commitment) .context("Updating storage commitment")?; - db.insert_state_update(self.current_block, &state_update) + db.insert_state_update_data(self.current_block, &state_update) .context("Inserting state update data")?; db.commit().context("Committing db transaction")?;