diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index 9120b6e77c..7690a4e1ee 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -24,7 +24,9 @@ use ethrex_common::types::{ use ethrex_common::types::{ELASTICITY_MULTIPLIER, P2PTransaction}; use ethrex_common::{Address, H256, TrieLogger}; use ethrex_metrics::metrics; -use ethrex_storage::{Store, UpdateBatch, error::StoreError, hash_address, hash_key}; +use ethrex_storage::{ + AccountUpdatesList, Store, UpdateBatch, error::StoreError, hash_address, hash_key, +}; use ethrex_vm::backends::levm::db::DatabaseLogger; use ethrex_vm::{BlockExecutionResult, DynVmDatabase, Evm, EvmEngine, EvmError}; use mempool::Mempool; @@ -358,30 +360,18 @@ impl Blockchain { pub async fn store_block( &self, block: &Block, + account_updates_list: AccountUpdatesList, execution_result: BlockExecutionResult, - account_updates: &[AccountUpdate], ) -> Result<(), ChainError> { - // Apply the account updates over the last block's state and compute the new state root - let apply_updates_list = self - .storage - .apply_account_updates_batch(block.header.parent_hash, account_updates) - .await? - .ok_or(ChainError::ParentStateNotFound)?; - - let new_state_root = apply_updates_list.state_trie_hash; - let state_updates = apply_updates_list.state_updates; - let accounts_updates = apply_updates_list.storage_updates; - let code_updates = apply_updates_list.code_updates; - // Check state root matches the one in block header - validate_state_root(&block.header, new_state_root)?; + validate_state_root(&block.header, account_updates_list.state_trie_hash)?; let update_batch = UpdateBatch { - account_updates: state_updates, - storage_updates: accounts_updates, + account_updates: account_updates_list.state_updates, + storage_updates: account_updates_list.storage_updates, blocks: vec![block.clone()], receipts: vec![(block.hash(), execution_result.receipts)], - code_updates, + code_updates: account_updates_list.code_updates, }; self.storage @@ -395,44 +385,65 @@ impl Blockchain { let since = Instant::now(); let (res, updates) = self.execute_block(block).await?; let executed = Instant::now(); - let result = self.store_block(block, res, &updates).await; + + // Apply the account updates over the last block's state and compute the new state root + let account_updates_list = self + .storage + .apply_account_updates_batch(block.header.parent_hash, &updates) + .await? + .ok_or(ChainError::ParentStateNotFound)?; + + let merkleized = Instant::now(); + let result = self.store_block(block, account_updates_list, res).await; let stored = Instant::now(); - Self::print_add_block_logs(block, since, executed, stored); + Self::print_add_block_logs(block, since, executed, merkleized, stored); result } - fn print_add_block_logs(block: &Block, since: Instant, executed: Instant, stored: Instant) { + fn print_add_block_logs( + block: &Block, + since: Instant, + executed: Instant, + merkleized: Instant, + stored: Instant, + ) { let interval = stored.duration_since(since).as_millis() as f64; if interval != 0f64 { let as_gigas = block.header.gas_used as f64 / 10_f64.powf(9_f64); let throughput = as_gigas / interval * 1000_f64; - let execution_time = executed.duration_since(since).as_millis() as f64; - let storage_time = stored.duration_since(executed).as_millis() as f64; - let execution_fraction = (execution_time * 100_f64 / interval).round() as u64; - let storage_fraction = (storage_time * 100_f64 / interval).round() as u64; - let execution_time_per_gigagas = (execution_time / as_gigas).round() as u64; - let storage_time_per_gigagas = (storage_time / as_gigas).round() as u64; + metrics!( let _ = METRICS_BLOCKS.set_block_number(block.header.number); METRICS_BLOCKS.set_latest_gas_used(block.header.gas_used as f64); METRICS_BLOCKS.set_latest_block_gas_limit(block.header.gas_limit as f64); METRICS_BLOCKS.set_latest_gigagas(throughput); ); + let base_log = format!( - "[METRIC] BLOCK EXECUTION THROUGHPUT ({}): {:.2} Ggas/s TIME SPENT: {:.0} ms. Gas Used: {:.0}%, #Txs: {}.", + "[METRIC] BLOCK EXECUTION THROUGHPUT ({}): {:.3} Ggas/s TIME SPENT: {:.0} ms. Gas Used: {:.3} ({:.0}%), #Txs: {}.", block.header.number, throughput, interval, + as_gigas, (block.header.gas_used as f64 / block.header.gas_limit as f64) * 100.0, block.body.transactions.len() ); + + fn percentage(init: Instant, end: Instant, total: f64) -> f64 { + (end.duration_since(init).as_millis() as f64 / total * 100.0).round() + } + let extra_log = if as_gigas > 0.0 { format!( - " exec/Ggas: {execution_time_per_gigagas} ms ({execution_fraction}%), st/Ggas: {storage_time_per_gigagas} ms ({storage_fraction}%)", + " exec: {}% merkle: {}% store: {}%", + percentage(since, executed, interval), + percentage(executed, merkleized, interval), + percentage(merkleized, stored, interval) ) } else { "".to_string() }; + info!("{}{}", base_log, extra_log); } } diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index e3014d7515..2ab9a62165 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -6,6 +6,7 @@ use std::{ use ethrex_blockchain::{ Blockchain, + error::ChainError, fork_choice::apply_fork_choice, payload::{BuildPayloadArgs, create_payload}, validate_block, @@ -194,9 +195,15 @@ pub async fn produce_block(state: &BlockProducerState) -> Result<(), BlockProduc requests: Vec::new(), }; + let account_updates_list = state + .store + .apply_account_updates_batch(block.header.parent_hash, &account_updates) + .await? + .ok_or(ChainError::ParentStateNotFound)?; + state .blockchain - .store_block(&block, execution_result, &account_updates) + .store_block(&block, account_updates_list, execution_result) .await?; info!("Stored new block {:x}", block.hash()); // WARN: We're not storing the payload into the Store because there's no use to it by the L2 for now. diff --git a/crates/storage/lib.rs b/crates/storage/lib.rs index ffc320f459..98db64a95e 100644 --- a/crates/storage/lib.rs +++ b/crates/storage/lib.rs @@ -9,5 +9,6 @@ mod utils; pub mod error; pub use store::{ - EngineType, MAX_SNAPSHOT_READS, STATE_TRIE_SEGMENTS, Store, UpdateBatch, hash_address, hash_key, + AccountUpdatesList, EngineType, MAX_SNAPSHOT_READS, STATE_TRIE_SEGMENTS, Store, UpdateBatch, + hash_address, hash_key, };