Skip to content

Commit

Permalink
add BlockchainProvider3
Browse files Browse the repository at this point in the history
  • Loading branch information
joshieDo committed Oct 15, 2024
1 parent 3dcc92b commit 7f77e27
Show file tree
Hide file tree
Showing 5 changed files with 3,894 additions and 23 deletions.
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 @@ -513,7 +513,7 @@ impl CanonicalInMemoryState {
state: &BlockState,
historical: StateProviderBox,
) -> MemoryOverlayStateProvider {
let in_memory = state.chain().into_iter().map(|block_state| block_state.block()).collect();
let in_memory = state.chain().map(|block_state| block_state.block()).collect();

MemoryOverlayStateProvider::new(historical, in_memory)
}
Expand All @@ -528,7 +528,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 @@ -706,10 +706,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 @@ -723,6 +721,55 @@ impl BlockState {
pub fn iter(self: Arc<Self>) -> impl Iterator<Item = Arc<Self>> {
std::iter::successors(Some(self), |state| state.parent.clone())
}

/// 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 @@ -1385,7 +1432,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 @@ -1396,18 +1443,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
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ impl<N: ProviderNodeTypes> BlockReader for BlockchainProvider2<N> {
stored_indices.tx_count = 0;

// Iterate from the lowest block in memory until our target block
for state in block_state.chain().into_iter().rev() {
for state in block_state.chain().collect::<Vec<_>>().into_iter().rev() {
let block_tx_count = state.block_ref().block.body.transactions.len() as u64;
if state.block_ref().block().number == number {
stored_indices.tx_count = block_tx_count;
Expand Down
Loading

0 comments on commit 7f77e27

Please sign in to comment.