From 0c7e2979c323335e2def86f3d9c11a5966a44ca0 Mon Sep 17 00:00:00 2001 From: voidash Date: Wed, 15 Jan 2025 10:25:33 +0545 Subject: [PATCH 1/3] Nit: replace block and sender in ExecutedBlock with RecoveredBlock --- crates/chain-state/src/in_memory.rs | 256 ++++++------- crates/chain-state/src/memory_overlay.rs | 10 +- crates/chain-state/src/test_utils.rs | 5 +- crates/engine/tree/src/engine.rs | 2 +- crates/engine/tree/src/persistence.rs | 12 +- crates/engine/tree/src/tree/mod.rs | 346 +++++++++--------- crates/ethereum/payload/src/lib.rs | 9 +- crates/node/builder/src/launch/engine.rs | 2 +- crates/optimism/payload/src/builder.rs | 9 +- .../src/providers/blockchain_provider.rs | 54 +-- .../provider/src/providers/consistent.rs | 106 ++++-- crates/storage/provider/src/writer/mod.rs | 12 +- 12 files changed, 443 insertions(+), 380 deletions(-) diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 59e01055f7a4..6358370e2b5d 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -6,7 +6,7 @@ use crate::{ }; use alloy_consensus::{transaction::TransactionMeta, BlockHeader}; use alloy_eips::{eip2718::Encodable2718, BlockHashOrNumber, BlockNumHash}; -use alloy_primitives::{map::HashMap, Address, TxHash, B256}; +use alloy_primitives::{map::HashMap, TxHash, B256}; use parking_lot::RwLock; use reth_chainspec::ChainInfo; use reth_execution_types::{Chain, ExecutionOutcome}; @@ -181,7 +181,7 @@ impl CanonicalInMemoryState { ) -> Self { let in_memory_state = InMemoryState::new(blocks, numbers, pending); let header = in_memory_state.head_state().map_or_else(SealedHeader::default, |state| { - state.block_ref().block().clone_sealed_header() + state.block_ref().recovered_block().clone_sealed_header() }); let chain_info_tracker = ChainInfoTracker::new(header, finalized, safe); let (canon_state_notification_sender, _) = @@ -228,7 +228,8 @@ impl CanonicalInMemoryState { /// Returns the header corresponding to the given hash. pub fn header_by_hash(&self, hash: B256) -> Option> { - self.state_by_hash(hash).map(|block| block.block_ref().block.clone_sealed_header()) + self.state_by_hash(hash) + .map(|block| block.block_ref().recovered_block().clone_sealed_header()) } /// Clears all entries in the in memory state. @@ -241,7 +242,7 @@ impl CanonicalInMemoryState { /// Note: This assumes that the parent block of the pending block is canonical. pub fn set_pending_block(&self, pending: ExecutedBlock) { // fetch the state of the pending block's parent block - let parent = self.state_by_hash(pending.block().parent_hash()); + let parent = self.state_by_hash(pending.recovered_block().parent_hash()); let pending = BlockState::with_parent(pending, parent); self.inner.in_memory_state.pending.send_modify(|p| { p.replace(pending); @@ -264,15 +265,15 @@ impl CanonicalInMemoryState { // we first remove the blocks from the reorged chain for block in reorged { - let hash = block.block().hash(); - let number = block.block().number(); + let hash = block.recovered_block().hash(); + let number = block.recovered_block().number(); blocks.remove(&hash); numbers.remove(&number); } // insert the new blocks for block in new_blocks { - let parent = blocks.get(&block.block().parent_hash()).cloned(); + let parent = blocks.get(&block.recovered_block().parent_hash()).cloned(); let block_state = BlockState::with_parent(block, parent); let hash = block_state.hash(); let number = block_state.number(); @@ -332,16 +333,16 @@ impl CanonicalInMemoryState { // height) let mut old_blocks = blocks .drain() - .filter(|(_, b)| b.block_ref().block().number() > persisted_height) + .filter(|(_, b)| b.block_ref().recovered_block().number() > persisted_height) .map(|(_, b)| b.block.clone()) .collect::>(); // sort the blocks by number so we can insert them back in natural order (low -> high) - old_blocks.sort_unstable_by_key(|block| block.block().number()); + old_blocks.sort_unstable_by_key(|block| block.recovered_block().number()); // re-insert the blocks in natural order and connect them to their parent blocks for block in old_blocks { - let parent = blocks.get(&block.block().parent_hash()).cloned(); + let parent = blocks.get(&block.recovered_block().parent_hash()).cloned(); let block_state = BlockState::with_parent(block, parent); let hash = block_state.hash(); let number = block_state.number(); @@ -354,7 +355,7 @@ impl CanonicalInMemoryState { // also shift the pending state if it exists self.inner.in_memory_state.pending.send_modify(|p| { if let Some(p) = p.as_mut() { - p.parent = blocks.get(&p.block_ref().block.parent_hash()).cloned(); + p.parent = blocks.get(&p.block_ref().recovered_block().parent_hash()).cloned(); } }); } @@ -461,7 +462,7 @@ impl CanonicalInMemoryState { /// Returns the `SealedHeader` corresponding to the pending state. pub fn pending_sealed_header(&self) -> Option> { - self.pending_state().map(|h| h.block_ref().block().clone_sealed_header()) + self.pending_state().map(|h| h.block_ref().recovered_block().clone_sealed_header()) } /// Returns the `Header` corresponding to the pending state. @@ -471,7 +472,8 @@ impl CanonicalInMemoryState { /// Returns the `SealedBlock` corresponding to the pending state. pub fn pending_block(&self) -> Option> { - self.pending_state().map(|block_state| block_state.block_ref().block().clone()) + self.pending_state() + .map(|block_state| block_state.block_ref().recovered_block().sealed_block().clone()) } /// Returns the `RecoveredBlock` corresponding to the pending state. @@ -479,15 +481,17 @@ impl CanonicalInMemoryState { where N::SignedTx: SignedTransaction, { - self.pending_state() - .and_then(|block_state| block_state.block_ref().block().clone().try_recover().ok()) + self.pending_state().map(|block_state| block_state.block_ref().recovered_block().clone()) } /// Returns a tuple with the `SealedBlock` corresponding to the pending /// state and a vector of its `Receipt`s. pub fn pending_block_and_receipts(&self) -> Option> { self.pending_state().map(|block_state| { - (block_state.block_ref().block().clone(), block_state.executed_block_receipts()) + ( + block_state.block_ref().recovered_block().sealed_block().clone(), + block_state.executed_block_receipts(), + ) }) } @@ -547,7 +551,7 @@ impl CanonicalInMemoryState { for block_state in self.canonical_chain() { if let Some(tx) = block_state .block_ref() - .block() + .recovered_block() .body() .transactions() .iter() @@ -571,7 +575,7 @@ impl CanonicalInMemoryState { for block_state in self.canonical_chain() { if let Some((index, tx)) = block_state .block_ref() - .block() + .recovered_block() .body() .transactions() .iter() @@ -582,10 +586,10 @@ impl CanonicalInMemoryState { tx_hash, index: index as u64, block_hash: block_state.hash(), - block_number: block_state.block_ref().block.number(), - base_fee: block_state.block_ref().block.base_fee_per_gas(), - timestamp: block_state.block_ref().block.timestamp(), - excess_blob_gas: block_state.block_ref().block.excess_blob_gas(), + block_number: block_state.block_ref().recovered_block().number(), + base_fee: block_state.block_ref().recovered_block().base_fee_per_gas(), + timestamp: block_state.block_ref().recovered_block().timestamp(), + excess_blob_gas: block_state.block_ref().recovered_block().excess_blob_gas(), }; return Some((tx.clone(), meta)) } @@ -621,7 +625,7 @@ impl BlockState { if let Some(parent) = &self.parent { parent.anchor() } else { - self.block.block().parent_num_hash() + self.block.recovered_block().parent_num_hash() } } @@ -635,27 +639,20 @@ impl BlockState { &self.block } - /// Returns a clone of the block with recovered senders for the state. - pub fn clone_recovered_block(&self) -> RecoveredBlock { - let block = self.block.block().clone(); - let senders = self.block.senders().clone(); - RecoveredBlock::new_sealed(block, senders) - } - /// Returns the hash of executed block that determines the state. pub fn hash(&self) -> B256 { - self.block.block().hash() + self.block.recovered_block().hash() } /// Returns the block number of executed block that determines the state. pub fn number(&self) -> u64 { - self.block.block().number() + self.block.recovered_block().number() } /// Returns the state root after applying the executed block that determines /// the state. pub fn state_root(&self) -> B256 { - self.block.block().state_root() + self.block.recovered_block().state_root() } /// Returns the `Receipts` of executed block that determines the state. @@ -748,7 +745,7 @@ impl BlockState { self.chain().find_map(|block_state| { block_state .block_ref() - .block() + .recovered_block() .body() .transactions() .iter() @@ -768,7 +765,7 @@ impl BlockState { self.chain().find_map(|block_state| { block_state .block_ref() - .block() + .recovered_block() .body() .transactions() .iter() @@ -779,10 +776,13 @@ impl BlockState { tx_hash, index: index as u64, block_hash: block_state.hash(), - block_number: block_state.block_ref().block.number(), - base_fee: block_state.block_ref().block.base_fee_per_gas(), - timestamp: block_state.block_ref().block.timestamp(), - excess_blob_gas: block_state.block_ref().block.excess_blob_gas(), + block_number: block_state.block_ref().recovered_block().number(), + base_fee: block_state.block_ref().recovered_block().base_fee_per_gas(), + timestamp: block_state.block_ref().recovered_block().timestamp(), + excess_blob_gas: block_state + .block_ref() + .recovered_block() + .excess_blob_gas(), }; (tx.clone(), meta) }) @@ -793,10 +793,8 @@ impl BlockState { /// Represents an executed block stored in-memory. #[derive(Clone, Debug, PartialEq, Eq, Default)] pub struct ExecutedBlock { - /// Sealed block the rest of fields refer to. - pub block: Arc>, - /// Block's senders. - pub senders: Arc>, + /// Recovered Block + pub recovered_block: Arc>, /// Block's execution outcome. pub execution_output: Arc>, /// Block's hashed state. @@ -808,30 +806,17 @@ pub struct ExecutedBlock { impl ExecutedBlock { /// [`ExecutedBlock`] constructor. pub const fn new( - block: Arc>, - senders: Arc>, + recovered_block: Arc>, execution_output: Arc>, hashed_state: Arc, trie: Arc, ) -> Self { - Self { block, senders, execution_output, hashed_state, trie } + Self { recovered_block, execution_output, hashed_state, trie } } - /// Returns a reference to the executed block. - pub fn block(&self) -> &SealedBlock { - &self.block - } - - /// Returns a reference to the block's senders - pub fn senders(&self) -> &Vec
{ - &self.senders - } - - /// Returns a [`RecoveredBlock`] - /// - /// Note: this clones the block and senders. - pub fn clone_recovered_block(&self) -> RecoveredBlock { - RecoveredBlock::new_sealed((*self.block).clone(), (*self.senders).clone()) + /// Returns a reference to [`RecoveredBlock`] + pub fn recovered_block(&self) -> &RecoveredBlock { + &self.recovered_block } /// Returns a reference to the block's execution outcome @@ -890,7 +875,7 @@ impl> NewCanonicalChain { Self::Commit { new } => { let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| { chain.append_block( - exec.clone_recovered_block(), + exec.recovered_block().clone(), exec.execution_outcome().clone(), ); chain @@ -900,14 +885,14 @@ impl> NewCanonicalChain { Self::Reorg { new, old } => { let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| { chain.append_block( - exec.clone_recovered_block(), + exec.recovered_block().clone(), exec.execution_outcome().clone(), ); chain })); let old = Arc::new(old.iter().fold(Chain::default(), |mut chain, exec| { chain.append_block( - exec.clone_recovered_block(), + exec.recovered_block().clone(), exec.execution_outcome().clone(), ); chain @@ -924,7 +909,7 @@ impl> NewCanonicalChain { pub fn tip(&self) -> &SealedBlock { match self { Self::Commit { new } | Self::Reorg { new, .. } => { - new.last().expect("non empty blocks").block() + new.last().expect("non empty blocks").recovered_block() } } } @@ -935,7 +920,9 @@ mod tests { use super::*; use crate::test_utils::TestBlockBuilder; use alloy_eips::eip7685::Requests; - use alloy_primitives::{map::B256HashMap, BlockNumber, Bytes, StorageKey, StorageValue}; + use alloy_primitives::{ + map::B256HashMap, Address, BlockNumber, Bytes, StorageKey, StorageValue, + }; use rand::Rng; use reth_errors::ProviderResult; use reth_primitives::{Account, Bytecode, EthPrimitives, Receipt}; @@ -1168,8 +1155,8 @@ mod tests { let result = in_memory_state.pending_state(); assert!(result.is_some()); let actual_pending_state = result.unwrap(); - assert_eq!(actual_pending_state.block.block().hash(), pending_hash); - assert_eq!(actual_pending_state.block.block().number, pending_number); + assert_eq!(actual_pending_state.block.recovered_block().hash(), pending_hash); + assert_eq!(actual_pending_state.block.recovered_block().number, pending_number); } #[test] @@ -1210,7 +1197,7 @@ mod tests { let state = BlockState::new(block.clone()); - assert_eq!(state.hash(), block.block.hash()); + assert_eq!(state.hash(), block.recovered_block().hash()); } #[test] @@ -1232,7 +1219,7 @@ mod tests { let state = BlockState::new(block.clone()); - assert_eq!(state.state_root(), block.block().state_root); + assert_eq!(state.state_root(), block.recovered_block().state_root); } #[test] @@ -1255,18 +1242,24 @@ mod tests { let block2 = test_block_builder.get_executed_block_with_number(0, B256::random()); let chain = NewCanonicalChain::Commit { new: vec![block1.clone()] }; state.update_chain(chain); - assert_eq!(state.head_state().unwrap().block_ref().block().hash(), block1.block().hash()); assert_eq!( - state.state_by_number(0).unwrap().block_ref().block().hash(), - block1.block().hash() + state.head_state().unwrap().block_ref().recovered_block().hash(), + block1.recovered_block().hash() + ); + assert_eq!( + state.state_by_number(0).unwrap().block_ref().recovered_block().hash(), + block1.recovered_block().hash() ); let chain = NewCanonicalChain::Reorg { new: vec![block2.clone()], old: vec![block1] }; state.update_chain(chain); - assert_eq!(state.head_state().unwrap().block_ref().block().hash(), block2.block().hash()); assert_eq!( - state.state_by_number(0).unwrap().block_ref().block().hash(), - block2.block().hash() + state.head_state().unwrap().block_ref().recovered_block().hash(), + block2.recovered_block().hash() + ); + assert_eq!( + state.state_by_number(0).unwrap().block_ref().recovered_block().hash(), + block2.recovered_block().hash() ); assert_eq!(state.inner.in_memory_state.block_count(), 1); @@ -1281,7 +1274,8 @@ mod tests { let block1 = test_block_builder.get_executed_block_with_number(0, B256::random()); // Second block with parent hash of the first block - let block2 = test_block_builder.get_executed_block_with_number(1, block1.block().hash()); + let block2 = + test_block_builder.get_executed_block_with_number(1, block1.recovered_block().hash()); // Commit the two blocks let chain = NewCanonicalChain::Commit { new: vec![block1.clone(), block2.clone()] }; @@ -1300,69 +1294,75 @@ mod tests { ); // Check the pending block - assert_eq!(state.pending_block().unwrap(), block2.block().clone()); + assert_eq!(state.pending_block().unwrap(), block2.recovered_block().sealed_block().clone()); // Check the pending block number and hash assert_eq!( state.pending_block_num_hash().unwrap(), - BlockNumHash { number: 1, hash: block2.block().hash() } + BlockNumHash { number: 1, hash: block2.recovered_block().hash() } ); // Check the pending header - assert_eq!(state.pending_header().unwrap(), block2.block().header().clone()); + assert_eq!(state.pending_header().unwrap(), block2.recovered_block().header().clone()); // Check the pending sealed header - assert_eq!(state.pending_sealed_header().unwrap(), block2.block().clone_sealed_header()); - - // Check the pending block with senders assert_eq!( - state.pending_recovered_block().unwrap(), - block2.block().clone().try_recover().unwrap() + state.pending_sealed_header().unwrap(), + block2.recovered_block().clone_sealed_header() ); + // Check the pending block with senders + assert_eq!(state.pending_recovered_block().unwrap(), block2.recovered_block().clone()); + // Check the pending block and receipts - assert_eq!(state.pending_block_and_receipts().unwrap(), (block2.block().clone(), vec![])); + assert_eq!( + state.pending_block_and_receipts().unwrap(), + (block2.recovered_block().sealed_block().clone(), vec![]) + ); } #[test] fn test_canonical_in_memory_state_state_provider() { let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default(); let block1 = test_block_builder.get_executed_block_with_number(1, B256::random()); - let block2 = test_block_builder.get_executed_block_with_number(2, block1.block().hash()); - let block3 = test_block_builder.get_executed_block_with_number(3, block2.block().hash()); + let block2 = + test_block_builder.get_executed_block_with_number(2, block1.recovered_block().hash()); + let block3 = + test_block_builder.get_executed_block_with_number(3, block2.recovered_block().hash()); let state1 = Arc::new(BlockState::new(block1.clone())); let state2 = Arc::new(BlockState::with_parent(block2.clone(), Some(state1.clone()))); let state3 = Arc::new(BlockState::with_parent(block3.clone(), Some(state2.clone()))); let mut blocks = HashMap::default(); - blocks.insert(block1.block().hash(), state1); - blocks.insert(block2.block().hash(), state2); - blocks.insert(block3.block().hash(), state3); + blocks.insert(block1.recovered_block().hash(), state1); + blocks.insert(block2.recovered_block().hash(), state2); + blocks.insert(block3.recovered_block().hash(), state3); let mut numbers = BTreeMap::new(); - numbers.insert(1, block1.block().hash()); - numbers.insert(2, block2.block().hash()); - numbers.insert(3, block3.block().hash()); + numbers.insert(1, block1.recovered_block().hash()); + numbers.insert(2, block2.recovered_block().hash()); + numbers.insert(3, block3.recovered_block().hash()); let canonical_state = CanonicalInMemoryState::new(blocks, numbers, None, None, None); let historical: StateProviderBox = Box::new(MockStateProvider); - let overlay_provider = canonical_state.state_provider(block3.block().hash(), historical); + let overlay_provider = + canonical_state.state_provider(block3.recovered_block().hash(), historical); assert_eq!(overlay_provider.in_memory.len(), 3); - assert_eq!(overlay_provider.in_memory[0].block().number, 3); - assert_eq!(overlay_provider.in_memory[1].block().number, 2); - assert_eq!(overlay_provider.in_memory[2].block().number, 1); + assert_eq!(overlay_provider.in_memory[0].recovered_block().number, 3); + assert_eq!(overlay_provider.in_memory[1].recovered_block().number, 2); + assert_eq!(overlay_provider.in_memory[2].recovered_block().number, 1); assert_eq!( - overlay_provider.in_memory[0].block().parent_hash, - overlay_provider.in_memory[1].block().hash() + overlay_provider.in_memory[0].recovered_block().parent_hash, + overlay_provider.in_memory[1].recovered_block().hash() ); assert_eq!( - overlay_provider.in_memory[1].block().parent_hash, - overlay_provider.in_memory[2].block().hash() + overlay_provider.in_memory[1].recovered_block().parent_hash, + overlay_provider.in_memory[2].recovered_block().hash() ); let unknown_hash = B256::random(); @@ -1381,7 +1381,7 @@ mod tests { #[test] fn test_canonical_in_memory_state_canonical_chain_single_block() { let block = TestBlockBuilder::eth().get_executed_block_with_number(1, B256::random()); - let hash = block.block().hash(); + let hash = block.recovered_block().hash(); let mut blocks = HashMap::default(); blocks.insert(hash, Arc::new(BlockState::new(block))); let mut numbers = BTreeMap::new(); @@ -1403,7 +1403,7 @@ mod tests { for i in 1..=3 { let block = block_builder.get_executed_block_with_number(i, parent_hash); - let hash = block.block().hash(); + let hash = block.recovered_block().hash(); state.update_blocks(Some(block), None); parent_hash = hash; } @@ -1425,7 +1425,7 @@ mod tests { for i in 1..=2 { let block = block_builder.get_executed_block_with_number(i, parent_hash); - let hash = block.block().hash(); + let hash = block.recovered_block().hash(); state.update_blocks(Some(block), None); parent_hash = hash; } @@ -1446,14 +1446,14 @@ mod tests { let parents = chain[3].parent_state_chain(); assert_eq!(parents.len(), 3); - assert_eq!(parents[0].block().block.number, 3); - assert_eq!(parents[1].block().block.number, 2); - assert_eq!(parents[2].block().block.number, 1); + assert_eq!(parents[0].block().recovered_block().number, 3); + assert_eq!(parents[1].block().recovered_block().number, 2); + assert_eq!(parents[2].block().recovered_block().number, 1); let parents = chain[2].parent_state_chain(); assert_eq!(parents.len(), 2); - assert_eq!(parents[0].block().block.number, 2); - assert_eq!(parents[1].block().block.number, 1); + assert_eq!(parents[0].block().recovered_block().number, 2); + assert_eq!(parents[1].block().recovered_block().number, 1); let parents = chain[0].parent_state_chain(); assert_eq!(parents.len(), 0); @@ -1465,15 +1465,15 @@ mod tests { let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default(); let single_block = create_mock_state(&mut test_block_builder, single_block_number, B256::random()); - let single_block_hash = single_block.block().block.hash(); + let single_block_hash = single_block.block().recovered_block().hash(); let parents = single_block.parent_state_chain(); assert_eq!(parents.len(), 0); let block_state_chain = single_block.chain().collect::>(); assert_eq!(block_state_chain.len(), 1); - assert_eq!(block_state_chain[0].block().block.number, single_block_number); - assert_eq!(block_state_chain[0].block().block.hash(), single_block_hash); + assert_eq!(block_state_chain[0].block().recovered_block().number, single_block_number); + assert_eq!(block_state_chain[0].block().recovered_block().hash(), single_block_hash); } #[test] @@ -1483,18 +1483,18 @@ mod tests { let block_state_chain = chain[2].chain().collect::>(); assert_eq!(block_state_chain.len(), 3); - assert_eq!(block_state_chain[0].block().block.number, 3); - assert_eq!(block_state_chain[1].block().block.number, 2); - assert_eq!(block_state_chain[2].block().block.number, 1); + assert_eq!(block_state_chain[0].block().recovered_block().number, 3); + assert_eq!(block_state_chain[1].block().recovered_block().number, 2); + assert_eq!(block_state_chain[2].block().recovered_block().number, 1); let block_state_chain = chain[1].chain().collect::>(); assert_eq!(block_state_chain.len(), 2); - assert_eq!(block_state_chain[0].block().block.number, 2); - assert_eq!(block_state_chain[1].block().block.number, 1); + assert_eq!(block_state_chain[0].block().recovered_block().number, 2); + assert_eq!(block_state_chain[1].block().recovered_block().number, 1); let block_state_chain = chain[0].chain().collect::>(); assert_eq!(block_state_chain.len(), 1); - assert_eq!(block_state_chain[0].block().block.number, 1); + assert_eq!(block_state_chain[0].block().recovered_block().number, 1); } #[test] @@ -1502,10 +1502,14 @@ mod tests { // Generate 4 blocks let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default(); let block0 = test_block_builder.get_executed_block_with_number(0, B256::random()); - let block1 = test_block_builder.get_executed_block_with_number(1, block0.block.hash()); - let block1a = test_block_builder.get_executed_block_with_number(1, block0.block.hash()); - let block2 = test_block_builder.get_executed_block_with_number(2, block1.block.hash()); - let block2a = test_block_builder.get_executed_block_with_number(2, block1.block.hash()); + let block1 = + test_block_builder.get_executed_block_with_number(1, block0.recovered_block.hash()); + let block1a = + test_block_builder.get_executed_block_with_number(1, block0.recovered_block.hash()); + let block2 = + test_block_builder.get_executed_block_with_number(2, block1.recovered_block.hash()); + let block2a = + test_block_builder.get_executed_block_with_number(2, block1.recovered_block.hash()); let sample_execution_outcome = ExecutionOutcome { receipts: Receipts::from_iter([vec![], vec![]]), @@ -1520,7 +1524,7 @@ mod tests { chain_commit.to_chain_notification(), CanonStateNotification::Commit { new: Arc::new(Chain::new( - vec![block0.clone_recovered_block(), block1.clone_recovered_block()], + vec![block0.recovered_block().clone(), block1.recovered_block().clone()], sample_execution_outcome.clone(), None )) @@ -1537,12 +1541,12 @@ mod tests { chain_reorg.to_chain_notification(), CanonStateNotification::Reorg { old: Arc::new(Chain::new( - vec![block1.clone_recovered_block(), block2.clone_recovered_block()], + vec![block1.recovered_block().clone(), block2.recovered_block().clone()], sample_execution_outcome.clone(), None )), new: Arc::new(Chain::new( - vec![block1a.clone_recovered_block(), block2a.clone_recovered_block()], + vec![block1a.recovered_block().clone(), block2a.recovered_block().clone()], sample_execution_outcome, None )) diff --git a/crates/chain-state/src/memory_overlay.rs b/crates/chain-state/src/memory_overlay.rs index 880c95ab3c37..51594890b8ac 100644 --- a/crates/chain-state/src/memory_overlay.rs +++ b/crates/chain-state/src/memory_overlay.rs @@ -65,8 +65,8 @@ impl<'a, N: NodePrimitives> MemoryOverlayStateProviderRef<'a, N> { impl BlockHashReader for MemoryOverlayStateProviderRef<'_, N> { fn block_hash(&self, number: BlockNumber) -> ProviderResult> { for block in &self.in_memory { - if block.block.number() == number { - return Ok(Some(block.block.hash())); + if block.recovered_block().number() == number { + return Ok(Some(block.recovered_block().hash())); } } @@ -82,9 +82,9 @@ impl BlockHashReader for MemoryOverlayStateProviderRef<'_, N> let mut earliest_block_number = None; let mut in_memory_hashes = Vec::new(); for block in &self.in_memory { - if range.contains(&block.block.number()) { - in_memory_hashes.insert(0, block.block.hash()); - earliest_block_number = Some(block.block.number()); + if range.contains(&block.recovered_block().number()) { + in_memory_hashes.insert(0, block.recovered_block().hash()); + earliest_block_number = Some(block.recovered_block().number()); } } diff --git a/crates/chain-state/src/test_utils.rs b/crates/chain-state/src/test_utils.rs index cce88d713612..9f8135b2a09a 100644 --- a/crates/chain-state/src/test_utils.rs +++ b/crates/chain-state/src/test_utils.rs @@ -210,8 +210,7 @@ impl TestBlockBuilder { let (block, senders) = block_with_senders.split_sealed(); ExecutedBlock::new( - Arc::new(block), - Arc::new(senders), + Arc::new(RecoveredBlock::new_sealed(block, senders)), Arc::new(ExecutionOutcome::new( BundleState::default(), receipts, @@ -251,7 +250,7 @@ impl TestBlockBuilder { range.map(move |number| { let current_parent_hash = parent_hash; let block = self.get_executed_block_with_number(number, current_parent_hash); - parent_hash = block.block.hash(); + parent_hash = block.recovered_block().hash(); block }) } diff --git a/crates/engine/tree/src/engine.rs b/crates/engine/tree/src/engine.rs index 238846d4f0d6..1e721627becf 100644 --- a/crates/engine/tree/src/engine.rs +++ b/crates/engine/tree/src/engine.rs @@ -253,7 +253,7 @@ impl Display for EngineApiRequest { match self { Self::Beacon(msg) => msg.fmt(f), Self::InsertExecutedBlock(block) => { - write!(f, "InsertExecutedBlock({:?})", block.block().num_hash()) + write!(f, "InsertExecutedBlock({:?})", block.recovered_block().num_hash()) } } } diff --git a/crates/engine/tree/src/persistence.rs b/crates/engine/tree/src/persistence.rs index 787120292452..5c9d1357d2c7 100644 --- a/crates/engine/tree/src/persistence.rs +++ b/crates/engine/tree/src/persistence.rs @@ -142,11 +142,11 @@ where &self, blocks: Vec>, ) -> Result, PersistenceError> { - debug!(target: "engine::persistence", first=?blocks.first().map(|b| b.block.num_hash()), last=?blocks.last().map(|b| b.block.num_hash()), "Saving range of blocks"); + debug!(target: "engine::persistence", first=?blocks.first().map(|b| b.recovered_block.num_hash()), last=?blocks.last().map(|b| b.recovered_block.num_hash()), "Saving range of blocks"); let start_time = Instant::now(); let last_block_hash_num = blocks.last().map(|block| BlockNumHash { - hash: block.block().hash(), - number: block.block().header().number(), + hash: block.recovered_block().hash(), + number: block.recovered_block().header().number(), }); if last_block_hash_num.is_some() { @@ -339,7 +339,7 @@ mod tests { let mut test_block_builder = TestBlockBuilder::eth(); let executed = test_block_builder.get_executed_block_with_number(block_number, B256::random()); - let block_hash = executed.block().hash(); + let block_hash = executed.recovered_block().hash(); let blocks = vec![executed]; let (tx, rx) = oneshot::channel(); @@ -363,7 +363,7 @@ mod tests { let mut test_block_builder = TestBlockBuilder::eth(); let blocks = test_block_builder.get_executed_blocks(0..5).collect::>(); - let last_hash = blocks.last().unwrap().block().hash(); + let last_hash = blocks.last().unwrap().recovered_block().hash(); let (tx, rx) = oneshot::channel(); persistence_handle.save_blocks(blocks, tx).unwrap(); @@ -380,7 +380,7 @@ mod tests { let mut test_block_builder = TestBlockBuilder::eth(); for range in ranges { let blocks = test_block_builder.get_executed_blocks(range).collect::>(); - let last_hash = blocks.last().unwrap().block().hash(); + let last_hash = blocks.last().unwrap().recovered_block().hash(); let (tx, rx) = oneshot::channel(); persistence_handle.save_blocks(blocks, tx).unwrap(); diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index cff2dfdebbd3..059fde3d7414 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -147,7 +147,7 @@ impl TreeState { /// Returns the block by hash. fn block_by_hash(&self, hash: B256) -> Option>> { - self.blocks_by_hash.get(&hash).map(|b| b.block.clone()) + self.blocks_by_hash.get(&hash).map(|b| Arc::new(b.recovered_block().sealed_block().clone())) } /// Returns all available blocks for the given hash that lead back to the canonical chain, from @@ -156,10 +156,10 @@ impl TreeState { /// Returns `None` if the block for the given hash is not found. fn blocks_by_hash(&self, hash: B256) -> Option<(B256, Vec>)> { let block = self.blocks_by_hash.get(&hash).cloned()?; - let mut parent_hash = block.block().parent_hash(); + let mut parent_hash = block.recovered_block().parent_hash(); let mut blocks = vec![block]; while let Some(executed) = self.blocks_by_hash.get(&parent_hash) { - parent_hash = executed.block.parent_hash(); + parent_hash = executed.recovered_block().parent_hash(); blocks.push(executed.clone()); } @@ -168,9 +168,9 @@ impl TreeState { /// Insert executed block into the state. fn insert_executed(&mut self, executed: ExecutedBlock) { - let hash = executed.block.hash(); - let parent_hash = executed.block.parent_hash(); - let block_number = executed.block.number(); + let hash = executed.recovered_block().hash(); + let parent_hash = executed.recovered_block().parent_hash(); + let block_number = executed.recovered_block().number(); if self.blocks_by_hash.contains_key(&hash) { return; @@ -202,7 +202,7 @@ impl TreeState { let executed = self.blocks_by_hash.remove(&hash)?; // Remove this block from collection of children of its parent block. - let parent_entry = self.parent_to_child.entry(executed.block.parent_hash()); + let parent_entry = self.parent_to_child.entry(executed.recovered_block().parent_hash()); if let hash_map::Entry::Occupied(mut entry) = parent_entry { entry.get_mut().remove(&hash); @@ -215,10 +215,11 @@ impl TreeState { let children = self.parent_to_child.remove(&hash).unwrap_or_default(); // Remove this block from `blocks_by_number`. - let block_number_entry = self.blocks_by_number.entry(executed.block.number()); + let block_number_entry = self.blocks_by_number.entry(executed.recovered_block().number()); if let btree_map::Entry::Occupied(mut entry) = block_number_entry { // We have to find the index of the block since it exists in a vec - if let Some(index) = entry.get().iter().position(|b| b.block.hash() == hash) { + if let Some(index) = entry.get().iter().position(|b| b.recovered_block().hash() == hash) + { entry.get_mut().swap_remove(index); // If there are no blocks left then remove the entry for this block @@ -239,7 +240,7 @@ impl TreeState { } while let Some(executed) = self.blocks_by_hash.get(¤t_block) { - current_block = executed.block.parent_hash(); + current_block = executed.recovered_block().parent_hash(); if current_block == hash { return true } @@ -267,14 +268,16 @@ impl TreeState { // upper bound let mut current_block = self.current_canonical_head.hash; while let Some(executed) = self.blocks_by_hash.get(¤t_block) { - current_block = executed.block.parent_hash(); - if executed.block.number() <= upper_bound { - debug!(target: "engine::tree", num_hash=?executed.block.num_hash(), "Attempting to remove block walking back from the head"); - if let Some((removed, _)) = self.remove_by_hash(executed.block.hash()) { - debug!(target: "engine::tree", num_hash=?removed.block.num_hash(), "Removed block walking back from the head"); + current_block = executed.recovered_block().parent_hash(); + if executed.recovered_block().number() <= upper_bound { + debug!(target: "engine::tree", num_hash=?executed.recovered_block().num_hash(), "Attempting to remove block walking back from the head"); + if let Some((removed, _)) = self.remove_by_hash(executed.recovered_block().hash()) { + debug!(target: "engine::tree", num_hash=?removed.recovered_block().num_hash(), "Removed block walking back from the head"); // finally, move the trie updates - self.persisted_trie_updates - .insert(removed.block.hash(), (removed.block.number(), removed.trie)); + self.persisted_trie_updates.insert( + removed.recovered_block().hash(), + (removed.recovered_block().number(), removed.trie), + ); } } } @@ -297,11 +300,11 @@ impl TreeState { let blocks_to_remove = self .blocks_by_number .range((Bound::Unbounded, Bound::Excluded(finalized_num))) - .flat_map(|(_, blocks)| blocks.iter().map(|b| b.block.hash())) + .flat_map(|(_, blocks)| blocks.iter().map(|b| b.recovered_block().hash())) .collect::>(); for hash in blocks_to_remove { if let Some((removed, _)) = self.remove_by_hash(hash) { - debug!(target: "engine::tree", num_hash=?removed.block.num_hash(), "Removed finalized sidechain block"); + debug!(target: "engine::tree", num_hash=?removed.recovered_block().num_hash(), "Removed finalized sidechain block"); } } @@ -318,17 +321,19 @@ impl TreeState { // re-insert the finalized hash if we removed it if let Some(position) = - blocks_to_remove.iter().position(|b| b.block.hash() == finalized_hash) + blocks_to_remove.iter().position(|b| b.recovered_block().hash() == finalized_hash) { let finalized_block = blocks_to_remove.swap_remove(position); self.blocks_by_number.insert(finalized_num, vec![finalized_block]); } - let mut blocks_to_remove = - blocks_to_remove.into_iter().map(|e| e.block.hash()).collect::>(); + let mut blocks_to_remove = blocks_to_remove + .into_iter() + .map(|e| e.recovered_block().hash()) + .collect::>(); while let Some(block) = blocks_to_remove.pop_front() { if let Some((removed, children)) = self.remove_by_hash(block) { - debug!(target: "engine::tree", num_hash=?removed.block.num_hash(), "Removed finalized sidechain child block"); + debug!(target: "engine::tree", num_hash=?removed.recovered_block().num_hash(), "Removed finalized sidechain child block"); blocks_to_remove.extend(children); } } @@ -900,11 +905,11 @@ where return Ok(None) }; - let new_head_number = new_head_block.block.number(); + let new_head_number = new_head_block.recovered_block().number(); let mut current_canonical_number = self.state.tree_state.current_canonical_head.number; let mut new_chain = vec![new_head_block.clone()]; - let mut current_hash = new_head_block.block.parent_hash(); + let mut current_hash = new_head_block.recovered_block().parent_hash(); let mut current_number = new_head_number - 1; // Walk back the new chain until we reach a block we know about @@ -913,7 +918,7 @@ where // that are _above_ the current canonical head. while current_number > current_canonical_number { if let Some(block) = self.executed_block_by_hash(current_hash)? { - current_hash = block.block.parent_hash(); + current_hash = block.recovered_block().parent_hash(); current_number -= 1; new_chain.push(block); } else { @@ -942,7 +947,7 @@ where while current_canonical_number > current_number { if let Some(block) = self.executed_block_by_hash(old_hash)? { old_chain.push(block.clone()); - old_hash = block.block.parent_hash(); + old_hash = block.recovered_block().parent_hash(); current_canonical_number -= 1; } else { // This shouldn't happen as we're walking back the canonical chain @@ -958,7 +963,7 @@ where // a common ancestor (fork block) is reached. while old_hash != current_hash { if let Some(block) = self.executed_block_by_hash(old_hash)? { - old_hash = block.block.parent_hash(); + old_hash = block.recovered_block().parent_hash(); old_chain.push(block); } else { // This shouldn't happen as we're walking back the canonical chain @@ -967,7 +972,7 @@ where } if let Some(block) = self.executed_block_by_hash(current_hash)? { - current_hash = block.block.parent_hash(); + current_hash = block.recovered_block().parent_hash(); new_chain.push(block); } else { // This shouldn't happen as we've already walked this path @@ -1203,7 +1208,7 @@ where if blocks_to_persist.is_empty() { debug!(target: "engine::tree", "Returned empty set of blocks to persist"); } else { - debug!(target: "engine::tree", blocks = ?blocks_to_persist.iter().map(|block| block.block.num_hash()).collect::>(), "Persisting blocks"); + debug!(target: "engine::tree", blocks = ?blocks_to_persist.iter().map(|block| block.recovered_block().num_hash()).collect::>(), "Persisting blocks"); let (tx, rx) = oneshot::channel(); let _ = self.persistence.save_blocks(blocks_to_persist, tx); self.persistence_state.start(rx); @@ -1262,9 +1267,9 @@ where FromEngine::Request(request) => { match request { EngineApiRequest::InsertExecutedBlock(block) => { - debug!(target: "engine::tree", block=?block.block().num_hash(), "inserting already executed block"); + debug!(target: "engine::tree", block=?block.recovered_block().num_hash(), "inserting already executed block"); let now = Instant::now(); - let sealed_block = block.block.clone(); + let sealed_block = Arc::new(block.recovered_block().sealed_block().clone()); self.state.tree_state.insert_executed(block); self.metrics.engine.inserted_already_executed_blocks.increment(1); @@ -1544,15 +1549,15 @@ where debug!(target: "engine::tree", ?last_persisted_number, ?canonical_head_number, ?target_number, ?current_hash, "Returning canonical blocks to persist"); while let Some(block) = self.state.tree_state.blocks_by_hash.get(¤t_hash) { - if block.block.number() <= last_persisted_number { + if block.recovered_block().number() <= last_persisted_number { break; } - if block.block.number() <= target_number { + if block.recovered_block().number() <= target_number { blocks_to_persist.push(block.clone()); } - current_hash = block.block.parent_hash(); + current_hash = block.recovered_block().parent_hash(); } // reverse the order so that the oldest block comes first @@ -1610,8 +1615,7 @@ where let hashed_state = self.provider.hashed_post_state(execution_output.state()); Ok(Some(ExecutedBlock { - block: Arc::new(block), - senders: Arc::new(senders), + recovered_block: Arc::new(RecoveredBlock::new_sealed(block, senders)), trie: updates.clone(), execution_output: Arc::new(execution_output), hashed_state: Arc::new(hashed_state), @@ -2003,7 +2007,7 @@ where let NewCanonicalChain::Reorg { new, old: _ } = chain_update else { return None }; let BlockNumHash { number: new_num, hash: new_hash } = - new.first().map(|block| block.block.num_hash())?; + new.first().map(|block| block.recovered_block().num_hash())?; match new_num.cmp(&self.persistence_state.last_persisted_block.number) { Ordering::Greater => { @@ -2045,8 +2049,8 @@ where // reinsert any missing reorged blocks if let NewCanonicalChain::Reorg { new, old } = &chain_update { - let new_first = new.first().map(|first| first.block.num_hash()); - let old_first = old.first().map(|first| first.block.num_hash()); + let new_first = new.first().map(|first| first.recovered_block().num_hash()); + let old_first = old.first().map(|first| first.recovered_block().num_hash()); trace!(target: "engine::tree", ?new_first, ?old_first, "Reorg detected, new and old first blocks"); self.update_reorg_metrics(old.len()); @@ -2080,8 +2084,13 @@ where /// This reinserts any blocks in the new chain that do not already exist in the tree fn reinsert_reorged_blocks(&mut self, new_chain: Vec>) { for block in new_chain { - if self.state.tree_state.executed_block_by_hash(block.block.hash()).is_none() { - trace!(target: "engine::tree", num=?block.block.number(), hash=?block.block.hash(), "Reinserting block into tree state"); + if self + .state + .tree_state + .executed_block_by_hash(block.recovered_block().hash()) + .is_none() + { + trace!(target: "engine::tree", num=?block.recovered_block().number(), hash=?block.recovered_block().hash(), "Reinserting block into tree state"); self.state.tree_state.insert_executed(block); } } @@ -2464,15 +2473,18 @@ where debug!(target: "engine::tree", ?root_elapsed, block=?sealed_block.num_hash(), "Calculated state root"); let executed: ExecutedBlock = ExecutedBlock { - block: sealed_block.clone(), - senders: Arc::new(block.senders().to_vec()), + recovered_block: Arc::new(RecoveredBlock::new_sealed( + sealed_block.as_ref().clone(), + block.senders().to_vec(), + )), execution_output: Arc::new(ExecutionOutcome::from((output, block_number))), hashed_state: Arc::new(hashed_state), trie: Arc::new(trie_output), }; - if self.state.tree_state.canonical_block_hash() == executed.block().parent_hash() { - debug!(target: "engine::tree", pending = ?executed.block().num_hash() ,"updating pending block"); + if self.state.tree_state.canonical_block_hash() == executed.recovered_block().parent_hash() + { + debug!(target: "engine::tree", pending = ?executed.recovered_block().num_hash() ,"updating pending block"); // if the parent is the canonical head, we can insert the block as the pending block self.canonical_in_memory_state.set_pending_block(executed.clone()); } @@ -2988,7 +3000,7 @@ mod tests { let mut parent_hash = B256::ZERO; for block in &blocks { - let sealed_block = block.block(); + let sealed_block = block.recovered_block(); let hash = sealed_block.hash(); let number = sealed_block.number; blocks_by_hash.insert(hash, block.clone()); @@ -3002,7 +3014,7 @@ mod tests { self.tree.state.tree_state = TreeState { blocks_by_hash, blocks_by_number, - current_canonical_head: blocks.last().unwrap().block().num_hash(), + current_canonical_head: blocks.last().unwrap().recovered_block().num_hash(), parent_to_child, persisted_trie_updates: HashMap::default(), }; @@ -3013,12 +3025,11 @@ mod tests { CanonicalInMemoryState::new(state_by_hash, hash_by_number, pending, None, None); self.blocks = blocks.clone(); - self.persist_blocks( - blocks - .into_iter() - .map(|b| RecoveredBlock::new_sealed(b.block().clone(), b.senders().clone())) - .collect(), - ); + + let recovered_blocks = + blocks.iter().map(|b| b.recovered_block().clone()).collect::>(); + + self.persist_blocks(recovered_blocks); self } @@ -3311,7 +3322,7 @@ mod tests { let test_harness = TestHarness::new(MAINNET.clone()).with_blocks(blocks.clone()); for executed_block in blocks { - let sealed_block = executed_block.block(); + let sealed_block = executed_block.recovered_block(); let expected_state = BlockState::new(executed_block.clone()); @@ -3441,21 +3452,21 @@ mod tests { tree_state.insert_executed(blocks[1].clone()); assert_eq!( - tree_state.parent_to_child.get(&blocks[0].block.hash()), - Some(&HashSet::from_iter([blocks[1].block.hash()])) + tree_state.parent_to_child.get(&blocks[0].recovered_block().hash()), + Some(&HashSet::from_iter([blocks[1].recovered_block().hash()])) ); - assert!(!tree_state.parent_to_child.contains_key(&blocks[1].block.hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[1].recovered_block().hash())); tree_state.insert_executed(blocks[2].clone()); assert_eq!( - tree_state.parent_to_child.get(&blocks[1].block.hash()), - Some(&HashSet::from_iter([blocks[2].block.hash()])) + tree_state.parent_to_child.get(&blocks[1].recovered_block().hash()), + Some(&HashSet::from_iter([blocks[2].recovered_block().hash()])) ); - assert!(tree_state.parent_to_child.contains_key(&blocks[1].block.hash())); + assert!(tree_state.parent_to_child.contains_key(&blocks[1].recovered_block().hash())); - assert!(!tree_state.parent_to_child.contains_key(&blocks[2].block.hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[2].recovered_block().hash())); } #[tokio::test] @@ -3469,12 +3480,12 @@ mod tests { } assert_eq!(tree_state.blocks_by_hash.len(), 5); - let fork_block_3 = - test_block_builder.get_executed_block_with_number(3, blocks[1].block.hash()); - let fork_block_4 = - test_block_builder.get_executed_block_with_number(4, fork_block_3.block.hash()); - let fork_block_5 = - test_block_builder.get_executed_block_with_number(5, fork_block_4.block.hash()); + let fork_block_3 = test_block_builder + .get_executed_block_with_number(3, blocks[1].recovered_block().hash()); + let fork_block_4 = test_block_builder + .get_executed_block_with_number(4, fork_block_3.recovered_block().hash()); + let fork_block_5 = test_block_builder + .get_executed_block_with_number(5, fork_block_4.recovered_block().hash()); tree_state.insert_executed(fork_block_3.clone()); tree_state.insert_executed(fork_block_4.clone()); @@ -3482,16 +3493,16 @@ mod tests { assert_eq!(tree_state.blocks_by_hash.len(), 8); assert_eq!(tree_state.blocks_by_number[&3].len(), 2); // two blocks at height 3 (original and fork) - assert_eq!(tree_state.parent_to_child[&blocks[1].block.hash()].len(), 2); // block 2 should have two children + assert_eq!(tree_state.parent_to_child[&blocks[1].recovered_block().hash()].len(), 2); // block 2 should have two children // verify that we can insert the same block again without issues tree_state.insert_executed(fork_block_4.clone()); assert_eq!(tree_state.blocks_by_hash.len(), 8); - assert!(tree_state.parent_to_child[&fork_block_3.block.hash()] - .contains(&fork_block_4.block.hash())); - assert!(tree_state.parent_to_child[&fork_block_4.block.hash()] - .contains(&fork_block_5.block.hash())); + assert!(tree_state.parent_to_child[&fork_block_3.recovered_block().hash()] + .contains(&fork_block_4.recovered_block().hash())); + assert!(tree_state.parent_to_child[&fork_block_4.recovered_block().hash()] + .contains(&fork_block_5.recovered_block().hash())); assert_eq!(tree_state.blocks_by_number[&4].len(), 2); assert_eq!(tree_state.blocks_by_number[&5].len(), 2); @@ -3510,40 +3521,40 @@ mod tests { let last = blocks.last().unwrap(); // set the canonical head - tree_state.set_canonical_head(last.block.num_hash()); + tree_state.set_canonical_head(last.recovered_block().num_hash()); // inclusive bound, so we should remove anything up to and including 2 tree_state.remove_until( - BlockNumHash::new(2, blocks[1].block.hash()), + BlockNumHash::new(2, blocks[1].recovered_block().hash()), start_num_hash.hash, - Some(blocks[1].block.num_hash()), + Some(blocks[1].recovered_block().num_hash()), ); - assert!(!tree_state.blocks_by_hash.contains_key(&blocks[0].block.hash())); - assert!(!tree_state.blocks_by_hash.contains_key(&blocks[1].block.hash())); + assert!(!tree_state.blocks_by_hash.contains_key(&blocks[0].recovered_block().hash())); + assert!(!tree_state.blocks_by_hash.contains_key(&blocks[1].recovered_block().hash())); assert!(!tree_state.blocks_by_number.contains_key(&1)); assert!(!tree_state.blocks_by_number.contains_key(&2)); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[2].block.hash())); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[3].block.hash())); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[4].block.hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[2].recovered_block().hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[3].recovered_block().hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[4].recovered_block().hash())); assert!(tree_state.blocks_by_number.contains_key(&3)); assert!(tree_state.blocks_by_number.contains_key(&4)); assert!(tree_state.blocks_by_number.contains_key(&5)); - assert!(!tree_state.parent_to_child.contains_key(&blocks[0].block.hash())); - assert!(!tree_state.parent_to_child.contains_key(&blocks[1].block.hash())); - assert!(tree_state.parent_to_child.contains_key(&blocks[2].block.hash())); - assert!(tree_state.parent_to_child.contains_key(&blocks[3].block.hash())); - assert!(!tree_state.parent_to_child.contains_key(&blocks[4].block.hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[0].recovered_block().hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[1].recovered_block().hash())); + assert!(tree_state.parent_to_child.contains_key(&blocks[2].recovered_block().hash())); + assert!(tree_state.parent_to_child.contains_key(&blocks[3].recovered_block().hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[4].recovered_block().hash())); assert_eq!( - tree_state.parent_to_child.get(&blocks[2].block.hash()), - Some(&HashSet::from_iter([blocks[3].block.hash()])) + tree_state.parent_to_child.get(&blocks[2].recovered_block().hash()), + Some(&HashSet::from_iter([blocks[3].recovered_block().hash()])) ); assert_eq!( - tree_state.parent_to_child.get(&blocks[3].block.hash()), - Some(&HashSet::from_iter([blocks[4].block.hash()])) + tree_state.parent_to_child.get(&blocks[3].recovered_block().hash()), + Some(&HashSet::from_iter([blocks[4].recovered_block().hash()])) ); } @@ -3560,40 +3571,40 @@ mod tests { let last = blocks.last().unwrap(); // set the canonical head - tree_state.set_canonical_head(last.block.num_hash()); + tree_state.set_canonical_head(last.recovered_block().num_hash()); // we should still remove everything up to and including 2 tree_state.remove_until( - BlockNumHash::new(2, blocks[1].block.hash()), + BlockNumHash::new(2, blocks[1].recovered_block().hash()), start_num_hash.hash, None, ); - assert!(!tree_state.blocks_by_hash.contains_key(&blocks[0].block.hash())); - assert!(!tree_state.blocks_by_hash.contains_key(&blocks[1].block.hash())); + assert!(!tree_state.blocks_by_hash.contains_key(&blocks[0].recovered_block().hash())); + assert!(!tree_state.blocks_by_hash.contains_key(&blocks[1].recovered_block().hash())); assert!(!tree_state.blocks_by_number.contains_key(&1)); assert!(!tree_state.blocks_by_number.contains_key(&2)); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[2].block.hash())); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[3].block.hash())); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[4].block.hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[2].recovered_block().hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[3].recovered_block().hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[4].recovered_block().hash())); assert!(tree_state.blocks_by_number.contains_key(&3)); assert!(tree_state.blocks_by_number.contains_key(&4)); assert!(tree_state.blocks_by_number.contains_key(&5)); - assert!(!tree_state.parent_to_child.contains_key(&blocks[0].block.hash())); - assert!(!tree_state.parent_to_child.contains_key(&blocks[1].block.hash())); - assert!(tree_state.parent_to_child.contains_key(&blocks[2].block.hash())); - assert!(tree_state.parent_to_child.contains_key(&blocks[3].block.hash())); - assert!(!tree_state.parent_to_child.contains_key(&blocks[4].block.hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[0].recovered_block().hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[1].recovered_block().hash())); + assert!(tree_state.parent_to_child.contains_key(&blocks[2].recovered_block().hash())); + assert!(tree_state.parent_to_child.contains_key(&blocks[3].recovered_block().hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[4].recovered_block().hash())); assert_eq!( - tree_state.parent_to_child.get(&blocks[2].block.hash()), - Some(&HashSet::from_iter([blocks[3].block.hash()])) + tree_state.parent_to_child.get(&blocks[2].recovered_block().hash()), + Some(&HashSet::from_iter([blocks[3].recovered_block().hash()])) ); assert_eq!( - tree_state.parent_to_child.get(&blocks[3].block.hash()), - Some(&HashSet::from_iter([blocks[4].block.hash()])) + tree_state.parent_to_child.get(&blocks[3].recovered_block().hash()), + Some(&HashSet::from_iter([blocks[4].recovered_block().hash()])) ); } @@ -3610,40 +3621,40 @@ mod tests { let last = blocks.last().unwrap(); // set the canonical head - tree_state.set_canonical_head(last.block.num_hash()); + tree_state.set_canonical_head(last.recovered_block().num_hash()); // we have no forks so we should still remove anything up to and including 2 tree_state.remove_until( - BlockNumHash::new(2, blocks[1].block.hash()), + BlockNumHash::new(2, blocks[1].recovered_block().hash()), start_num_hash.hash, - Some(blocks[0].block.num_hash()), + Some(blocks[0].recovered_block().num_hash()), ); - assert!(!tree_state.blocks_by_hash.contains_key(&blocks[0].block.hash())); - assert!(!tree_state.blocks_by_hash.contains_key(&blocks[1].block.hash())); + assert!(!tree_state.blocks_by_hash.contains_key(&blocks[0].recovered_block().hash())); + assert!(!tree_state.blocks_by_hash.contains_key(&blocks[1].recovered_block().hash())); assert!(!tree_state.blocks_by_number.contains_key(&1)); assert!(!tree_state.blocks_by_number.contains_key(&2)); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[2].block.hash())); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[3].block.hash())); - assert!(tree_state.blocks_by_hash.contains_key(&blocks[4].block.hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[2].recovered_block().hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[3].recovered_block().hash())); + assert!(tree_state.blocks_by_hash.contains_key(&blocks[4].recovered_block().hash())); assert!(tree_state.blocks_by_number.contains_key(&3)); assert!(tree_state.blocks_by_number.contains_key(&4)); assert!(tree_state.blocks_by_number.contains_key(&5)); - assert!(!tree_state.parent_to_child.contains_key(&blocks[0].block.hash())); - assert!(!tree_state.parent_to_child.contains_key(&blocks[1].block.hash())); - assert!(tree_state.parent_to_child.contains_key(&blocks[2].block.hash())); - assert!(tree_state.parent_to_child.contains_key(&blocks[3].block.hash())); - assert!(!tree_state.parent_to_child.contains_key(&blocks[4].block.hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[0].recovered_block().hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[1].recovered_block().hash())); + assert!(tree_state.parent_to_child.contains_key(&blocks[2].recovered_block().hash())); + assert!(tree_state.parent_to_child.contains_key(&blocks[3].recovered_block().hash())); + assert!(!tree_state.parent_to_child.contains_key(&blocks[4].recovered_block().hash())); assert_eq!( - tree_state.parent_to_child.get(&blocks[2].block.hash()), - Some(&HashSet::from_iter([blocks[3].block.hash()])) + tree_state.parent_to_child.get(&blocks[2].recovered_block().hash()), + Some(&HashSet::from_iter([blocks[3].recovered_block().hash()])) ); assert_eq!( - tree_state.parent_to_child.get(&blocks[3].block.hash()), - Some(&HashSet::from_iter([blocks[4].block.hash()])) + tree_state.parent_to_child.get(&blocks[3].recovered_block().hash()), + Some(&HashSet::from_iter([blocks[4].recovered_block().hash()])) ); } @@ -3660,40 +3671,44 @@ mod tests { } // set block 3 as the current canonical head - test_harness.tree.state.tree_state.set_canonical_head(blocks[2].block.num_hash()); + test_harness + .tree + .state + .tree_state + .set_canonical_head(blocks[2].recovered_block().num_hash()); // create a fork from block 2 - let fork_block_3 = - test_block_builder.get_executed_block_with_number(3, blocks[1].block.hash()); - let fork_block_4 = - test_block_builder.get_executed_block_with_number(4, fork_block_3.block.hash()); - let fork_block_5 = - test_block_builder.get_executed_block_with_number(5, fork_block_4.block.hash()); + let fork_block_3 = test_block_builder + .get_executed_block_with_number(3, blocks[1].recovered_block().hash()); + let fork_block_4 = test_block_builder + .get_executed_block_with_number(4, fork_block_3.recovered_block().hash()); + let fork_block_5 = test_block_builder + .get_executed_block_with_number(5, fork_block_4.recovered_block().hash()); test_harness.tree.state.tree_state.insert_executed(fork_block_3.clone()); test_harness.tree.state.tree_state.insert_executed(fork_block_4.clone()); test_harness.tree.state.tree_state.insert_executed(fork_block_5.clone()); // normal (non-reorg) case - let result = test_harness.tree.on_new_head(blocks[4].block.hash()).unwrap(); + let result = test_harness.tree.on_new_head(blocks[4].recovered_block().hash()).unwrap(); assert!(matches!(result, Some(NewCanonicalChain::Commit { .. }))); if let Some(NewCanonicalChain::Commit { new }) = result { assert_eq!(new.len(), 2); - assert_eq!(new[0].block.hash(), blocks[3].block.hash()); - assert_eq!(new[1].block.hash(), blocks[4].block.hash()); + assert_eq!(new[0].recovered_block().hash(), blocks[3].recovered_block().hash()); + assert_eq!(new[1].recovered_block().hash(), blocks[4].recovered_block().hash()); } // reorg case - let result = test_harness.tree.on_new_head(fork_block_5.block.hash()).unwrap(); + let result = test_harness.tree.on_new_head(fork_block_5.recovered_block().hash()).unwrap(); assert!(matches!(result, Some(NewCanonicalChain::Reorg { .. }))); if let Some(NewCanonicalChain::Reorg { new, old }) = result { assert_eq!(new.len(), 3); - assert_eq!(new[0].block.hash(), fork_block_3.block.hash()); - assert_eq!(new[1].block.hash(), fork_block_4.block.hash()); - assert_eq!(new[2].block.hash(), fork_block_5.block.hash()); + assert_eq!(new[0].recovered_block().hash(), fork_block_3.recovered_block().hash()); + assert_eq!(new[1].recovered_block().hash(), fork_block_4.recovered_block().hash()); + assert_eq!(new[2].recovered_block().hash(), fork_block_5.recovered_block().hash()); assert_eq!(old.len(), 1); - assert_eq!(old[0].block.hash(), blocks[2].block.hash()); + assert_eq!(old[0].recovered_block().hash(), blocks[2].recovered_block().hash()); } } @@ -3712,7 +3727,7 @@ mod tests { } // set last block as the current canonical head - let last_block = blocks.last().unwrap().block.clone(); + let last_block = blocks.last().unwrap().recovered_block().clone(); test_harness.tree.state.tree_state.set_canonical_head(last_block.num_hash()); @@ -3722,8 +3737,7 @@ mod tests { for block in &chain_a { test_harness.tree.state.tree_state.insert_executed(ExecutedBlock { - block: Arc::new(block.clone_sealed_block()), - senders: Arc::new(block.senders().to_vec()), + recovered_block: Arc::new(block.clone()), execution_output: Arc::new(ExecutionOutcome::default()), hashed_state: Arc::new(HashedPostState::default()), trie: Arc::new(TrieUpdates::default()), @@ -3733,8 +3747,7 @@ mod tests { for block in &chain_b { test_harness.tree.state.tree_state.insert_executed(ExecutedBlock { - block: Arc::new(block.clone_sealed_block()), - senders: Arc::new(block.senders().to_vec()), + recovered_block: Arc::new(block.clone()), execution_output: Arc::new(ExecutionOutcome::default()), hashed_state: Arc::new(HashedPostState::default()), trie: Arc::new(TrieUpdates::default()), @@ -3752,12 +3765,12 @@ mod tests { if let Some(NewCanonicalChain::Reorg { new, old }) = result { assert_eq!(new.len(), expected_new.len()); for (index, block) in expected_new.iter().enumerate() { - assert_eq!(new[index].block.hash(), block.hash()); + assert_eq!(new[index].recovered_block().hash(), block.hash()); } assert_eq!(old.len(), chain_a.len()); for (index, block) in chain_a.iter().enumerate() { - assert_eq!(old[index].block.hash(), block.hash()); + assert_eq!(old[index].recovered_block().hash(), block.hash()); } } @@ -3798,12 +3811,12 @@ mod tests { for (i, item) in blocks_to_persist.iter().enumerate().take(expected_blocks_to_persist_length) { - assert_eq!(item.block.number, last_persisted_block_number + i as u64 + 1); + assert_eq!(item.recovered_block().number, last_persisted_block_number + i as u64 + 1); } // make sure only canonical blocks are included let fork_block = test_block_builder.get_executed_block_with_number(4, B256::random()); - let fork_block_hash = fork_block.block.hash(); + let fork_block_hash = fork_block.recovered_block().hash(); test_harness.tree.state.tree_state.insert_executed(fork_block); assert!(test_harness.tree.state.tree_state.block_by_hash(fork_block_hash).is_some()); @@ -3812,12 +3825,11 @@ mod tests { assert_eq!(blocks_to_persist.len(), expected_blocks_to_persist_length); // check that the fork block is not included in the blocks to persist - assert!(!blocks_to_persist.iter().any(|b| b.block.hash() == fork_block_hash)); + assert!(!blocks_to_persist.iter().any(|b| b.recovered_block().hash() == fork_block_hash)); // check that the original block 4 is still included - assert!(blocks_to_persist - .iter() - .any(|b| b.block.number == 4 && b.block.hash() == blocks[4].block.hash())); + assert!(blocks_to_persist.iter().any(|b| b.recovered_block().number == 4 && + b.recovered_block().hash() == blocks[4].recovered_block().hash())); } #[tokio::test] @@ -3831,7 +3843,7 @@ mod tests { test_harness = test_harness.with_blocks(blocks); let missing_block = test_block_builder - .generate_random_block(6, test_harness.blocks.last().unwrap().block().hash()); + .generate_random_block(6, test_harness.blocks.last().unwrap().recovered_block().hash()); test_harness.fcu_to(missing_block.hash(), PayloadStatusEnum::Syncing).await; @@ -3855,11 +3867,11 @@ mod tests { test_harness = test_harness.with_blocks(base_chain.clone()); test_harness - .fcu_to(base_chain.last().unwrap().block().hash(), ForkchoiceStatus::Valid) + .fcu_to(base_chain.last().unwrap().recovered_block().hash(), ForkchoiceStatus::Valid) .await; // extend main chain - let main_chain = test_harness.block_builder.create_fork(base_chain[0].block(), 3); + let main_chain = test_harness.block_builder.create_fork(base_chain[0].recovered_block(), 3); test_harness.insert_chain(main_chain).await; } @@ -3872,7 +3884,7 @@ mod tests { let main_chain: Vec<_> = test_harness.block_builder.get_executed_blocks(0..5).collect(); test_harness = test_harness.with_blocks(main_chain.clone()); - let fork_chain = test_harness.block_builder.create_fork(main_chain[2].block(), 3); + let fork_chain = test_harness.block_builder.create_fork(main_chain[2].recovered_block(), 3); let fork_chain_last_hash = fork_chain.last().unwrap().hash(); // add fork blocks to the tree @@ -3905,13 +3917,13 @@ mod tests { test_harness = test_harness.with_blocks(base_chain.clone()); test_harness - .fcu_to(base_chain.last().unwrap().block().hash(), ForkchoiceStatus::Valid) + .fcu_to(base_chain.last().unwrap().recovered_block().hash(), ForkchoiceStatus::Valid) .await; // extend main chain with enough blocks to trigger pipeline run but don't insert them let main_chain = test_harness .block_builder - .create_fork(base_chain[0].block(), MIN_BLOCKS_FOR_PIPELINE_RUN + 10); + .create_fork(base_chain[0].recovered_block(), MIN_BLOCKS_FOR_PIPELINE_RUN + 10); let main_chain_last_hash = main_chain.last().unwrap().hash(); test_harness.send_fcu(main_chain_last_hash, ForkchoiceStatus::Syncing).await; @@ -3972,14 +3984,14 @@ mod tests { // fcu to the tip of base chain test_harness - .fcu_to(base_chain.last().unwrap().block().hash(), ForkchoiceStatus::Valid) + .fcu_to(base_chain.last().unwrap().recovered_block().hash(), ForkchoiceStatus::Valid) .await; // create main chain, extension of base chain, with enough blocks to // trigger backfill sync let main_chain = test_harness .block_builder - .create_fork(base_chain[0].block(), MIN_BLOCKS_FOR_PIPELINE_RUN + 10); + .create_fork(base_chain[0].recovered_block(), MIN_BLOCKS_FOR_PIPELINE_RUN + 10); let main_chain_last = main_chain.last().unwrap(); let main_chain_last_hash = main_chain_last.hash(); @@ -4099,11 +4111,12 @@ mod tests { // fcu to the tip of base chain test_harness - .fcu_to(base_chain.last().unwrap().block().hash(), ForkchoiceStatus::Valid) + .fcu_to(base_chain.last().unwrap().recovered_block().hash(), ForkchoiceStatus::Valid) .await; // create main chain, extension of base chain - let main_chain = test_harness.block_builder.create_fork(base_chain[0].block(), 10); + let main_chain = + test_harness.block_builder.create_fork(base_chain[0].recovered_block(), 10); // determine target in the middle of main hain let target = main_chain.get(5).unwrap(); let target_hash = target.hash(); @@ -4138,7 +4151,7 @@ mod tests { let base_chain: Vec<_> = test_harness.block_builder.get_executed_blocks(0..1).collect(); test_harness = test_harness.with_blocks(base_chain.clone()); - let old_head = base_chain.first().unwrap().block(); + let old_head = base_chain.first().unwrap().recovered_block(); // extend base chain let extension_chain = test_harness.block_builder.create_fork(old_head, 5); @@ -4198,7 +4211,7 @@ mod tests { // side chain consisting of two blocks, the last will be inserted first // so that we force it to be buffered let side_chain = - test_harness.block_builder.create_fork(base_chain.last().unwrap().block(), 2); + test_harness.block_builder.create_fork(base_chain.last().unwrap().recovered_block(), 2); // buffer last block of side chain let buffered_block = side_chain.last().unwrap(); @@ -4236,7 +4249,7 @@ mod tests { let base_chain: Vec<_> = test_harness.block_builder.get_executed_blocks(0..1).collect(); test_harness = test_harness.with_blocks(base_chain.clone()); - let old_head = base_chain.first().unwrap().block(); + let old_head = base_chain.first().unwrap().recovered_block(); // extend base chain let extension_chain = test_harness.block_builder.create_fork(old_head, 5); @@ -4300,8 +4313,9 @@ mod tests { test_harness = test_harness.with_blocks(base_chain.clone()); // create a side chain with an invalid block - let side_chain = - test_harness.block_builder.create_fork(base_chain.last().unwrap().block(), 15); + let side_chain = test_harness + .block_builder + .create_fork(base_chain.last().unwrap().recovered_block(), 15); let invalid_index = 9; test_harness.setup_range_insertion_for_invalid_chain(side_chain.clone(), invalid_index); diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 4f5fe530161a..3480e9bcb1b9 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -30,7 +30,8 @@ use reth_payload_builder_primitives::PayloadBuilderError; use reth_payload_primitives::PayloadBuilderAttributes; use reth_primitives::{ proofs::{self}, - Block, BlockBody, EthereumHardforks, InvalidTransactionError, Receipt, TransactionSigned, + Block, BlockBody, EthereumHardforks, InvalidTransactionError, Receipt, RecoveredBlock, + TransactionSigned, }; use reth_primitives_traits::Block as _; use reth_revm::database::StateProviderDatabase; @@ -494,8 +495,10 @@ where // create the executed block data let executed = ExecutedBlock { - block: sealed_block.clone(), - senders: Arc::new(executed_senders), + recovered_block: Arc::new(RecoveredBlock::new_sealed( + sealed_block.as_ref().clone(), + executed_senders, + )), execution_output: Arc::new(execution_outcome), hashed_state: Arc::new(hashed_state), trie: Arc::new(trie_output), diff --git a/crates/node/builder/src/launch/engine.rs b/crates/node/builder/src/launch/engine.rs index 31968197d818..b008b00d2020 100644 --- a/crates/node/builder/src/launch/engine.rs +++ b/crates/node/builder/src/launch/engine.rs @@ -344,7 +344,7 @@ where tokio::select! { payload = built_payloads.select_next_some() => { if let Some(executed_block) = payload.executed_block() { - debug!(target: "reth::cli", block=?executed_block.block().num_hash(), "inserting built payload"); + debug!(target: "reth::cli", block=?executed_block.recovered_block().num_hash(), "inserting built payload"); if let Either::Right(eth_service) = &mut engine_service { eth_service.orchestrator_mut().handler_mut().handler_mut().on_event(EngineApiRequest::InsertExecutedBlock(executed_block).into()); } diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 505843370a14..817660690c5e 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -25,7 +25,8 @@ use reth_payload_builder_primitives::PayloadBuilderError; use reth_payload_primitives::PayloadBuilderAttributes; use reth_payload_util::{NoopPayloadTransactions, PayloadTransactions}; use reth_primitives::{ - proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, SealedHeader, TxType, + proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, RecoveredBlock, + SealedHeader, TxType, }; use reth_primitives_traits::block::Block as _; use reth_provider::{ @@ -438,8 +439,10 @@ where // create the executed block data let executed: ExecutedBlock = ExecutedBlock { - block: sealed_block.clone(), - senders: Arc::new(info.executed_senders), + recovered_block: Arc::new(RecoveredBlock::new_sealed( + sealed_block.as_ref().clone(), + info.executed_senders, + )), execution_output: Arc::new(execution_outcome), hashed_state: Arc::new(hashed_state), trie: Arc::new(trie_output), diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 707ce2212a81..934f28711288 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -792,7 +792,7 @@ mod tests { use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_errors::ProviderError; use reth_execution_types::{Chain, ExecutionOutcome}; - use reth_primitives::{EthPrimitives, Receipt, SealedBlock, StaticFileSegment}; + use reth_primitives::{EthPrimitives, Receipt, RecoveredBlock, SealedBlock, StaticFileSegment}; use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_storage_api::{ BlockBodyIndicesProvider, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, @@ -925,8 +925,7 @@ mod tests { ExecutionOutcome { receipts: block_receipts.into(), ..Default::default() }; ExecutedBlock::new( - Arc::new(block.clone()), - Arc::new(senders), + Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)), execution_outcome.into(), Default::default(), Default::default(), @@ -987,10 +986,10 @@ mod tests { if state.anchor().number + 1 == block_number { let mut lowest_memory_block = state.parent_state_chain().last().expect("qed").block(); - let num_hash = lowest_memory_block.block().num_hash(); + let num_hash = lowest_memory_block.recovered_block().num_hash(); let mut execution_output = (*lowest_memory_block.execution_output).clone(); - execution_output.first_block = lowest_memory_block.block().number; + execution_output.first_block = lowest_memory_block.recovered_block().number; lowest_memory_block.execution_output = Arc::new(execution_output); // Push to disk @@ -1055,8 +1054,10 @@ mod tests { first_in_mem_block.senders().expect("failed to recover senders"); let chain = NewCanonicalChain::Commit { new: vec![ExecutedBlock::new( - Arc::new(first_in_mem_block.clone()), - Arc::new(in_memory_block_senders), + Arc::new(RecoveredBlock::new_sealed( + first_in_mem_block.clone(), + in_memory_block_senders, + )), Default::default(), Default::default(), Default::default(), @@ -1089,8 +1090,10 @@ mod tests { // Insert the last block into the pending state provider.canonical_in_memory_state.set_pending_block(ExecutedBlock { - block: Arc::new(last_in_mem_block.clone()), - senders: Default::default(), + recovered_block: Arc::new(RecoveredBlock::new_sealed( + last_in_mem_block.clone(), + Default::default(), + )), execution_output: Default::default(), hashed_state: Default::default(), trie: Default::default(), @@ -1145,8 +1148,10 @@ mod tests { first_in_mem_block.senders().expect("failed to recover senders"); let chain = NewCanonicalChain::Commit { new: vec![ExecutedBlock::new( - Arc::new(first_in_mem_block.clone()), - Arc::new(in_memory_block_senders), + Arc::new(RecoveredBlock::new_sealed( + first_in_mem_block.clone(), + in_memory_block_senders, + )), Default::default(), Default::default(), Default::default(), @@ -1197,8 +1202,10 @@ mod tests { // Set the block as pending provider.canonical_in_memory_state.set_pending_block(ExecutedBlock { - block: Arc::new(block.clone()), - senders: Default::default(), + recovered_block: Arc::new(RecoveredBlock::new_sealed( + block.clone(), + Default::default(), + )), execution_output: Default::default(), hashed_state: Default::default(), trie: Default::default(), @@ -1278,8 +1285,10 @@ mod tests { first_in_mem_block.senders().expect("failed to recover senders"); let chain = NewCanonicalChain::Commit { new: vec![ExecutedBlock::new( - Arc::new(first_in_mem_block.clone()), - Arc::new(in_memory_block_senders), + Arc::new(RecoveredBlock::new_sealed( + first_in_mem_block.clone(), + in_memory_block_senders, + )), Default::default(), Default::default(), Default::default(), @@ -1841,8 +1850,7 @@ mod tests { .map(|block| { let senders = block.senders().expect("failed to recover senders"); ExecutedBlock::new( - Arc::new(block.clone()), - Arc::new(senders), + Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)), Arc::new(ExecutionOutcome { bundle: BundleState::new( in_memory_state.into_iter().map(|(address, (account, _))| { @@ -1977,8 +1985,10 @@ mod tests { // adding a pending block to state can test pending() and pending_state_by_hash() function let pending_block = database_blocks[database_blocks.len() - 1].clone(); only_database_provider.canonical_in_memory_state.set_pending_block(ExecutedBlock { - block: Arc::new(pending_block.clone()), - senders: Default::default(), + recovered_block: Arc::new(RecoveredBlock::new_sealed( + pending_block.clone(), + Default::default(), + )), execution_output: Default::default(), hashed_state: Default::default(), trie: Default::default(), @@ -2098,8 +2108,10 @@ mod tests { // Set the pending block in memory let pending_block = in_memory_blocks.last().unwrap(); provider.canonical_in_memory_state.set_pending_block(ExecutedBlock { - block: Arc::new(pending_block.clone()), - senders: Default::default(), + recovered_block: Arc::new(RecoveredBlock::new_sealed( + pending_block.clone(), + Default::default(), + )), execution_output: Default::default(), hashed_state: Default::default(), trie: Default::default(), diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 1417be828f8b..df1d055ebd9c 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -442,7 +442,7 @@ impl ConsistentProvider { let (start, end) = self.convert_range_bounds(range, || { in_mem_chain .iter() - .map(|b| b.block_ref().block().body().transactions().len() as u64) + .map(|b| b.block_ref().recovered_block().body().transactions().len() as u64) .sum::() + last_block_body_index.last_tx_num() }); @@ -474,7 +474,8 @@ impl ConsistentProvider { // Iterate from the lowest block to the highest in-memory chain for block_state in in_mem_chain.iter().rev() { - let block_tx_count = block_state.block_ref().block().body().transactions().len(); + let block_tx_count = + block_state.block_ref().recovered_block().body().transactions().len(); let remaining = (tx_range.end() - tx_range.start() + 1) as usize; // If the transaction range start is equal or higher than the next block first @@ -546,7 +547,7 @@ impl ConsistentProvider { // Iterate from the lowest block to the highest for block_state in in_mem_chain.iter().rev() { let executed_block = block_state.block_ref(); - let block = executed_block.block(); + let block = executed_block.recovered_block(); for tx_index in 0..block.body().transactions().len() { match id { @@ -629,7 +630,7 @@ impl HeaderProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block( (*block_hash).into(), |db_provider| db_provider.header(block_hash), - |block_state| Ok(Some(block_state.block_ref().block().header().clone())), + |block_state| Ok(Some(block_state.block_ref().recovered_block().header().clone())), ) } @@ -637,7 +638,7 @@ impl HeaderProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block( num.into(), |db_provider| db_provider.header_by_number(num), - |block_state| Ok(Some(block_state.block_ref().block().header().clone())), + |block_state| Ok(Some(block_state.block_ref().recovered_block().header().clone())), ) } @@ -679,7 +680,7 @@ impl HeaderProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.headers_range(range), - |block_state, _| Some(block_state.block_ref().block().header().clone()), + |block_state, _| Some(block_state.block_ref().recovered_block().header().clone()), |_| true, ) } @@ -691,7 +692,7 @@ impl HeaderProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block( number.into(), |db_provider| db_provider.sealed_header(number), - |block_state| Ok(Some(block_state.block_ref().block().clone_sealed_header())), + |block_state| Ok(Some(block_state.block_ref().recovered_block().clone_sealed_header())), ) } @@ -702,7 +703,7 @@ impl HeaderProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.sealed_headers_range(range), - |block_state, _| Some(block_state.block_ref().block().clone_sealed_header()), + |block_state, _| Some(block_state.block_ref().recovered_block().clone_sealed_header()), |_| true, ) } @@ -716,7 +717,7 @@ impl HeaderProvider for ConsistentProvider { range, |db_provider, range, predicate| db_provider.sealed_headers_while(range, predicate), |block_state, predicate| { - let header = block_state.block_ref().block().sealed_header(); + let header = block_state.block_ref().recovered_block().sealed_header(); predicate(header).then(|| header.clone()) }, predicate, @@ -802,7 +803,7 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block( hash.into(), |db_provider| db_provider.find_block_by_hash(hash, source), - |block_state| Ok(Some(block_state.block_ref().block().clone_block())), + |block_state| Ok(Some(block_state.block_ref().recovered_block().clone_block())), ) } BlockSource::Pending => { @@ -815,7 +816,7 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.block(id), - |block_state| Ok(Some(block_state.block_ref().block().clone_block())), + |block_state| Ok(Some(block_state.block_ref().recovered_block().clone_block())), ) } @@ -847,7 +848,7 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.block_with_senders(id, transaction_kind), - |block_state| Ok(Some(block_state.clone_recovered_block())), + |block_state| Ok(Some(block_state.block().recovered_block().clone())), ) } @@ -859,7 +860,7 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.sealed_block_with_senders(id, transaction_kind), - |block_state| Ok(Some(block_state.clone_recovered_block())), + |block_state| Ok(Some(block_state.block().recovered_block().clone())), ) } @@ -867,7 +868,7 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.block_range(range), - |block_state, _| Some(block_state.block_ref().block().clone_block()), + |block_state, _| Some(block_state.block_ref().recovered_block().clone_block()), |_| true, ) } @@ -879,7 +880,7 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.block_with_senders_range(range), - |block_state, _| Some(block_state.clone_recovered_block()), + |block_state, _| Some(block_state.block().recovered_block().clone()), |_| true, ) } @@ -891,7 +892,7 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.sealed_block_with_senders_range(range), - |block_state, _| Some(block_state.clone_recovered_block()), + |block_state, _| Some(block_state.block().recovered_block().clone()), |_| true, ) } @@ -913,7 +914,13 @@ impl TransactionsProvider for ConsistentProvider { id.into(), |provider| provider.transaction_by_id(id), |tx_index, _, block_state| { - Ok(block_state.block_ref().block().body().transactions().get(tx_index).cloned()) + Ok(block_state + .block_ref() + .recovered_block() + .body() + .transactions() + .get(tx_index) + .cloned()) }, ) } @@ -926,7 +933,13 @@ impl TransactionsProvider for ConsistentProvider { id.into(), |provider| provider.transaction_by_id_unhashed(id), |tx_index, _, block_state| { - Ok(block_state.block_ref().block().body().transactions().get(tx_index).cloned()) + Ok(block_state + .block_ref() + .recovered_block() + .body() + .transactions() + .get(tx_index) + .cloned()) }, ) } @@ -956,7 +969,7 @@ impl TransactionsProvider for ConsistentProvider { self.get_in_memory_or_storage_by_tx( id.into(), |provider| provider.transaction_block(id), - |_, _, block_state| Ok(Some(block_state.block_ref().block().number())), + |_, _, block_state| Ok(Some(block_state.block_ref().recovered_block().number())), ) } @@ -967,7 +980,9 @@ impl TransactionsProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block( id, |provider| provider.transactions_by_block(id), - |block_state| Ok(Some(block_state.block_ref().block().body().transactions().to_vec())), + |block_state| { + Ok(Some(block_state.block_ref().recovered_block().body().transactions().to_vec())) + }, ) } @@ -978,7 +993,9 @@ impl TransactionsProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.transactions_by_block_range(range), - |block_state, _| Some(block_state.block_ref().block().body().transactions().to_vec()), + |block_state, _| { + Some(block_state.block_ref().recovered_block().body().transactions().to_vec()) + }, |_| true, ) } @@ -991,7 +1008,8 @@ impl TransactionsProvider for ConsistentProvider { range, |db_provider, db_range| db_provider.transactions_by_tx_range(db_range), |index_range, block_state| { - Ok(block_state.block_ref().block().body().transactions()[index_range].to_vec()) + Ok(block_state.block_ref().recovered_block().body().transactions()[index_range] + .to_vec()) }, ) } @@ -1003,7 +1021,9 @@ impl TransactionsProvider for ConsistentProvider { self.get_in_memory_or_storage_by_tx_range( range, |db_provider, db_range| db_provider.senders_by_tx_range(db_range), - |index_range, block_state| Ok(block_state.block_ref().senders[index_range].to_vec()), + |index_range, block_state| { + Ok(block_state.block_ref().recovered_block.senders()[index_range].to_vec()) + }, ) } @@ -1011,7 +1031,9 @@ impl TransactionsProvider for ConsistentProvider { self.get_in_memory_or_storage_by_tx( id.into(), |provider| provider.transaction_sender(id), - |tx_index, _, block_state| Ok(block_state.block_ref().senders.get(tx_index).copied()), + |tx_index, _, block_state| { + Ok(block_state.block_ref().recovered_block.senders().get(tx_index).copied()) + }, ) } } @@ -1032,7 +1054,7 @@ impl ReceiptProvider for ConsistentProvider { fn receipt_by_hash(&self, hash: TxHash) -> ProviderResult> { for block_state in self.head_block.iter().flat_map(|b| b.chain()) { let executed_block = block_state.block_ref(); - let block = executed_block.block(); + let block = executed_block.recovered_block(); let receipts = block_state.executed_block_receipts(); // assuming 1:1 correspondence between transactions and receipts @@ -1124,7 +1146,9 @@ impl WithdrawalsProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.withdrawals_by_block(id, timestamp), - |block_state| Ok(block_state.block_ref().block().body().withdrawals().cloned()), + |block_state| { + Ok(block_state.block_ref().recovered_block().body().withdrawals().cloned()) + }, ) } } @@ -1139,7 +1163,7 @@ impl OmmersProvider for ConsistentProvider { return Ok(Some(Vec::new())) } - Ok(block_state.block_ref().block().body().ommers().map(|o| o.to_vec())) + Ok(block_state.block_ref().recovered_block().body().ommers().map(|o| o.to_vec())) }, ) } @@ -1167,8 +1191,9 @@ impl BlockBodyIndicesProvider for ConsistentProvider { // Iterate from the lowest block in memory until our target block for state in block_state.chain().collect::>().into_iter().rev() { - let block_tx_count = state.block_ref().block.body().transactions().len() as u64; - if state.block_ref().block().number() == number { + let block_tx_count = + state.block_ref().recovered_block().body().transactions().len() as u64; + if state.block_ref().recovered_block().number() == number { stored_indices.tx_count = block_tx_count; } else { stored_indices.first_tx_num += block_tx_count; @@ -1450,7 +1475,7 @@ mod tests { use reth_chain_state::{ExecutedBlock, NewCanonicalChain}; use reth_db::models::AccountBeforeTx; use reth_execution_types::ExecutionOutcome; - use reth_primitives::SealedBlock; + use reth_primitives::{RecoveredBlock, SealedBlock}; use reth_storage_api::{BlockReader, BlockSource, ChangeSetReader}; use reth_testing_utils::generators::{ self, random_block_range, random_changeset_range, random_eoa_accounts, BlockRangeParams, @@ -1550,8 +1575,10 @@ mod tests { first_in_mem_block.senders().expect("failed to recover senders"); let chain = NewCanonicalChain::Commit { new: vec![ExecutedBlock::new( - Arc::new(first_in_mem_block.clone()), - Arc::new(in_memory_block_senders), + Arc::new(RecoveredBlock::new_sealed( + first_in_mem_block.clone(), + in_memory_block_senders, + )), Default::default(), Default::default(), Default::default(), @@ -1590,8 +1617,10 @@ mod tests { // Insert the last block into the pending state provider.canonical_in_memory_state.set_pending_block(ExecutedBlock { - block: Arc::new(last_in_mem_block.clone()), - senders: Default::default(), + recovered_block: Arc::new(RecoveredBlock::new_sealed( + last_in_mem_block.clone(), + Default::default(), + )), execution_output: Default::default(), hashed_state: Default::default(), trie: Default::default(), @@ -1654,8 +1683,10 @@ mod tests { first_in_mem_block.senders().expect("failed to recover senders"); let chain = NewCanonicalChain::Commit { new: vec![ExecutedBlock::new( - Arc::new(first_in_mem_block.clone()), - Arc::new(in_memory_block_senders), + Arc::new(RecoveredBlock::new_sealed( + first_in_mem_block.clone(), + in_memory_block_senders, + )), Default::default(), Default::default(), Default::default(), @@ -1758,8 +1789,7 @@ mod tests { .map(|block| { let senders = block.senders().expect("failed to recover senders"); ExecutedBlock::new( - Arc::new(block.clone()), - Arc::new(senders), + Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)), Arc::new(ExecutionOutcome { bundle: BundleState::new( in_memory_state.into_iter().map(|(address, (account, _))| { diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index 022c71f81c44..da6fa25c5193 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -143,9 +143,9 @@ where } // NOTE: checked non-empty above - let first_block = blocks.first().unwrap().block(); + let first_block = blocks.first().unwrap().recovered_block(); - let last_block = blocks.last().unwrap().block(); + let last_block = blocks.last().unwrap().recovered_block(); let first_number = first_block.number(); let last_block_number = last_block.number(); @@ -160,11 +160,9 @@ where // * trie updates (cannot naively extend, need helper) // * indices (already done basically) // Insert the blocks - for ExecutedBlock { block, senders, execution_output, hashed_state, trie } in blocks { - let sealed_block = Arc::unwrap_or_clone(block) - .try_with_senders_unchecked(Arc::unwrap_or_clone(senders)) - .unwrap(); - self.database().insert_block(sealed_block, StorageLocation::Both)?; + for ExecutedBlock { recovered_block, execution_output, hashed_state, trie } in blocks { + self.database() + .insert_block(recovered_block.as_ref().clone(), StorageLocation::Both)?; // Write state and changesets to the database. // Must be written after blocks because of the receipt lookup. From f051ebf040868e774c448b0dd7d0ea98f5ad792d Mon Sep 17 00:00:00 2001 From: voidash Date: Wed, 15 Jan 2025 12:38:40 +0545 Subject: [PATCH 2/3] fix: test_block_reader_pending now passes --- crates/storage/provider/src/providers/blockchain_provider.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 934f28711288..8b8e486e1de5 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -1204,7 +1204,7 @@ mod tests { provider.canonical_in_memory_state.set_pending_block(ExecutedBlock { recovered_block: Arc::new(RecoveredBlock::new_sealed( block.clone(), - Default::default(), + block.senders().unwrap(), )), execution_output: Default::default(), hashed_state: Default::default(), From 3c93646fe4f11e6138ede024e8af09bee0593b0b Mon Sep 17 00:00:00 2001 From: voidash Date: Wed, 15 Jan 2025 21:05:44 +0545 Subject: [PATCH 3/3] resolve comments --- crates/storage/provider/src/providers/consistent.rs | 4 ++-- crates/storage/provider/src/writer/mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index df1d055ebd9c..d84152f88e9d 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -630,7 +630,7 @@ impl HeaderProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block( (*block_hash).into(), |db_provider| db_provider.header(block_hash), - |block_state| Ok(Some(block_state.block_ref().recovered_block().header().clone())), + |block_state| Ok(Some(block_state.block_ref().recovered_block().clone_header())), ) } @@ -638,7 +638,7 @@ impl HeaderProvider for ConsistentProvider { self.get_in_memory_or_storage_by_block( num.into(), |db_provider| db_provider.header_by_number(num), - |block_state| Ok(Some(block_state.block_ref().recovered_block().header().clone())), + |block_state| Ok(Some(block_state.block_ref().recovered_block().clone_header())), ) } diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index da6fa25c5193..d1cc61600db8 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -162,7 +162,7 @@ where // Insert the blocks for ExecutedBlock { recovered_block, execution_output, hashed_state, trie } in blocks { self.database() - .insert_block(recovered_block.as_ref().clone(), StorageLocation::Both)?; + .insert_block(Arc::unwrap_or_clone(recovered_block), StorageLocation::Both)?; // Write state and changesets to the database. // Must be written after blocks because of the receipt lookup.