mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: relax provider bounds (#12857)
This commit is contained in:
@ -57,7 +57,7 @@ pub struct BlockchainProvider2<N: NodeTypesWithDB> {
|
||||
pub(crate) database: ProviderFactory<N>,
|
||||
/// Tracks the chain info wrt forkchoice updates and in memory canonical
|
||||
/// state.
|
||||
pub(crate) canonical_in_memory_state: CanonicalInMemoryState,
|
||||
pub(crate) canonical_in_memory_state: CanonicalInMemoryState<N::Primitives>,
|
||||
}
|
||||
|
||||
impl<N: NodeTypesWithDB> Clone for BlockchainProvider2<N> {
|
||||
@ -117,7 +117,7 @@ impl<N: ProviderNodeTypes> BlockchainProvider2<N> {
|
||||
}
|
||||
|
||||
/// Gets a clone of `canonical_in_memory_state`.
|
||||
pub fn canonical_in_memory_state(&self) -> CanonicalInMemoryState {
|
||||
pub fn canonical_in_memory_state(&self) -> CanonicalInMemoryState<N::Primitives> {
|
||||
self.canonical_in_memory_state.clone()
|
||||
}
|
||||
|
||||
@ -132,8 +132,8 @@ impl<N: ProviderNodeTypes> BlockchainProvider2<N> {
|
||||
/// This uses a given [`BlockState`] to initialize a state provider for that block.
|
||||
fn block_state_provider(
|
||||
&self,
|
||||
state: &BlockState,
|
||||
) -> ProviderResult<MemoryOverlayStateProvider> {
|
||||
state: &BlockState<N::Primitives>,
|
||||
) -> ProviderResult<MemoryOverlayStateProvider<N::Primitives>> {
|
||||
let anchor_hash = state.anchor().hash;
|
||||
let latest_historical = self.database.history_by_block_hash(anchor_hash)?;
|
||||
Ok(state.state_provider(latest_historical))
|
||||
@ -647,7 +647,7 @@ impl<N: ProviderNodeTypes> StateProviderFactory for BlockchainProvider2<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NodeTypesWithDB> CanonChainTracker for BlockchainProvider2<N>
|
||||
impl<N: ProviderNodeTypes> CanonChainTracker for BlockchainProvider2<N>
|
||||
where
|
||||
Self: BlockReader,
|
||||
{
|
||||
@ -721,7 +721,7 @@ impl<N: NodeTypesWithDB<Primitives = EthPrimitives>> CanonStateSubscriptions
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NodeTypesWithDB> ForkChoiceSubscriptions for BlockchainProvider2<N> {
|
||||
impl<N: ProviderNodeTypes> ForkChoiceSubscriptions for BlockchainProvider2<N> {
|
||||
fn subscribe_safe_block(&self) -> ForkChoiceNotifications {
|
||||
let receiver = self.canonical_in_memory_state.subscribe_safe_block();
|
||||
ForkChoiceNotifications(receiver)
|
||||
@ -2347,7 +2347,7 @@ mod tests {
|
||||
(block_range, |block: &SealedBlock| block.clone().unseal()),
|
||||
(block_with_senders_range, |block: &SealedBlock| block
|
||||
.clone()
|
||||
.unseal()
|
||||
.unseal::<reth_primitives::Block>()
|
||||
.with_senders_unchecked(vec![])),
|
||||
(sealed_block_with_senders_range, |block: &SealedBlock| block
|
||||
.clone()
|
||||
@ -2542,7 +2542,7 @@ mod tests {
|
||||
block_with_senders,
|
||||
|block: &SealedBlock, _: TxNumber, _: B256, _: &Vec<Vec<Receipt>>| (
|
||||
(BlockHashOrNumber::Number(block.number), TransactionVariant::WithHash),
|
||||
block.clone().unseal().with_recovered_senders()
|
||||
block.clone().unseal::<reth_primitives::Block>().with_recovered_senders()
|
||||
),
|
||||
(BlockHashOrNumber::Number(u64::MAX), TransactionVariant::WithHash)
|
||||
),
|
||||
@ -2551,7 +2551,7 @@ mod tests {
|
||||
block_with_senders,
|
||||
|block: &SealedBlock, _: TxNumber, _: B256, _: &Vec<Vec<Receipt>>| (
|
||||
(BlockHashOrNumber::Hash(block.hash()), TransactionVariant::WithHash),
|
||||
block.clone().unseal().with_recovered_senders()
|
||||
block.clone().unseal::<reth_primitives::Block>().with_recovered_senders()
|
||||
),
|
||||
(BlockHashOrNumber::Hash(B256::random()), TransactionVariant::WithHash)
|
||||
),
|
||||
@ -2561,7 +2561,12 @@ mod tests {
|
||||
|block: &SealedBlock, _: TxNumber, _: B256, _: &Vec<Vec<Receipt>>| (
|
||||
(BlockHashOrNumber::Number(block.number), TransactionVariant::WithHash),
|
||||
Some(
|
||||
block.clone().unseal().with_recovered_senders().unwrap().seal(block.hash())
|
||||
block
|
||||
.clone()
|
||||
.unseal::<reth_primitives::Block>()
|
||||
.with_recovered_senders()
|
||||
.unwrap()
|
||||
.seal(block.hash())
|
||||
)
|
||||
),
|
||||
(BlockHashOrNumber::Number(u64::MAX), TransactionVariant::WithHash)
|
||||
@ -2572,7 +2577,12 @@ mod tests {
|
||||
|block: &SealedBlock, _: TxNumber, _: B256, _: &Vec<Vec<Receipt>>| (
|
||||
(BlockHashOrNumber::Hash(block.hash()), TransactionVariant::WithHash),
|
||||
Some(
|
||||
block.clone().unseal().with_recovered_senders().unwrap().seal(block.hash())
|
||||
block
|
||||
.clone()
|
||||
.unseal::<reth_primitives::Block>()
|
||||
.with_recovered_senders()
|
||||
.unwrap()
|
||||
.seal(block.hash())
|
||||
)
|
||||
),
|
||||
(BlockHashOrNumber::Hash(B256::random()), TransactionVariant::WithHash)
|
||||
|
||||
@ -8,6 +8,7 @@ use crate::{
|
||||
};
|
||||
use alloy_consensus::Header;
|
||||
use alloy_eips::{
|
||||
eip2718::Encodable2718,
|
||||
eip4895::{Withdrawal, Withdrawals},
|
||||
BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber,
|
||||
};
|
||||
@ -48,13 +49,14 @@ use tracing::trace;
|
||||
/// CAUTION: Avoid holding this provider for too long or the inner database transaction will
|
||||
/// time-out.
|
||||
#[derive(Debug)]
|
||||
#[doc(hidden)] // triggers ICE for `cargo docs`
|
||||
pub struct ConsistentProvider<N: ProviderNodeTypes> {
|
||||
/// Storage provider.
|
||||
storage_provider: <ProviderFactory<N> as DatabaseProviderFactory>::Provider,
|
||||
/// Head block at time of [`Self`] creation
|
||||
head_block: Option<Arc<BlockState>>,
|
||||
head_block: Option<Arc<BlockState<N::Primitives>>>,
|
||||
/// In-memory canonical state. This is not a snapshot, and can change! Use with caution.
|
||||
canonical_in_memory_state: CanonicalInMemoryState,
|
||||
canonical_in_memory_state: CanonicalInMemoryState<N::Primitives>,
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
@ -65,7 +67,7 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
/// view of memory and database.
|
||||
pub fn new(
|
||||
storage_provider_factory: ProviderFactory<N>,
|
||||
state: CanonicalInMemoryState,
|
||||
state: CanonicalInMemoryState<N::Primitives>,
|
||||
) -> ProviderResult<Self> {
|
||||
// Each one provides a snapshot at the time of instantiation, but its order matters.
|
||||
//
|
||||
@ -307,7 +309,7 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
RangeInclusive<BlockNumber>,
|
||||
&mut P,
|
||||
) -> ProviderResult<Vec<T>>,
|
||||
G: Fn(&BlockState, &mut P) -> Option<T>,
|
||||
G: Fn(&BlockState<N::Primitives>, &mut P) -> Option<T>,
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
// Each one provides a snapshot at the time of instantiation, but its order matters.
|
||||
@ -399,8 +401,8 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
/// This uses a given [`BlockState`] to initialize a state provider for that block.
|
||||
fn block_state_provider_ref(
|
||||
&self,
|
||||
state: &BlockState,
|
||||
) -> ProviderResult<MemoryOverlayStateProviderRef<'_>> {
|
||||
state: &BlockState<N::Primitives>,
|
||||
) -> ProviderResult<MemoryOverlayStateProviderRef<'_, N::Primitives>> {
|
||||
let anchor_hash = state.anchor().hash;
|
||||
let latest_historical = self.history_by_block_hash_ref(anchor_hash)?;
|
||||
let in_memory = state.chain().map(|block_state| block_state.block()).collect();
|
||||
@ -423,7 +425,7 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
&DatabaseProviderRO<N::DB, N>,
|
||||
RangeInclusive<TxNumber>,
|
||||
) -> ProviderResult<Vec<R>>,
|
||||
M: Fn(RangeInclusive<usize>, &BlockState) -> ProviderResult<Vec<R>>,
|
||||
M: Fn(RangeInclusive<usize>, &BlockState<N::Primitives>) -> ProviderResult<Vec<R>>,
|
||||
{
|
||||
let in_mem_chain = self.head_block.iter().flat_map(|b| b.chain()).collect::<Vec<_>>();
|
||||
let provider = &self.storage_provider;
|
||||
@ -445,7 +447,7 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
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().block().body.transactions().len() as u64)
|
||||
.sum::<u64>() +
|
||||
last_block_body_index.last_tx_num()
|
||||
});
|
||||
@ -477,7 +479,7 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
|
||||
// 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().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
|
||||
@ -519,7 +521,7 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
) -> ProviderResult<Option<R>>
|
||||
where
|
||||
S: FnOnce(&DatabaseProviderRO<N::DB, N>) -> ProviderResult<Option<R>>,
|
||||
M: Fn(usize, TxNumber, &BlockState) -> ProviderResult<Option<R>>,
|
||||
M: Fn(usize, TxNumber, &BlockState<N::Primitives>) -> ProviderResult<Option<R>>,
|
||||
{
|
||||
let in_mem_chain = self.head_block.iter().flat_map(|b| b.chain()).collect::<Vec<_>>();
|
||||
let provider = &self.storage_provider;
|
||||
@ -551,10 +553,10 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
let executed_block = block_state.block_ref();
|
||||
let block = executed_block.block();
|
||||
|
||||
for tx_index in 0..block.body.transactions.len() {
|
||||
for tx_index in 0..block.body.transactions().len() {
|
||||
match id {
|
||||
HashOrNumber::Hash(tx_hash) => {
|
||||
if tx_hash == block.body.transactions[tx_index].hash() {
|
||||
if tx_hash == block.body.transactions()[tx_index].trie_hash() {
|
||||
return fetch_from_block_state(tx_index, in_memory_tx_num, block_state)
|
||||
}
|
||||
}
|
||||
@ -586,7 +588,7 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
|
||||
) -> ProviderResult<R>
|
||||
where
|
||||
S: FnOnce(&DatabaseProviderRO<N::DB, N>) -> ProviderResult<R>,
|
||||
M: Fn(&BlockState) -> ProviderResult<R>,
|
||||
M: Fn(&BlockState<N::Primitives>) -> ProviderResult<R>,
|
||||
{
|
||||
if let Some(Some(block_state)) = self.head_block.as_ref().map(|b| b.block_on_chain(id)) {
|
||||
return fetch_from_block_state(block_state)
|
||||
@ -839,7 +841,7 @@ impl<N: ProviderNodeTypes> BlockReader for ConsistentProvider<N> {
|
||||
return Ok(Some(Vec::new()))
|
||||
}
|
||||
|
||||
Ok(Some(block_state.block_ref().block().body.ommers.clone()))
|
||||
Ok(block_state.block_ref().block().body.ommers().map(|o| o.to_vec()))
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -865,7 +867,7 @@ impl<N: ProviderNodeTypes> BlockReader for ConsistentProvider<N> {
|
||||
|
||||
// Iterate from the lowest block in memory until our target block
|
||||
for state in block_state.chain().collect::<Vec<_>>().into_iter().rev() {
|
||||
let block_tx_count = state.block_ref().block.body.transactions.len() as u64;
|
||||
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;
|
||||
} else {
|
||||
@ -962,7 +964,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
|
||||
.block_ref()
|
||||
.block()
|
||||
.body
|
||||
.transactions
|
||||
.transactions()
|
||||
.get(tx_index)
|
||||
.cloned()
|
||||
.map(Into::into))
|
||||
@ -982,7 +984,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
|
||||
.block_ref()
|
||||
.block()
|
||||
.body
|
||||
.transactions
|
||||
.transactions()
|
||||
.get(tx_index)
|
||||
.cloned()
|
||||
.map(Into::into))
|
||||
@ -1050,11 +1052,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
|
||||
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]
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(Into::into)
|
||||
.collect())
|
||||
Ok(block_state.block_ref().block().body.transactions()[index_range].to_vec())
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -1098,12 +1096,13 @@ impl<N: ProviderNodeTypes> ReceiptProvider for ConsistentProvider<N> {
|
||||
|
||||
// assuming 1:1 correspondence between transactions and receipts
|
||||
debug_assert_eq!(
|
||||
block.body.transactions.len(),
|
||||
block.body.transactions().len(),
|
||||
receipts.len(),
|
||||
"Mismatch between transaction and receipt count"
|
||||
);
|
||||
|
||||
if let Some(tx_index) = block.body.transactions.iter().position(|tx| tx.hash() == hash)
|
||||
if let Some(tx_index) =
|
||||
block.body.transactions().iter().position(|tx| tx.trie_hash() == hash)
|
||||
{
|
||||
// safe to use tx_index for receipts due to 1:1 correspondence
|
||||
return Ok(receipts.get(tx_index).cloned());
|
||||
@ -1181,7 +1180,7 @@ impl<N: ProviderNodeTypes> WithdrawalsProvider for ConsistentProvider<N> {
|
||||
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.clone()),
|
||||
|block_state| Ok(block_state.block_ref().block().body.withdrawals().cloned()),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1196,8 +1195,8 @@ impl<N: ProviderNodeTypes> WithdrawalsProvider for ConsistentProvider<N> {
|
||||
.block_ref()
|
||||
.block()
|
||||
.body
|
||||
.withdrawals
|
||||
.clone()
|
||||
.withdrawals()
|
||||
.cloned()
|
||||
.and_then(|mut w| w.pop()))
|
||||
},
|
||||
)
|
||||
|
||||
@ -47,7 +47,7 @@ use reth_execution_types::{Chain, ExecutionOutcome};
|
||||
use reth_network_p2p::headers::downloader::SyncTarget;
|
||||
use reth_node_types::{BlockTy, BodyTy, NodeTypes, TxTy};
|
||||
use reth_primitives::{
|
||||
Account, Block, BlockExt, BlockWithSenders, Bytecode, GotExpected, Receipt, SealedBlock,
|
||||
Account, BlockExt, BlockWithSenders, Bytecode, GotExpected, Receipt, SealedBlock,
|
||||
SealedBlockFor, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry,
|
||||
TransactionMeta, TransactionSignedNoHash,
|
||||
};
|
||||
@ -1229,7 +1229,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> BlockReader for DatabaseProvid
|
||||
.pop()
|
||||
.ok_or(ProviderError::InvalidStorageOutput)?;
|
||||
|
||||
return Ok(Some(Block { header, body }))
|
||||
return Ok(Some(Self::Block::new(header, body)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,12 +21,13 @@ use reth_blockchain_tree_api::{
|
||||
};
|
||||
use reth_chain_state::{ChainInfoTracker, ForkChoiceNotifications, ForkChoiceSubscriptions};
|
||||
use reth_chainspec::{ChainInfo, EthereumHardforks};
|
||||
use reth_db::table::Value;
|
||||
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
||||
use reth_evm::ConfigureEvmEnv;
|
||||
use reth_node_types::{BlockTy, FullNodePrimitives, NodeTypes, NodeTypesWithDB, TxTy};
|
||||
use reth_primitives::{
|
||||
Account, BlockWithSenders, Receipt, SealedBlock, SealedBlockFor, SealedBlockWithSenders,
|
||||
SealedHeader, TransactionMeta, TransactionSigned,
|
||||
Account, BlockWithSenders, EthPrimitives, Receipt, SealedBlock, SealedBlockFor,
|
||||
SealedBlockWithSenders, SealedHeader, TransactionMeta,
|
||||
};
|
||||
use reth_prune_types::{PruneCheckpoint, PruneSegment};
|
||||
use reth_stages_types::{StageCheckpoint, StageId};
|
||||
@ -77,10 +78,8 @@ where
|
||||
ChainSpec: EthereumHardforks,
|
||||
Storage: ChainStorage<Self::Primitives>,
|
||||
Primitives: FullNodePrimitives<
|
||||
SignedTx = TransactionSigned,
|
||||
SignedTx: Value,
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
BlockBody = reth_primitives::BlockBody,
|
||||
Block = reth_primitives::Block,
|
||||
Receipt = reth_primitives::Receipt,
|
||||
>,
|
||||
>,
|
||||
@ -92,10 +91,8 @@ impl<T> NodeTypesForProvider for T where
|
||||
ChainSpec: EthereumHardforks,
|
||||
Storage: ChainStorage<T::Primitives>,
|
||||
Primitives: FullNodePrimitives<
|
||||
SignedTx = TransactionSigned,
|
||||
SignedTx: Value,
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
BlockBody = reth_primitives::BlockBody,
|
||||
Block = reth_primitives::Block,
|
||||
Receipt = reth_primitives::Receipt,
|
||||
>,
|
||||
>
|
||||
@ -108,9 +105,18 @@ where
|
||||
Self: NodeTypesForProvider + NodeTypesWithDB,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T> ProviderNodeTypes for T where T: NodeTypesForProvider + NodeTypesWithDB {}
|
||||
|
||||
/// A helper trait with requirements for [`NodeTypesForProvider`] to be used within legacy
|
||||
/// blockchain tree.
|
||||
pub trait NodeTypesForTree: NodeTypesForProvider<Primitives = EthPrimitives> {}
|
||||
impl<T> NodeTypesForTree for T where T: NodeTypesForProvider<Primitives = EthPrimitives> {}
|
||||
|
||||
/// Helper trait with requirements for [`ProviderNodeTypes`] to be used within legacy blockchain
|
||||
/// tree.
|
||||
pub trait TreeNodeTypes: ProviderNodeTypes + NodeTypesForTree {}
|
||||
impl<T> TreeNodeTypes for T where T: ProviderNodeTypes + NodeTypesForTree {}
|
||||
|
||||
/// The main type for interacting with the blockchain.
|
||||
///
|
||||
/// This type serves as the main entry point for interacting with the blockchain and provides data
|
||||
@ -342,7 +348,7 @@ impl<N: ProviderNodeTypes> BlockIdReader for BlockchainProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> BlockReader for BlockchainProvider<N> {
|
||||
impl<N: TreeNodeTypes> BlockReader for BlockchainProvider<N> {
|
||||
type Block = BlockTy<N>;
|
||||
|
||||
fn find_block_by_hash(
|
||||
|
||||
Reference in New Issue
Block a user