diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 1ac01b57b..cec932177 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -455,26 +455,33 @@ impl BlockState { .unwrap_or_default() } - /// Returns a vector of parent `BlockStates` starting from the oldest one. + /// Returns a vector of parent `BlockStates`. + /// The block state order in the output vector is newest to oldest. pub fn parent_state_chain(&self) -> Vec<&Self> { let mut parents = Vec::new(); let mut current = self.parent.as_deref(); while let Some(parent) = current { - parents.insert(0, parent); + parents.push(parent); current = parent.parent.as_deref(); } parents } - /// Returns a vector of `BlockStates` representing the entire in memory chain, - /// including self as the last element. + /// Returns a vector of `BlockStates` representing the entire in memory chain. + /// The block state order in the output vector is newest to oldest, including + /// self as the first element. pub fn chain(&self) -> Vec<&Self> { - let mut chain = self.parent_state_chain(); - chain.push(self); + let mut chain = vec![self]; + self.append_parent_chain(&mut chain); chain } + + /// Appends the parent chain of this `BlockState` to the given vector. + pub fn append_parent_chain<'a>(&'a self, chain: &mut Vec<&'a Self>) { + chain.extend(self.parent_state_chain()); + } } /// Represents an executed block stored in-memory. @@ -889,17 +896,17 @@ mod tests { let overlay_provider = canonical_state.state_provider(block3.block().hash(), historical); assert_eq!(overlay_provider.in_memory.len(), 3); - assert_eq!(overlay_provider.in_memory[0].block().number, 1); + 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, 3); + assert_eq!(overlay_provider.in_memory[2].block().number, 1); assert_eq!( - overlay_provider.in_memory[1].block().parent_hash, - overlay_provider.in_memory[0].block().hash() + overlay_provider.in_memory[0].block().parent_hash, + overlay_provider.in_memory[1].block().hash() ); assert_eq!( - overlay_provider.in_memory[2].block().parent_hash, - overlay_provider.in_memory[1].block().hash() + overlay_provider.in_memory[1].block().parent_hash, + overlay_provider.in_memory[2].block().hash() ); let unknown_hash = B256::random(); @@ -914,14 +921,14 @@ mod tests { let parents = chain[3].parent_state_chain(); assert_eq!(parents.len(), 3); - assert_eq!(parents[0].block().block.number, 1); + assert_eq!(parents[0].block().block.number, 3); assert_eq!(parents[1].block().block.number, 2); - assert_eq!(parents[2].block().block.number, 3); + assert_eq!(parents[2].block().block.number, 1); let parents = chain[2].parent_state_chain(); assert_eq!(parents.len(), 2); - assert_eq!(parents[0].block().block.number, 1); - assert_eq!(parents[1].block().block.number, 2); + assert_eq!(parents[0].block().block.number, 2); + assert_eq!(parents[1].block().block.number, 1); let parents = chain[0].parent_state_chain(); assert_eq!(parents.len(), 0); @@ -948,14 +955,14 @@ mod tests { let block_state_chain = chain[2].chain(); assert_eq!(block_state_chain.len(), 3); - assert_eq!(block_state_chain[0].block().block.number, 1); + 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, 3); + assert_eq!(block_state_chain[2].block().block.number, 1); let block_state_chain = chain[1].chain(); assert_eq!(block_state_chain.len(), 2); - assert_eq!(block_state_chain[0].block().block.number, 1); - assert_eq!(block_state_chain[1].block().block.number, 2); + assert_eq!(block_state_chain[0].block().block.number, 2); + assert_eq!(block_state_chain[1].block().block.number, 1); let block_state_chain = chain[0].chain(); assert_eq!(block_state_chain.len(), 1); diff --git a/crates/chain-state/src/memory_overlay.rs b/crates/chain-state/src/memory_overlay.rs index cba585018..58653b28f 100644 --- a/crates/chain-state/src/memory_overlay.rs +++ b/crates/chain-state/src/memory_overlay.rs @@ -10,7 +10,7 @@ use reth_trie::{updates::TrieUpdates, AccountProof, HashedPostState}; /// the historical state provider for fallback lookups. #[allow(missing_debug_implementations)] pub struct MemoryOverlayStateProvider { - /// The collection of executed parent blocks. + /// The collection of executed parent blocks. Expected order is newest to oldest. pub(crate) in_memory: Vec, /// The collection of hashed state from in-memory blocks. pub(crate) hashed_post_state: HashedPostState, @@ -31,7 +31,7 @@ impl MemoryOverlayStateProvider { impl BlockHashReader for MemoryOverlayStateProvider { fn block_hash(&self, number: BlockNumber) -> ProviderResult> { - for block in self.in_memory.iter().rev() { + for block in &self.in_memory { if block.block.number == number { return Ok(Some(block.block.hash())) } @@ -48,7 +48,7 @@ impl BlockHashReader for MemoryOverlayStateProvider { let range = start..end; let mut earliest_block_number = None; let mut in_memory_hashes = Vec::new(); - for block in self.in_memory.iter().rev() { + 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); @@ -64,7 +64,7 @@ impl BlockHashReader for MemoryOverlayStateProvider { impl AccountReader for MemoryOverlayStateProvider { fn basic_account(&self, address: Address) -> ProviderResult> { - for block in self.in_memory.iter().rev() { + for block in &self.in_memory { if let Some(account) = block.execution_output.account(&address) { return Ok(account) } @@ -113,7 +113,7 @@ impl StateProvider for MemoryOverlayStateProvider { address: Address, storage_key: StorageKey, ) -> ProviderResult> { - for block in self.in_memory.iter().rev() { + for block in &self.in_memory { if let Some(value) = block.execution_output.storage(&address, storage_key.into()) { return Ok(Some(value)) } @@ -123,7 +123,7 @@ impl StateProvider for MemoryOverlayStateProvider { } fn bytecode_by_hash(&self, code_hash: B256) -> ProviderResult> { - for block in self.in_memory.iter().rev() { + for block in &self.in_memory { if let Some(contract) = block.execution_output.bytecode(&code_hash) { return Ok(Some(contract)) } diff --git a/crates/engine/tree/src/tree.rs b/crates/engine/tree/src/tree.rs index 271984d20..6f0856e29 100644 --- a/crates/engine/tree/src/tree.rs +++ b/crates/engine/tree/src/tree.rs @@ -731,7 +731,7 @@ where let mut parent_hash = hash; while let Some(executed) = self.state.tree_state.blocks_by_hash.get(&parent_hash) { parent_hash = executed.block.parent_hash; - in_memory.insert(0, executed.clone()); + in_memory.push(executed.clone()); } let historical = self.provider.state_by_block_hash(parent_hash)?;