mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore(sdk): make Chain generic over data primitives (#12635)
This commit is contained in:
@ -7,9 +7,10 @@ use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash};
|
||||
use core::{fmt, ops::RangeInclusive};
|
||||
use reth_execution_errors::{BlockExecutionError, InternalBlockExecutionError};
|
||||
use reth_primitives::{
|
||||
Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionSigned,
|
||||
SealedBlock, SealedBlockWithSenders, SealedHeader, TransactionSigned,
|
||||
TransactionSignedEcRecovered,
|
||||
};
|
||||
use reth_primitives_traits::NodePrimitives;
|
||||
use reth_trie::updates::TrieUpdates;
|
||||
use revm::db::BundleState;
|
||||
|
||||
@ -25,7 +26,7 @@ use revm::db::BundleState;
|
||||
/// A chain of blocks should not be empty.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Chain {
|
||||
pub struct Chain<N: NodePrimitives = reth_primitives::EthPrimitives> {
|
||||
/// All blocks in this chain.
|
||||
blocks: BTreeMap<BlockNumber, SealedBlockWithSenders>,
|
||||
/// The outcome of block execution for this chain.
|
||||
@ -34,14 +35,14 @@ pub struct Chain {
|
||||
/// chain, ranging from the [`Chain::first`] block to the [`Chain::tip`] block, inclusive.
|
||||
///
|
||||
/// Additionally, it includes the individual state changes that led to the current state.
|
||||
execution_outcome: ExecutionOutcome,
|
||||
execution_outcome: ExecutionOutcome<N::Receipt>,
|
||||
/// State trie updates after block is added to the chain.
|
||||
/// NOTE: Currently, trie updates are present only for
|
||||
/// single-block chains that extend the canonical chain.
|
||||
trie_updates: Option<TrieUpdates>,
|
||||
}
|
||||
|
||||
impl Chain {
|
||||
impl<N: NodePrimitives> Chain<N> {
|
||||
/// Create new Chain from blocks and state.
|
||||
///
|
||||
/// # Warning
|
||||
@ -49,7 +50,7 @@ impl Chain {
|
||||
/// A chain of blocks should not be empty.
|
||||
pub fn new(
|
||||
blocks: impl IntoIterator<Item = SealedBlockWithSenders>,
|
||||
execution_outcome: ExecutionOutcome,
|
||||
execution_outcome: ExecutionOutcome<N::Receipt>,
|
||||
trie_updates: Option<TrieUpdates>,
|
||||
) -> Self {
|
||||
let blocks = blocks.into_iter().map(|b| (b.number, b)).collect::<BTreeMap<_, _>>();
|
||||
@ -61,7 +62,7 @@ impl Chain {
|
||||
/// Create new Chain from a single block and its state.
|
||||
pub fn from_block(
|
||||
block: SealedBlockWithSenders,
|
||||
execution_outcome: ExecutionOutcome,
|
||||
execution_outcome: ExecutionOutcome<N::Receipt>,
|
||||
trie_updates: Option<TrieUpdates>,
|
||||
) -> Self {
|
||||
Self::new([block], execution_outcome, trie_updates)
|
||||
@ -93,12 +94,12 @@ impl Chain {
|
||||
}
|
||||
|
||||
/// Get execution outcome of this chain
|
||||
pub const fn execution_outcome(&self) -> &ExecutionOutcome {
|
||||
pub const fn execution_outcome(&self) -> &ExecutionOutcome<N::Receipt> {
|
||||
&self.execution_outcome
|
||||
}
|
||||
|
||||
/// Get mutable execution outcome of this chain
|
||||
pub fn execution_outcome_mut(&mut self) -> &mut ExecutionOutcome {
|
||||
pub fn execution_outcome_mut(&mut self) -> &mut ExecutionOutcome<N::Receipt> {
|
||||
&mut self.execution_outcome
|
||||
}
|
||||
|
||||
@ -132,7 +133,7 @@ impl Chain {
|
||||
pub fn execution_outcome_at_block(
|
||||
&self,
|
||||
block_number: BlockNumber,
|
||||
) -> Option<ExecutionOutcome> {
|
||||
) -> Option<ExecutionOutcome<N::Receipt>> {
|
||||
if self.tip().number == block_number {
|
||||
return Some(self.execution_outcome.clone())
|
||||
}
|
||||
@ -149,19 +150,21 @@ impl Chain {
|
||||
/// 1. The blocks contained in the chain.
|
||||
/// 2. The execution outcome representing the final state.
|
||||
/// 3. The optional trie updates.
|
||||
pub fn into_inner(self) -> (ChainBlocks<'static>, ExecutionOutcome, Option<TrieUpdates>) {
|
||||
pub fn into_inner(
|
||||
self,
|
||||
) -> (ChainBlocks<'static>, ExecutionOutcome<N::Receipt>, Option<TrieUpdates>) {
|
||||
(ChainBlocks { blocks: Cow::Owned(self.blocks) }, self.execution_outcome, self.trie_updates)
|
||||
}
|
||||
|
||||
/// Destructure the chain into its inner components:
|
||||
/// 1. A reference to the blocks contained in the chain.
|
||||
/// 2. A reference to the execution outcome representing the final state.
|
||||
pub const fn inner(&self) -> (ChainBlocks<'_>, &ExecutionOutcome) {
|
||||
pub const fn inner(&self) -> (ChainBlocks<'_>, &ExecutionOutcome<N::Receipt>) {
|
||||
(ChainBlocks { blocks: Cow::Borrowed(&self.blocks) }, &self.execution_outcome)
|
||||
}
|
||||
|
||||
/// Returns an iterator over all the receipts of the blocks in the chain.
|
||||
pub fn block_receipts_iter(&self) -> impl Iterator<Item = &Vec<Option<Receipt>>> + '_ {
|
||||
pub fn block_receipts_iter(&self) -> impl Iterator<Item = &Vec<Option<N::Receipt>>> + '_ {
|
||||
self.execution_outcome.receipts().iter()
|
||||
}
|
||||
|
||||
@ -173,7 +176,7 @@ impl Chain {
|
||||
/// Returns an iterator over all blocks and their receipts in the chain.
|
||||
pub fn blocks_and_receipts(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (&SealedBlockWithSenders, &Vec<Option<Receipt>>)> + '_ {
|
||||
) -> impl Iterator<Item = (&SealedBlockWithSenders, &Vec<Option<N::Receipt>>)> + '_ {
|
||||
self.blocks_iter().zip(self.block_receipts_iter())
|
||||
}
|
||||
|
||||
@ -219,7 +222,7 @@ impl Chain {
|
||||
}
|
||||
|
||||
/// Get all receipts for the given block.
|
||||
pub fn receipts_by_block_hash(&self, block_hash: BlockHash) -> Option<Vec<&Receipt>> {
|
||||
pub fn receipts_by_block_hash(&self, block_hash: BlockHash) -> Option<Vec<&N::Receipt>> {
|
||||
let num = self.block_number(block_hash)?;
|
||||
self.execution_outcome.receipts_by_block(num).iter().map(Option::as_ref).collect()
|
||||
}
|
||||
@ -227,7 +230,7 @@ impl Chain {
|
||||
/// Get all receipts with attachment.
|
||||
///
|
||||
/// Attachment includes block number, block hash, transaction hash and transaction index.
|
||||
pub fn receipts_with_attachment(&self) -> Vec<BlockReceipts> {
|
||||
pub fn receipts_with_attachment(&self) -> Vec<BlockReceipts<N::Receipt>> {
|
||||
let mut receipt_attach = Vec::with_capacity(self.blocks().len());
|
||||
for ((block_num, block), receipts) in
|
||||
self.blocks().iter().zip(self.execution_outcome.receipts().iter())
|
||||
@ -250,7 +253,7 @@ impl Chain {
|
||||
pub fn append_block(
|
||||
&mut self,
|
||||
block: SealedBlockWithSenders,
|
||||
execution_outcome: ExecutionOutcome,
|
||||
execution_outcome: ExecutionOutcome<N::Receipt>,
|
||||
) {
|
||||
self.blocks.insert(block.number, block);
|
||||
self.execution_outcome.extend(execution_outcome);
|
||||
@ -300,7 +303,7 @@ impl Chain {
|
||||
///
|
||||
/// If chain doesn't have any blocks.
|
||||
#[track_caller]
|
||||
pub fn split(mut self, split_at: ChainSplitTarget) -> ChainSplit {
|
||||
pub fn split(mut self, split_at: ChainSplitTarget) -> ChainSplit<N> {
|
||||
let chain_tip = *self.blocks.last_entry().expect("chain is never empty").key();
|
||||
let block_number = match split_at {
|
||||
ChainSplitTarget::Hash(block_hash) => {
|
||||
@ -454,11 +457,11 @@ impl IntoIterator for ChainBlocks<'_> {
|
||||
|
||||
/// Used to hold receipts and their attachment.
|
||||
#[derive(Default, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct BlockReceipts {
|
||||
pub struct BlockReceipts<T = reth_primitives::Receipt> {
|
||||
/// Block identifier
|
||||
pub block: BlockNumHash,
|
||||
/// Transaction identifier and receipt.
|
||||
pub tx_receipts: Vec<(TxHash, Receipt)>,
|
||||
pub tx_receipts: Vec<(TxHash, T)>,
|
||||
}
|
||||
|
||||
/// The target block where the chain should be split.
|
||||
@ -484,26 +487,26 @@ impl From<BlockHash> for ChainSplitTarget {
|
||||
|
||||
/// Result of a split chain.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum ChainSplit {
|
||||
pub enum ChainSplit<N: NodePrimitives = reth_primitives::EthPrimitives> {
|
||||
/// Chain is not split. Pending chain is returned.
|
||||
/// Given block split is higher than last block.
|
||||
/// Or in case of split by hash when hash is unknown.
|
||||
NoSplitPending(Chain),
|
||||
NoSplitPending(Chain<N>),
|
||||
/// Chain is not split. Canonical chain is returned.
|
||||
/// Given block split is lower than first block.
|
||||
NoSplitCanonical(Chain),
|
||||
NoSplitCanonical(Chain<N>),
|
||||
/// Chain is split into two: `[canonical]` and `[pending]`
|
||||
/// The target of this chain split [`ChainSplitTarget`] belongs to the `canonical` chain.
|
||||
Split {
|
||||
/// Contains lower block numbers that are considered canonicalized. It ends with
|
||||
/// the [`ChainSplitTarget`] block. The state of this chain is now empty and no longer
|
||||
/// usable.
|
||||
canonical: Chain,
|
||||
canonical: Chain<N>,
|
||||
/// Right contains all subsequent blocks __after__ the [`ChainSplitTarget`] that are still
|
||||
/// pending.
|
||||
///
|
||||
/// The state of the original chain is moved here.
|
||||
pending: Chain,
|
||||
pending: Chain<N>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -678,7 +681,7 @@ mod tests {
|
||||
|
||||
block3.set_parent_hash(block2_hash);
|
||||
|
||||
let mut chain1 =
|
||||
let mut chain1: Chain =
|
||||
Chain { blocks: BTreeMap::from([(1, block1), (2, block2)]), ..Default::default() };
|
||||
|
||||
let chain2 =
|
||||
@ -692,7 +695,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_number_split() {
|
||||
let execution_outcome1 = ExecutionOutcome::new(
|
||||
let execution_outcome1: ExecutionOutcome = ExecutionOutcome::new(
|
||||
BundleState::new(
|
||||
vec![(
|
||||
Address::new([2; 20]),
|
||||
@ -739,7 +742,8 @@ mod tests {
|
||||
let mut block_state_extended = execution_outcome1;
|
||||
block_state_extended.extend(execution_outcome2);
|
||||
|
||||
let chain = Chain::new(vec![block1.clone(), block2.clone()], block_state_extended, None);
|
||||
let chain: Chain =
|
||||
Chain::new(vec![block1.clone(), block2.clone()], block_state_extended, None);
|
||||
|
||||
let (split1_execution_outcome, split2_execution_outcome) =
|
||||
chain.execution_outcome.clone().split_at(2);
|
||||
@ -838,7 +842,7 @@ mod tests {
|
||||
|
||||
// Create a Chain object with a BTreeMap of blocks mapped to their block numbers,
|
||||
// including block1_hash and block2_hash, and the execution_outcome
|
||||
let chain = Chain {
|
||||
let chain: Chain = Chain {
|
||||
blocks: BTreeMap::from([(10, block1), (11, block2)]),
|
||||
execution_outcome: execution_outcome.clone(),
|
||||
..Default::default()
|
||||
|
||||
Reference in New Issue
Block a user