Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(provider): add BlockchainProvider3 with only one view #11706

Merged
merged 4 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 58 additions & 11 deletions crates/chain-state/src/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
CanonStateNotification, CanonStateNotificationSender, CanonStateNotifications,
ChainInfoTracker, MemoryOverlayStateProvider,
};
use alloy_eips::BlockNumHash;
use alloy_eips::{BlockHashOrNumber, BlockNumHash};
use alloy_primitives::{map::HashMap, Address, TxHash, B256};
use parking_lot::RwLock;
use reth_chainspec::ChainInfo;
Expand Down Expand Up @@ -514,7 +514,7 @@ impl CanonicalInMemoryState {
historical: StateProviderBox,
) -> MemoryOverlayStateProvider {
let in_memory = if let Some(state) = self.state_by_hash(hash) {
state.chain().into_iter().map(|block_state| block_state.block()).collect()
state.chain().map(|block_state| block_state.block()).collect()
} else {
Vec::new()
};
Expand Down Expand Up @@ -692,10 +692,8 @@ impl BlockState {
/// Returns a vector of `BlockStates` representing the entire in memory chain.
/// The block state order in the output vector is newest to oldest (highest to lowest),
/// including self as the first element.
pub fn chain(&self) -> Vec<&Self> {
let mut chain = vec![self];
self.append_parent_chain(&mut chain);
chain
pub fn chain(&self) -> impl Iterator<Item = &Self> {
std::iter::successors(Some(self), |state| state.parent.as_deref())
}

/// Appends the parent chain of this [`BlockState`] to the given vector.
Expand All @@ -715,10 +713,59 @@ impl BlockState {
/// This merges the state of all blocks that are part of the chain that the this block is
/// the head of. This includes all blocks that connect back to the canonical block on disk.
pub fn state_provider(&self, historical: StateProviderBox) -> MemoryOverlayStateProvider {
let in_memory = self.chain().into_iter().map(|block_state| block_state.block()).collect();
let in_memory = self.chain().map(|block_state| block_state.block()).collect();

MemoryOverlayStateProvider::new(historical, in_memory)
}

/// Tries to find a block by [`BlockHashOrNumber`] in the chain ending at this block.
pub fn block_on_chain(&self, hash_or_num: BlockHashOrNumber) -> Option<&Self> {
self.chain().find(|block| match hash_or_num {
BlockHashOrNumber::Hash(hash) => block.hash() == hash,
BlockHashOrNumber::Number(number) => block.number() == number,
})
}

/// Tries to find a transaction by [`TxHash`] in the chain ending at this block.
pub fn transaction_on_chain(&self, hash: TxHash) -> Option<TransactionSigned> {
self.chain().find_map(|block_state| {
block_state
.block_ref()
.block()
.body
.transactions()
.find(|tx| tx.hash() == hash)
.cloned()
})
}

/// Tries to find a transaction with meta by [`TxHash`] in the chain ending at this block.
pub fn transaction_meta_on_chain(
&self,
tx_hash: TxHash,
) -> Option<(TransactionSigned, TransactionMeta)> {
self.chain().find_map(|block_state| {
block_state
.block_ref()
.block()
.body
.transactions()
.enumerate()
.find(|(_, tx)| tx.hash() == tx_hash)
.map(|(index, tx)| {
let meta = TransactionMeta {
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.header.base_fee_per_gas,
timestamp: block_state.block_ref().block.timestamp,
excess_blob_gas: block_state.block_ref().block.excess_blob_gas,
};
(tx.clone(), meta)
})
})
}
}

/// Represents an executed block stored in-memory.
Expand Down Expand Up @@ -1381,7 +1428,7 @@ mod tests {
let parents = single_block.parent_state_chain();
assert_eq!(parents.len(), 0);

let block_state_chain = single_block.chain();
let block_state_chain = single_block.chain().collect::<Vec<_>>();
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);
Expand All @@ -1392,18 +1439,18 @@ mod tests {
let mut test_block_builder = TestBlockBuilder::default();
let chain = create_mock_state_chain(&mut test_block_builder, 3);

let block_state_chain = chain[2].chain();
let block_state_chain = chain[2].chain().collect::<Vec<_>>();
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);

let block_state_chain = chain[1].chain();
let block_state_chain = chain[1].chain().collect::<Vec<_>>();
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);

let block_state_chain = chain[0].chain();
let block_state_chain = chain[0].chain().collect::<Vec<_>>();
assert_eq!(block_state_chain.len(), 1);
assert_eq!(block_state_chain[0].block().block.number, 1);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/chain-state/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use notifications::{
};

mod memory_overlay;
pub use memory_overlay::MemoryOverlayStateProvider;
pub use memory_overlay::{MemoryOverlayStateProvider, MemoryOverlayStateProviderRef};

#[cfg(any(test, feature = "test-utils"))]
/// Common test helpers
Expand Down
Loading