mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix: gracefully handle missing persisted_trie_updates (#13942)
This commit is contained in:
@ -240,7 +240,7 @@ impl<N: NodePrimitives> CanonicalInMemoryState<N> {
|
|||||||
/// Updates the pending block with the given block.
|
/// Updates the pending block with the given block.
|
||||||
///
|
///
|
||||||
/// Note: This assumes that the parent block of the pending block is canonical.
|
/// Note: This assumes that the parent block of the pending block is canonical.
|
||||||
pub fn set_pending_block(&self, pending: ExecutedBlock<N>) {
|
pub fn set_pending_block(&self, pending: ExecutedBlockWithTrieUpdates<N>) {
|
||||||
// fetch the state of the pending block's parent block
|
// fetch the state of the pending block's parent block
|
||||||
let parent = self.state_by_hash(pending.recovered_block().parent_hash());
|
let parent = self.state_by_hash(pending.recovered_block().parent_hash());
|
||||||
let pending = BlockState::with_parent(pending, parent);
|
let pending = BlockState::with_parent(pending, parent);
|
||||||
@ -254,9 +254,10 @@ impl<N: NodePrimitives> CanonicalInMemoryState<N> {
|
|||||||
///
|
///
|
||||||
/// This removes all reorged blocks and appends the new blocks to the tracked chain and connects
|
/// This removes all reorged blocks and appends the new blocks to the tracked chain and connects
|
||||||
/// them to their parent blocks.
|
/// them to their parent blocks.
|
||||||
fn update_blocks<I>(&self, new_blocks: I, reorged: I)
|
fn update_blocks<I, R>(&self, new_blocks: I, reorged: R)
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = ExecutedBlock<N>>,
|
I: IntoIterator<Item = ExecutedBlockWithTrieUpdates<N>>,
|
||||||
|
R: IntoIterator<Item = ExecutedBlock<N>>,
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
// acquire locks, starting with the numbers lock
|
// acquire locks, starting with the numbers lock
|
||||||
@ -601,7 +602,7 @@ impl<N: NodePrimitives> CanonicalInMemoryState<N> {
|
|||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct BlockState<N: NodePrimitives = EthPrimitives> {
|
pub struct BlockState<N: NodePrimitives = EthPrimitives> {
|
||||||
/// The executed block that determines the state after this block has been executed.
|
/// The executed block that determines the state after this block has been executed.
|
||||||
block: ExecutedBlock<N>,
|
block: ExecutedBlockWithTrieUpdates<N>,
|
||||||
/// The block's parent block if it exists.
|
/// The block's parent block if it exists.
|
||||||
parent: Option<Arc<BlockState<N>>>,
|
parent: Option<Arc<BlockState<N>>>,
|
||||||
}
|
}
|
||||||
@ -609,12 +610,15 @@ pub struct BlockState<N: NodePrimitives = EthPrimitives> {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl<N: NodePrimitives> BlockState<N> {
|
impl<N: NodePrimitives> BlockState<N> {
|
||||||
/// [`BlockState`] constructor.
|
/// [`BlockState`] constructor.
|
||||||
pub const fn new(block: ExecutedBlock<N>) -> Self {
|
pub const fn new(block: ExecutedBlockWithTrieUpdates<N>) -> Self {
|
||||||
Self { block, parent: None }
|
Self { block, parent: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockState`] constructor with parent.
|
/// [`BlockState`] constructor with parent.
|
||||||
pub const fn with_parent(block: ExecutedBlock<N>, parent: Option<Arc<Self>>) -> Self {
|
pub const fn with_parent(
|
||||||
|
block: ExecutedBlockWithTrieUpdates<N>,
|
||||||
|
parent: Option<Arc<Self>>,
|
||||||
|
) -> Self {
|
||||||
Self { block, parent }
|
Self { block, parent }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,12 +632,12 @@ impl<N: NodePrimitives> BlockState<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the executed block that determines the state.
|
/// Returns the executed block that determines the state.
|
||||||
pub fn block(&self) -> ExecutedBlock<N> {
|
pub fn block(&self) -> ExecutedBlockWithTrieUpdates<N> {
|
||||||
self.block.clone()
|
self.block.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the executed block that determines the state.
|
/// Returns a reference to the executed block that determines the state.
|
||||||
pub const fn block_ref(&self) -> &ExecutedBlock<N> {
|
pub const fn block_ref(&self) -> &ExecutedBlockWithTrieUpdates<N> {
|
||||||
&self.block
|
&self.block
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,7 +791,7 @@ impl<N: NodePrimitives> BlockState<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an executed block stored in-memory.
|
/// Represents an executed block stored in-memory.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Default)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct ExecutedBlock<N: NodePrimitives = EthPrimitives> {
|
pub struct ExecutedBlock<N: NodePrimitives = EthPrimitives> {
|
||||||
/// Recovered Block
|
/// Recovered Block
|
||||||
pub recovered_block: Arc<RecoveredBlock<N::Block>>,
|
pub recovered_block: Arc<RecoveredBlock<N::Block>>,
|
||||||
@ -795,21 +799,19 @@ pub struct ExecutedBlock<N: NodePrimitives = EthPrimitives> {
|
|||||||
pub execution_output: Arc<ExecutionOutcome<N::Receipt>>,
|
pub execution_output: Arc<ExecutionOutcome<N::Receipt>>,
|
||||||
/// Block's hashed state.
|
/// Block's hashed state.
|
||||||
pub hashed_state: Arc<HashedPostState>,
|
pub hashed_state: Arc<HashedPostState>,
|
||||||
/// Trie updates that result of applying the block.
|
}
|
||||||
pub trie: Arc<TrieUpdates>,
|
|
||||||
|
impl<N: NodePrimitives> Default for ExecutedBlock<N> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
recovered_block: Default::default(),
|
||||||
|
execution_output: Default::default(),
|
||||||
|
hashed_state: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: NodePrimitives> ExecutedBlock<N> {
|
impl<N: NodePrimitives> ExecutedBlock<N> {
|
||||||
/// [`ExecutedBlock`] constructor.
|
|
||||||
pub const fn new(
|
|
||||||
recovered_block: Arc<RecoveredBlock<N::Block>>,
|
|
||||||
execution_output: Arc<ExecutionOutcome<N::Receipt>>,
|
|
||||||
hashed_state: Arc<HashedPostState>,
|
|
||||||
trie: Arc<TrieUpdates>,
|
|
||||||
) -> Self {
|
|
||||||
Self { recovered_block, execution_output, hashed_state, trie }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a reference to an inner [`SealedBlock`]
|
/// Returns a reference to an inner [`SealedBlock`]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sealed_block(&self) -> &SealedBlock<N::Block> {
|
pub fn sealed_block(&self) -> &SealedBlock<N::Block> {
|
||||||
@ -833,6 +835,42 @@ impl<N: NodePrimitives> ExecutedBlock<N> {
|
|||||||
pub fn hashed_state(&self) -> &HashedPostState {
|
pub fn hashed_state(&self) -> &HashedPostState {
|
||||||
&self.hashed_state
|
&self.hashed_state
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An [`ExecutedBlock`] with its [`TrieUpdates`].
|
||||||
|
///
|
||||||
|
/// We store it as separate type because [`TrieUpdates`] are only available for blocks stored in
|
||||||
|
/// memory and can't be obtained for canonical persisted blocks.
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
PartialEq,
|
||||||
|
Eq,
|
||||||
|
Default,
|
||||||
|
derive_more::Deref,
|
||||||
|
derive_more::DerefMut,
|
||||||
|
derive_more::Into,
|
||||||
|
)]
|
||||||
|
pub struct ExecutedBlockWithTrieUpdates<N: NodePrimitives = EthPrimitives> {
|
||||||
|
/// Inner [`ExecutedBlock`].
|
||||||
|
#[deref]
|
||||||
|
#[deref_mut]
|
||||||
|
#[into]
|
||||||
|
pub block: ExecutedBlock<N>,
|
||||||
|
/// Trie updates that result of applying the block.
|
||||||
|
pub trie: Arc<TrieUpdates>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: NodePrimitives> ExecutedBlockWithTrieUpdates<N> {
|
||||||
|
/// [`ExecutedBlock`] constructor.
|
||||||
|
pub const fn new(
|
||||||
|
recovered_block: Arc<RecoveredBlock<N::Block>>,
|
||||||
|
execution_output: Arc<ExecutionOutcome<N::Receipt>>,
|
||||||
|
hashed_state: Arc<HashedPostState>,
|
||||||
|
trie: Arc<TrieUpdates>,
|
||||||
|
) -> Self {
|
||||||
|
Self { block: ExecutedBlock { recovered_block, execution_output, hashed_state }, trie }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a reference to the trie updates for the block
|
/// Returns a reference to the trie updates for the block
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -847,14 +885,18 @@ pub enum NewCanonicalChain<N: NodePrimitives = EthPrimitives> {
|
|||||||
/// A simple append to the current canonical head
|
/// A simple append to the current canonical head
|
||||||
Commit {
|
Commit {
|
||||||
/// all blocks that lead back to the canonical head
|
/// all blocks that lead back to the canonical head
|
||||||
new: Vec<ExecutedBlock<N>>,
|
new: Vec<ExecutedBlockWithTrieUpdates<N>>,
|
||||||
},
|
},
|
||||||
/// A reorged chain consists of two chains that trace back to a shared ancestor block at which
|
/// A reorged chain consists of two chains that trace back to a shared ancestor block at which
|
||||||
/// point they diverge.
|
/// point they diverge.
|
||||||
Reorg {
|
Reorg {
|
||||||
/// All blocks of the _new_ chain
|
/// All blocks of the _new_ chain
|
||||||
new: Vec<ExecutedBlock<N>>,
|
new: Vec<ExecutedBlockWithTrieUpdates<N>>,
|
||||||
/// All blocks of the _old_ chain
|
/// All blocks of the _old_ chain
|
||||||
|
///
|
||||||
|
/// These are not [`ExecutedBlockWithTrieUpdates`] because we don't always have the trie
|
||||||
|
/// updates for the old canonical chain. For example, in case of node being restarted right
|
||||||
|
/// before the reorg [`TrieUpdates`] can't be fetched from database.
|
||||||
old: Vec<ExecutedBlock<N>>,
|
old: Vec<ExecutedBlock<N>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -1257,7 +1299,7 @@ mod tests {
|
|||||||
block1.recovered_block().hash()
|
block1.recovered_block().hash()
|
||||||
);
|
);
|
||||||
|
|
||||||
let chain = NewCanonicalChain::Reorg { new: vec![block2.clone()], old: vec![block1] };
|
let chain = NewCanonicalChain::Reorg { new: vec![block2.clone()], old: vec![block1.block] };
|
||||||
state.update_chain(chain);
|
state.update_chain(chain);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.head_state().unwrap().block_ref().recovered_block().hash(),
|
state.head_state().unwrap().block_ref().recovered_block().hash(),
|
||||||
@ -1540,7 +1582,7 @@ mod tests {
|
|||||||
// Test reorg notification
|
// Test reorg notification
|
||||||
let chain_reorg = NewCanonicalChain::Reorg {
|
let chain_reorg = NewCanonicalChain::Reorg {
|
||||||
new: vec![block1a.clone(), block2a.clone()],
|
new: vec![block1a.clone(), block2a.clone()],
|
||||||
old: vec![block1.clone(), block2.clone()],
|
old: vec![block1.block.clone(), block2.block.clone()],
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use super::ExecutedBlock;
|
use super::ExecutedBlockWithTrieUpdates;
|
||||||
use alloy_consensus::BlockHeader;
|
use alloy_consensus::BlockHeader;
|
||||||
use alloy_primitives::{
|
use alloy_primitives::{
|
||||||
keccak256, map::B256HashMap, Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
|
keccak256, map::B256HashMap, Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
|
||||||
@ -23,7 +23,7 @@ pub struct MemoryOverlayStateProviderRef<'a, N: NodePrimitives = reth_primitives
|
|||||||
/// Historical state provider for state lookups that are not found in in-memory blocks.
|
/// Historical state provider for state lookups that are not found in in-memory blocks.
|
||||||
pub(crate) historical: Box<dyn StateProvider + 'a>,
|
pub(crate) historical: Box<dyn StateProvider + 'a>,
|
||||||
/// The collection of executed parent blocks. Expected order is newest to oldest.
|
/// The collection of executed parent blocks. Expected order is newest to oldest.
|
||||||
pub(crate) in_memory: Vec<ExecutedBlock<N>>,
|
pub(crate) in_memory: Vec<ExecutedBlockWithTrieUpdates<N>>,
|
||||||
/// Lazy-loaded in-memory trie data.
|
/// Lazy-loaded in-memory trie data.
|
||||||
pub(crate) trie_state: OnceLock<MemoryOverlayTrieState>,
|
pub(crate) trie_state: OnceLock<MemoryOverlayTrieState>,
|
||||||
}
|
}
|
||||||
@ -40,7 +40,10 @@ impl<'a, N: NodePrimitives> MemoryOverlayStateProviderRef<'a, N> {
|
|||||||
/// - `in_memory` - the collection of executed ancestor blocks in reverse.
|
/// - `in_memory` - the collection of executed ancestor blocks in reverse.
|
||||||
/// - `historical` - a historical state provider for the latest ancestor block stored in the
|
/// - `historical` - a historical state provider for the latest ancestor block stored in the
|
||||||
/// database.
|
/// database.
|
||||||
pub fn new(historical: Box<dyn StateProvider + 'a>, in_memory: Vec<ExecutedBlock<N>>) -> Self {
|
pub fn new(
|
||||||
|
historical: Box<dyn StateProvider + 'a>,
|
||||||
|
in_memory: Vec<ExecutedBlockWithTrieUpdates<N>>,
|
||||||
|
) -> Self {
|
||||||
Self { historical, in_memory, trie_state: OnceLock::new() }
|
Self { historical, in_memory, trie_state: OnceLock::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
in_memory::ExecutedBlock, CanonStateNotification, CanonStateNotifications,
|
in_memory::ExecutedBlockWithTrieUpdates, CanonStateNotification, CanonStateNotifications,
|
||||||
CanonStateSubscriptions,
|
CanonStateSubscriptions,
|
||||||
};
|
};
|
||||||
use alloy_consensus::{
|
use alloy_consensus::{
|
||||||
@ -204,17 +204,17 @@ impl<N: NodePrimitives> TestBlockBuilder<N> {
|
|||||||
fork
|
fork
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an [`ExecutedBlock`] with [`BlockNumber`], [`Receipts`] and parent hash.
|
/// Gets an [`ExecutedBlockWithTrieUpdates`] with [`BlockNumber`], [`Receipts`] and parent hash.
|
||||||
fn get_executed_block(
|
fn get_executed_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
block_number: BlockNumber,
|
block_number: BlockNumber,
|
||||||
receipts: Receipts,
|
receipts: Receipts,
|
||||||
parent_hash: B256,
|
parent_hash: B256,
|
||||||
) -> ExecutedBlock {
|
) -> ExecutedBlockWithTrieUpdates {
|
||||||
let block_with_senders = self.generate_random_block(block_number, parent_hash);
|
let block_with_senders = self.generate_random_block(block_number, parent_hash);
|
||||||
|
|
||||||
let (block, senders) = block_with_senders.split_sealed();
|
let (block, senders) = block_with_senders.split_sealed();
|
||||||
ExecutedBlock::new(
|
ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(block, senders)),
|
Arc::new(RecoveredBlock::new_sealed(block, senders)),
|
||||||
Arc::new(ExecutionOutcome::new(
|
Arc::new(ExecutionOutcome::new(
|
||||||
BundleState::default(),
|
BundleState::default(),
|
||||||
@ -227,22 +227,22 @@ impl<N: NodePrimitives> TestBlockBuilder<N> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates an [`ExecutedBlock`] that includes the given [`Receipts`].
|
/// Generates an [`ExecutedBlockWithTrieUpdates`] that includes the given [`Receipts`].
|
||||||
pub fn get_executed_block_with_receipts(
|
pub fn get_executed_block_with_receipts(
|
||||||
&mut self,
|
&mut self,
|
||||||
receipts: Receipts,
|
receipts: Receipts,
|
||||||
parent_hash: B256,
|
parent_hash: B256,
|
||||||
) -> ExecutedBlock {
|
) -> ExecutedBlockWithTrieUpdates {
|
||||||
let number = rand::thread_rng().gen::<u64>();
|
let number = rand::thread_rng().gen::<u64>();
|
||||||
self.get_executed_block(number, receipts, parent_hash)
|
self.get_executed_block(number, receipts, parent_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates an [`ExecutedBlock`] with the given [`BlockNumber`].
|
/// Generates an [`ExecutedBlockWithTrieUpdates`] with the given [`BlockNumber`].
|
||||||
pub fn get_executed_block_with_number(
|
pub fn get_executed_block_with_number(
|
||||||
&mut self,
|
&mut self,
|
||||||
block_number: BlockNumber,
|
block_number: BlockNumber,
|
||||||
parent_hash: B256,
|
parent_hash: B256,
|
||||||
) -> ExecutedBlock {
|
) -> ExecutedBlockWithTrieUpdates {
|
||||||
self.get_executed_block(block_number, Receipts { receipt_vec: vec![vec![]] }, parent_hash)
|
self.get_executed_block(block_number, Receipts { receipt_vec: vec![vec![]] }, parent_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ impl<N: NodePrimitives> TestBlockBuilder<N> {
|
|||||||
pub fn get_executed_blocks(
|
pub fn get_executed_blocks(
|
||||||
&mut self,
|
&mut self,
|
||||||
range: Range<u64>,
|
range: Range<u64>,
|
||||||
) -> impl Iterator<Item = ExecutedBlock> + '_ {
|
) -> impl Iterator<Item = ExecutedBlockWithTrieUpdates> + '_ {
|
||||||
let mut parent_hash = B256::default();
|
let mut parent_hash = B256::default();
|
||||||
range.map(move |number| {
|
range.map(move |number| {
|
||||||
let current_parent_hash = parent_hash;
|
let current_parent_hash = parent_hash;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use alloy_primitives::B256;
|
use alloy_primitives::B256;
|
||||||
use futures::{Stream, StreamExt};
|
use futures::{Stream, StreamExt};
|
||||||
use reth_chain_state::ExecutedBlock;
|
use reth_chain_state::ExecutedBlockWithTrieUpdates;
|
||||||
use reth_engine_primitives::{BeaconConsensusEngineEvent, BeaconEngineMessage, EngineTypes};
|
use reth_engine_primitives::{BeaconConsensusEngineEvent, BeaconEngineMessage, EngineTypes};
|
||||||
use reth_primitives::{NodePrimitives, RecoveredBlock};
|
use reth_primitives::{NodePrimitives, RecoveredBlock};
|
||||||
use reth_primitives_traits::Block;
|
use reth_primitives_traits::Block;
|
||||||
@ -245,7 +245,7 @@ pub enum EngineApiRequest<T: EngineTypes, N: NodePrimitives> {
|
|||||||
/// A request received from the consensus engine.
|
/// A request received from the consensus engine.
|
||||||
Beacon(BeaconEngineMessage<T>),
|
Beacon(BeaconEngineMessage<T>),
|
||||||
/// Request to insert an already executed block, e.g. via payload building.
|
/// Request to insert an already executed block, e.g. via payload building.
|
||||||
InsertExecutedBlock(ExecutedBlock<N>),
|
InsertExecutedBlock(ExecutedBlockWithTrieUpdates<N>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EngineTypes, N: NodePrimitives> Display for EngineApiRequest<T, N> {
|
impl<T: EngineTypes, N: NodePrimitives> Display for EngineApiRequest<T, N> {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::metrics::PersistenceMetrics;
|
use crate::metrics::PersistenceMetrics;
|
||||||
use alloy_consensus::BlockHeader;
|
use alloy_consensus::BlockHeader;
|
||||||
use alloy_eips::BlockNumHash;
|
use alloy_eips::BlockNumHash;
|
||||||
use reth_chain_state::ExecutedBlock;
|
use reth_chain_state::ExecutedBlockWithTrieUpdates;
|
||||||
use reth_errors::ProviderError;
|
use reth_errors::ProviderError;
|
||||||
use reth_primitives::{EthPrimitives, NodePrimitives};
|
use reth_primitives::{EthPrimitives, NodePrimitives};
|
||||||
use reth_provider::{
|
use reth_provider::{
|
||||||
@ -140,7 +140,7 @@ where
|
|||||||
|
|
||||||
fn on_save_blocks(
|
fn on_save_blocks(
|
||||||
&self,
|
&self,
|
||||||
blocks: Vec<ExecutedBlock<N::Primitives>>,
|
blocks: Vec<ExecutedBlockWithTrieUpdates<N::Primitives>>,
|
||||||
) -> Result<Option<BlockNumHash>, PersistenceError> {
|
) -> Result<Option<BlockNumHash>, PersistenceError> {
|
||||||
debug!(target: "engine::persistence", first=?blocks.first().map(|b| b.recovered_block.num_hash()), last=?blocks.last().map(|b| b.recovered_block.num_hash()), "Saving range of blocks");
|
debug!(target: "engine::persistence", first=?blocks.first().map(|b| b.recovered_block.num_hash()), last=?blocks.last().map(|b| b.recovered_block.num_hash()), "Saving range of blocks");
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
@ -181,7 +181,7 @@ pub enum PersistenceAction<N: NodePrimitives = EthPrimitives> {
|
|||||||
///
|
///
|
||||||
/// First, header, transaction, and receipt-related data should be written to static files.
|
/// First, header, transaction, and receipt-related data should be written to static files.
|
||||||
/// Then the execution history-related data will be written to the database.
|
/// Then the execution history-related data will be written to the database.
|
||||||
SaveBlocks(Vec<ExecutedBlock<N>>, oneshot::Sender<Option<BlockNumHash>>),
|
SaveBlocks(Vec<ExecutedBlockWithTrieUpdates<N>>, oneshot::Sender<Option<BlockNumHash>>),
|
||||||
|
|
||||||
/// Removes block data above the given block number from the database.
|
/// Removes block data above the given block number from the database.
|
||||||
///
|
///
|
||||||
@ -258,7 +258,7 @@ impl<T: NodePrimitives> PersistenceHandle<T> {
|
|||||||
/// If there are no blocks to persist, then `None` is sent in the sender.
|
/// If there are no blocks to persist, then `None` is sent in the sender.
|
||||||
pub fn save_blocks(
|
pub fn save_blocks(
|
||||||
&self,
|
&self,
|
||||||
blocks: Vec<ExecutedBlock<T>>,
|
blocks: Vec<ExecutedBlockWithTrieUpdates<T>>,
|
||||||
tx: oneshot::Sender<Option<BlockNumHash>>,
|
tx: oneshot::Sender<Option<BlockNumHash>>,
|
||||||
) -> Result<(), SendError<PersistenceAction<T>>> {
|
) -> Result<(), SendError<PersistenceAction<T>>> {
|
||||||
self.send_action(PersistenceAction::SaveBlocks(blocks, tx))
|
self.send_action(PersistenceAction::SaveBlocks(blocks, tx))
|
||||||
|
|||||||
@ -21,7 +21,8 @@ use alloy_rpc_types_engine::{
|
|||||||
use block_buffer::BlockBuffer;
|
use block_buffer::BlockBuffer;
|
||||||
use error::{InsertBlockError, InsertBlockErrorKind, InsertBlockFatalError};
|
use error::{InsertBlockError, InsertBlockErrorKind, InsertBlockFatalError};
|
||||||
use reth_chain_state::{
|
use reth_chain_state::{
|
||||||
CanonicalInMemoryState, ExecutedBlock, MemoryOverlayStateProvider, NewCanonicalChain,
|
CanonicalInMemoryState, ExecutedBlock, ExecutedBlockWithTrieUpdates,
|
||||||
|
MemoryOverlayStateProvider, NewCanonicalChain,
|
||||||
};
|
};
|
||||||
use reth_consensus::{Consensus, FullConsensus, PostExecutionInput};
|
use reth_consensus::{Consensus, FullConsensus, PostExecutionInput};
|
||||||
pub use reth_engine_primitives::InvalidBlockHook;
|
pub use reth_engine_primitives::InvalidBlockHook;
|
||||||
@ -102,13 +103,13 @@ pub struct TreeState<N: NodePrimitives = EthPrimitives> {
|
|||||||
/// __All__ unique executed blocks by block hash that are connected to the canonical chain.
|
/// __All__ unique executed blocks by block hash that are connected to the canonical chain.
|
||||||
///
|
///
|
||||||
/// This includes blocks of all forks.
|
/// This includes blocks of all forks.
|
||||||
blocks_by_hash: HashMap<B256, ExecutedBlock<N>>,
|
blocks_by_hash: HashMap<B256, ExecutedBlockWithTrieUpdates<N>>,
|
||||||
/// Executed blocks grouped by their respective block number.
|
/// Executed blocks grouped by their respective block number.
|
||||||
///
|
///
|
||||||
/// This maps unique block number to all known blocks for that height.
|
/// This maps unique block number to all known blocks for that height.
|
||||||
///
|
///
|
||||||
/// Note: there can be multiple blocks at the same height due to forks.
|
/// Note: there can be multiple blocks at the same height due to forks.
|
||||||
blocks_by_number: BTreeMap<BlockNumber, Vec<ExecutedBlock<N>>>,
|
blocks_by_number: BTreeMap<BlockNumber, Vec<ExecutedBlockWithTrieUpdates<N>>>,
|
||||||
/// Map of any parent block hash to its children.
|
/// Map of any parent block hash to its children.
|
||||||
parent_to_child: HashMap<B256, HashSet<B256>>,
|
parent_to_child: HashMap<B256, HashSet<B256>>,
|
||||||
/// Map of hash to trie updates for canonical blocks that are persisted but not finalized.
|
/// Map of hash to trie updates for canonical blocks that are persisted but not finalized.
|
||||||
@ -136,8 +137,8 @@ impl<N: NodePrimitives> TreeState<N> {
|
|||||||
self.blocks_by_hash.len()
|
self.blocks_by_hash.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`ExecutedBlock`] by hash.
|
/// Returns the [`ExecutedBlockWithTrieUpdates`] by hash.
|
||||||
fn executed_block_by_hash(&self, hash: B256) -> Option<&ExecutedBlock<N>> {
|
fn executed_block_by_hash(&self, hash: B256) -> Option<&ExecutedBlockWithTrieUpdates<N>> {
|
||||||
self.blocks_by_hash.get(&hash)
|
self.blocks_by_hash.get(&hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +151,7 @@ impl<N: NodePrimitives> TreeState<N> {
|
|||||||
/// newest to oldest. And the parent hash of the oldest block that is missing from the buffer.
|
/// newest to oldest. And the parent hash of the oldest block that is missing from the buffer.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the block for the given hash is not found.
|
/// Returns `None` if the block for the given hash is not found.
|
||||||
fn blocks_by_hash(&self, hash: B256) -> Option<(B256, Vec<ExecutedBlock<N>>)> {
|
fn blocks_by_hash(&self, hash: B256) -> Option<(B256, Vec<ExecutedBlockWithTrieUpdates<N>>)> {
|
||||||
let block = self.blocks_by_hash.get(&hash).cloned()?;
|
let block = self.blocks_by_hash.get(&hash).cloned()?;
|
||||||
let mut parent_hash = block.recovered_block().parent_hash();
|
let mut parent_hash = block.recovered_block().parent_hash();
|
||||||
let mut blocks = vec![block];
|
let mut blocks = vec![block];
|
||||||
@ -163,7 +164,7 @@ impl<N: NodePrimitives> TreeState<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert executed block into the state.
|
/// Insert executed block into the state.
|
||||||
fn insert_executed(&mut self, executed: ExecutedBlock<N>) {
|
fn insert_executed(&mut self, executed: ExecutedBlockWithTrieUpdates<N>) {
|
||||||
let hash = executed.recovered_block().hash();
|
let hash = executed.recovered_block().hash();
|
||||||
let parent_hash = executed.recovered_block().parent_hash();
|
let parent_hash = executed.recovered_block().parent_hash();
|
||||||
let block_number = executed.recovered_block().number();
|
let block_number = executed.recovered_block().number();
|
||||||
@ -194,7 +195,10 @@ impl<N: NodePrimitives> TreeState<N> {
|
|||||||
/// ## Returns
|
/// ## Returns
|
||||||
///
|
///
|
||||||
/// The removed block and the block hashes of its children.
|
/// The removed block and the block hashes of its children.
|
||||||
fn remove_by_hash(&mut self, hash: B256) -> Option<(ExecutedBlock<N>, HashSet<B256>)> {
|
fn remove_by_hash(
|
||||||
|
&mut self,
|
||||||
|
hash: B256,
|
||||||
|
) -> Option<(ExecutedBlockWithTrieUpdates<N>, HashSet<B256>)> {
|
||||||
let executed = self.blocks_by_hash.remove(&hash)?;
|
let executed = self.blocks_by_hash.remove(&hash)?;
|
||||||
|
|
||||||
// Remove this block from collection of children of its parent block.
|
// Remove this block from collection of children of its parent block.
|
||||||
@ -903,7 +907,8 @@ where
|
|||||||
// This is only done for in-memory blocks, because we should not have persisted any blocks
|
// This is only done for in-memory blocks, because we should not have persisted any blocks
|
||||||
// that are _above_ the current canonical head.
|
// that are _above_ the current canonical head.
|
||||||
while current_number > current_canonical_number {
|
while current_number > current_canonical_number {
|
||||||
if let Some(block) = self.executed_block_by_hash(current_hash)? {
|
if let Some(block) = self.state.tree_state.executed_block_by_hash(current_hash).cloned()
|
||||||
|
{
|
||||||
current_hash = block.recovered_block().parent_hash();
|
current_hash = block.recovered_block().parent_hash();
|
||||||
current_number -= 1;
|
current_number -= 1;
|
||||||
new_chain.push(block);
|
new_chain.push(block);
|
||||||
@ -931,7 +936,7 @@ where
|
|||||||
// If the canonical chain is ahead of the new chain,
|
// If the canonical chain is ahead of the new chain,
|
||||||
// gather all blocks until new head number.
|
// gather all blocks until new head number.
|
||||||
while current_canonical_number > current_number {
|
while current_canonical_number > current_number {
|
||||||
if let Some(block) = self.executed_block_by_hash(old_hash)? {
|
if let Some(block) = self.canonical_block_by_hash(old_hash)? {
|
||||||
old_chain.push(block.clone());
|
old_chain.push(block.clone());
|
||||||
old_hash = block.recovered_block().parent_hash();
|
old_hash = block.recovered_block().parent_hash();
|
||||||
current_canonical_number -= 1;
|
current_canonical_number -= 1;
|
||||||
@ -948,7 +953,7 @@ where
|
|||||||
// Walk both chains from specified hashes at same height until
|
// Walk both chains from specified hashes at same height until
|
||||||
// a common ancestor (fork block) is reached.
|
// a common ancestor (fork block) is reached.
|
||||||
while old_hash != current_hash {
|
while old_hash != current_hash {
|
||||||
if let Some(block) = self.executed_block_by_hash(old_hash)? {
|
if let Some(block) = self.canonical_block_by_hash(old_hash)? {
|
||||||
old_hash = block.recovered_block().parent_hash();
|
old_hash = block.recovered_block().parent_hash();
|
||||||
old_chain.push(block);
|
old_chain.push(block);
|
||||||
} else {
|
} else {
|
||||||
@ -957,7 +962,8 @@ where
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(block) = self.executed_block_by_hash(current_hash)? {
|
if let Some(block) = self.state.tree_state.executed_block_by_hash(current_hash).cloned()
|
||||||
|
{
|
||||||
current_hash = block.recovered_block().parent_hash();
|
current_hash = block.recovered_block().parent_hash();
|
||||||
new_chain.push(block);
|
new_chain.push(block);
|
||||||
} else {
|
} else {
|
||||||
@ -1524,7 +1530,7 @@ where
|
|||||||
/// Returns a batch of consecutive canonical blocks to persist in the range
|
/// Returns a batch of consecutive canonical blocks to persist in the range
|
||||||
/// `(last_persisted_number .. canonical_head - threshold]` . The expected
|
/// `(last_persisted_number .. canonical_head - threshold]` . The expected
|
||||||
/// order is oldest -> newest.
|
/// order is oldest -> newest.
|
||||||
fn get_canonical_blocks_to_persist(&self) -> Vec<ExecutedBlock<N>> {
|
fn get_canonical_blocks_to_persist(&self) -> Vec<ExecutedBlockWithTrieUpdates<N>> {
|
||||||
let mut blocks_to_persist = Vec::new();
|
let mut blocks_to_persist = Vec::new();
|
||||||
let mut current_hash = self.state.tree_state.canonical_block_hash();
|
let mut current_hash = self.state.tree_state.canonical_block_hash();
|
||||||
let last_persisted_number = self.persistence_state.last_persisted_block.number;
|
let last_persisted_number = self.persistence_state.last_persisted_block.number;
|
||||||
@ -1577,19 +1583,13 @@ where
|
|||||||
/// has in memory.
|
/// has in memory.
|
||||||
///
|
///
|
||||||
/// For finalized blocks, this will return `None`.
|
/// For finalized blocks, this will return `None`.
|
||||||
fn executed_block_by_hash(&self, hash: B256) -> ProviderResult<Option<ExecutedBlock<N>>> {
|
fn canonical_block_by_hash(&self, hash: B256) -> ProviderResult<Option<ExecutedBlock<N>>> {
|
||||||
trace!(target: "engine::tree", ?hash, "Fetching executed block by hash");
|
trace!(target: "engine::tree", ?hash, "Fetching executed block by hash");
|
||||||
// check memory first
|
// check memory first
|
||||||
let block = self.state.tree_state.executed_block_by_hash(hash).cloned();
|
if let Some(block) = self.state.tree_state.executed_block_by_hash(hash).cloned() {
|
||||||
|
return Ok(Some(block.block))
|
||||||
if block.is_some() {
|
|
||||||
return Ok(block)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some((_, updates)) = self.state.tree_state.persisted_trie_updates.get(&hash) else {
|
|
||||||
return Ok(None)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (block, senders) = self
|
let (block, senders) = self
|
||||||
.provider
|
.provider
|
||||||
.sealed_block_with_senders(hash.into(), TransactionVariant::WithHash)?
|
.sealed_block_with_senders(hash.into(), TransactionVariant::WithHash)?
|
||||||
@ -1603,7 +1603,6 @@ where
|
|||||||
|
|
||||||
Ok(Some(ExecutedBlock {
|
Ok(Some(ExecutedBlock {
|
||||||
recovered_block: Arc::new(RecoveredBlock::new_sealed(block, senders)),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(block, senders)),
|
||||||
trie: updates.clone(),
|
|
||||||
execution_output: Arc::new(execution_output),
|
execution_output: Arc::new(execution_output),
|
||||||
hashed_state: Arc::new(hashed_state),
|
hashed_state: Arc::new(hashed_state),
|
||||||
}))
|
}))
|
||||||
@ -2042,7 +2041,21 @@ where
|
|||||||
|
|
||||||
self.update_reorg_metrics(old.len());
|
self.update_reorg_metrics(old.len());
|
||||||
self.reinsert_reorged_blocks(new.clone());
|
self.reinsert_reorged_blocks(new.clone());
|
||||||
self.reinsert_reorged_blocks(old.clone());
|
// Try reinserting the reorged canonical chain. This is only possible if we have
|
||||||
|
// `persisted_trie_updatess` for those blocks.
|
||||||
|
let old = old
|
||||||
|
.iter()
|
||||||
|
.filter_map(|block| {
|
||||||
|
let (_, trie) = self
|
||||||
|
.state
|
||||||
|
.tree_state
|
||||||
|
.persisted_trie_updates
|
||||||
|
.get(&block.recovered_block.hash())
|
||||||
|
.cloned()?;
|
||||||
|
Some(ExecutedBlockWithTrieUpdates { block: block.clone(), trie })
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
self.reinsert_reorged_blocks(old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the tracked in-memory state with the new chain
|
// update the tracked in-memory state with the new chain
|
||||||
@ -2069,7 +2082,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This reinserts any blocks in the new chain that do not already exist in the tree
|
/// This reinserts any blocks in the new chain that do not already exist in the tree
|
||||||
fn reinsert_reorged_blocks(&mut self, new_chain: Vec<ExecutedBlock<N>>) {
|
fn reinsert_reorged_blocks(&mut self, new_chain: Vec<ExecutedBlockWithTrieUpdates<N>>) {
|
||||||
for block in new_chain {
|
for block in new_chain {
|
||||||
if self
|
if self
|
||||||
.state
|
.state
|
||||||
@ -2369,10 +2382,15 @@ where
|
|||||||
self.metrics.block_validation.record_state_root(&trie_output, root_elapsed.as_secs_f64());
|
self.metrics.block_validation.record_state_root(&trie_output, root_elapsed.as_secs_f64());
|
||||||
debug!(target: "engine::tree", ?root_elapsed, block=?block_num_hash, "Calculated state root");
|
debug!(target: "engine::tree", ?root_elapsed, block=?block_num_hash, "Calculated state root");
|
||||||
|
|
||||||
let executed: ExecutedBlock<N> = ExecutedBlock {
|
let executed: ExecutedBlockWithTrieUpdates<N> = ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(block),
|
block: ExecutedBlock {
|
||||||
execution_output: Arc::new(ExecutionOutcome::from((output, block_num_hash.number))),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
||||||
hashed_state: Arc::new(hashed_state),
|
sealed_block.as_ref().clone(),
|
||||||
|
block.senders().to_vec(),
|
||||||
|
)),
|
||||||
|
execution_output: Arc::new(ExecutionOutcome::from((output, block_num_hash.number))),
|
||||||
|
hashed_state: Arc::new(hashed_state),
|
||||||
|
},
|
||||||
trie: Arc::new(trie_output),
|
trie: Arc::new(trie_output),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2878,7 +2896,7 @@ mod tests {
|
|||||||
>,
|
>,
|
||||||
to_tree_tx: Sender<FromEngine<EngineApiRequest<EthEngineTypes, EthPrimitives>, Block>>,
|
to_tree_tx: Sender<FromEngine<EngineApiRequest<EthEngineTypes, EthPrimitives>, Block>>,
|
||||||
from_tree_rx: UnboundedReceiver<EngineApiEvent>,
|
from_tree_rx: UnboundedReceiver<EngineApiEvent>,
|
||||||
blocks: Vec<ExecutedBlock>,
|
blocks: Vec<ExecutedBlockWithTrieUpdates>,
|
||||||
action_rx: Receiver<PersistenceAction>,
|
action_rx: Receiver<PersistenceAction>,
|
||||||
executor_provider: MockExecutorProvider,
|
executor_provider: MockExecutorProvider,
|
||||||
block_builder: TestBlockBuilder,
|
block_builder: TestBlockBuilder,
|
||||||
@ -2949,7 +2967,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_blocks(mut self, blocks: Vec<ExecutedBlock>) -> Self {
|
fn with_blocks(mut self, blocks: Vec<ExecutedBlockWithTrieUpdates>) -> Self {
|
||||||
let mut blocks_by_hash = HashMap::default();
|
let mut blocks_by_hash = HashMap::default();
|
||||||
let mut blocks_by_number = BTreeMap::new();
|
let mut blocks_by_number = BTreeMap::new();
|
||||||
let mut state_by_hash = HashMap::default();
|
let mut state_by_hash = HashMap::default();
|
||||||
@ -3694,20 +3712,24 @@ mod tests {
|
|||||||
let chain_b = test_block_builder.create_fork(&last_block, 10);
|
let chain_b = test_block_builder.create_fork(&last_block, 10);
|
||||||
|
|
||||||
for block in &chain_a {
|
for block in &chain_a {
|
||||||
test_harness.tree.state.tree_state.insert_executed(ExecutedBlock {
|
test_harness.tree.state.tree_state.insert_executed(ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(block.clone()),
|
block: ExecutedBlock {
|
||||||
execution_output: Arc::new(ExecutionOutcome::default()),
|
recovered_block: Arc::new(block.clone()),
|
||||||
hashed_state: Arc::new(HashedPostState::default()),
|
execution_output: Arc::new(ExecutionOutcome::default()),
|
||||||
|
hashed_state: Arc::new(HashedPostState::default()),
|
||||||
|
},
|
||||||
trie: Arc::new(TrieUpdates::default()),
|
trie: Arc::new(TrieUpdates::default()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
test_harness.tree.state.tree_state.set_canonical_head(chain_a.last().unwrap().num_hash());
|
test_harness.tree.state.tree_state.set_canonical_head(chain_a.last().unwrap().num_hash());
|
||||||
|
|
||||||
for block in &chain_b {
|
for block in &chain_b {
|
||||||
test_harness.tree.state.tree_state.insert_executed(ExecutedBlock {
|
test_harness.tree.state.tree_state.insert_executed(ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(block.clone()),
|
block: ExecutedBlock {
|
||||||
execution_output: Arc::new(ExecutionOutcome::default()),
|
recovered_block: Arc::new(block.clone()),
|
||||||
hashed_state: Arc::new(HashedPostState::default()),
|
execution_output: Arc::new(ExecutionOutcome::default()),
|
||||||
|
hashed_state: Arc::new(HashedPostState::default()),
|
||||||
|
},
|
||||||
trie: Arc::new(TrieUpdates::default()),
|
trie: Arc::new(TrieUpdates::default()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use alloy_rpc_types_engine::{
|
|||||||
ExecutionPayloadV1, PayloadAttributes, PayloadId,
|
ExecutionPayloadV1, PayloadAttributes, PayloadId,
|
||||||
};
|
};
|
||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
use reth_chain_state::ExecutedBlock;
|
use reth_chain_state::ExecutedBlockWithTrieUpdates;
|
||||||
use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes};
|
use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes};
|
||||||
use reth_primitives::{EthPrimitives, SealedBlock};
|
use reth_primitives::{EthPrimitives, SealedBlock};
|
||||||
use reth_rpc_types_compat::engine::payload::{
|
use reth_rpc_types_compat::engine::payload::{
|
||||||
@ -28,7 +28,7 @@ pub struct EthBuiltPayload {
|
|||||||
/// The built block
|
/// The built block
|
||||||
pub(crate) block: Arc<SealedBlock>,
|
pub(crate) block: Arc<SealedBlock>,
|
||||||
/// Block execution data for the payload, if any.
|
/// Block execution data for the payload, if any.
|
||||||
pub(crate) executed_block: Option<ExecutedBlock>,
|
pub(crate) executed_block: Option<ExecutedBlockWithTrieUpdates>,
|
||||||
/// The fees of the block
|
/// The fees of the block
|
||||||
pub(crate) fees: U256,
|
pub(crate) fees: U256,
|
||||||
/// The blobs, proofs, and commitments in the block. If the block is pre-cancun, this will be
|
/// The blobs, proofs, and commitments in the block. If the block is pre-cancun, this will be
|
||||||
@ -48,7 +48,7 @@ impl EthBuiltPayload {
|
|||||||
id: PayloadId,
|
id: PayloadId,
|
||||||
block: Arc<SealedBlock>,
|
block: Arc<SealedBlock>,
|
||||||
fees: U256,
|
fees: U256,
|
||||||
executed_block: Option<ExecutedBlock>,
|
executed_block: Option<ExecutedBlockWithTrieUpdates>,
|
||||||
requests: Option<Requests>,
|
requests: Option<Requests>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { id, block, executed_block, fees, sidecars: Vec::new(), requests }
|
Self { id, block, executed_block, fees, sidecars: Vec::new(), requests }
|
||||||
@ -100,7 +100,7 @@ impl BuiltPayload for EthBuiltPayload {
|
|||||||
self.fees
|
self.fees
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executed_block(&self) -> Option<ExecutedBlock> {
|
fn executed_block(&self) -> Option<ExecutedBlockWithTrieUpdates> {
|
||||||
self.executed_block.clone()
|
self.executed_block.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ impl BuiltPayload for &EthBuiltPayload {
|
|||||||
(**self).fees()
|
(**self).fees()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executed_block(&self) -> Option<ExecutedBlock> {
|
fn executed_block(&self) -> Option<ExecutedBlockWithTrieUpdates> {
|
||||||
self.executed_block.clone()
|
self.executed_block.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ use reth_basic_payload_builder::{
|
|||||||
commit_withdrawals, is_better_payload, BuildArguments, BuildOutcome, PayloadBuilder,
|
commit_withdrawals, is_better_payload, BuildArguments, BuildOutcome, PayloadBuilder,
|
||||||
PayloadConfig,
|
PayloadConfig,
|
||||||
};
|
};
|
||||||
use reth_chain_state::ExecutedBlock;
|
use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates};
|
||||||
use reth_chainspec::{ChainSpec, ChainSpecProvider};
|
use reth_chainspec::{ChainSpec, ChainSpecProvider};
|
||||||
use reth_errors::RethError;
|
use reth_errors::RethError;
|
||||||
use reth_evm::{
|
use reth_evm::{
|
||||||
@ -481,13 +481,15 @@ where
|
|||||||
debug!(target: "payload_builder", id=%attributes.id, sealed_block_header = ?sealed_block.sealed_header(), "sealed built block");
|
debug!(target: "payload_builder", id=%attributes.id, sealed_block_header = ?sealed_block.sealed_header(), "sealed built block");
|
||||||
|
|
||||||
// create the executed block data
|
// create the executed block data
|
||||||
let executed = ExecutedBlock {
|
let executed = ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
block: ExecutedBlock {
|
||||||
sealed_block.as_ref().clone(),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
||||||
executed_senders,
|
sealed_block.as_ref().clone(),
|
||||||
)),
|
executed_senders,
|
||||||
execution_output: Arc::new(execution_outcome),
|
)),
|
||||||
hashed_state: Arc::new(hashed_state),
|
execution_output: Arc::new(execution_outcome),
|
||||||
|
hashed_state: Arc::new(hashed_state),
|
||||||
|
},
|
||||||
trie: Arc::new(trie_output),
|
trie: Arc::new(trie_output),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ use alloy_rpc_types_engine::PayloadId;
|
|||||||
use op_alloy_consensus::{OpDepositReceipt, OpTxType};
|
use op_alloy_consensus::{OpDepositReceipt, OpTxType};
|
||||||
use op_alloy_rpc_types_engine::OpPayloadAttributes;
|
use op_alloy_rpc_types_engine::OpPayloadAttributes;
|
||||||
use reth_basic_payload_builder::*;
|
use reth_basic_payload_builder::*;
|
||||||
use reth_chain_state::ExecutedBlock;
|
use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates};
|
||||||
use reth_chainspec::{ChainSpecProvider, EthereumHardforks};
|
use reth_chainspec::{ChainSpecProvider, EthereumHardforks};
|
||||||
use reth_evm::{
|
use reth_evm::{
|
||||||
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm,
|
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm,
|
||||||
@ -435,13 +435,15 @@ where
|
|||||||
debug!(target: "payload_builder", id=%ctx.attributes().payload_id(), sealed_block_header = ?sealed_block.header(), "sealed built block");
|
debug!(target: "payload_builder", id=%ctx.attributes().payload_id(), sealed_block_header = ?sealed_block.header(), "sealed built block");
|
||||||
|
|
||||||
// create the executed block data
|
// create the executed block data
|
||||||
let executed: ExecutedBlock<OpPrimitives> = ExecutedBlock {
|
let executed: ExecutedBlockWithTrieUpdates<OpPrimitives> = ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
block: ExecutedBlock {
|
||||||
sealed_block.as_ref().clone(),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
||||||
info.executed_senders,
|
sealed_block.as_ref().clone(),
|
||||||
)),
|
info.executed_senders,
|
||||||
execution_output: Arc::new(execution_outcome),
|
)),
|
||||||
hashed_state: Arc::new(hashed_state),
|
execution_output: Arc::new(execution_outcome),
|
||||||
|
hashed_state: Arc::new(hashed_state),
|
||||||
|
},
|
||||||
trie: Arc::new(trie_output),
|
trie: Arc::new(trie_output),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use op_alloy_consensus::{encode_holocene_extra_data, EIP1559ParamError};
|
|||||||
/// Re-export for use in downstream arguments.
|
/// Re-export for use in downstream arguments.
|
||||||
pub use op_alloy_rpc_types_engine::OpPayloadAttributes;
|
pub use op_alloy_rpc_types_engine::OpPayloadAttributes;
|
||||||
use op_alloy_rpc_types_engine::{OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4};
|
use op_alloy_rpc_types_engine::{OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4};
|
||||||
use reth_chain_state::ExecutedBlock;
|
use reth_chain_state::ExecutedBlockWithTrieUpdates;
|
||||||
use reth_chainspec::EthereumHardforks;
|
use reth_chainspec::EthereumHardforks;
|
||||||
use reth_optimism_chainspec::OpChainSpec;
|
use reth_optimism_chainspec::OpChainSpec;
|
||||||
use reth_optimism_primitives::{OpBlock, OpPrimitives, OpTransactionSigned};
|
use reth_optimism_primitives::{OpBlock, OpPrimitives, OpTransactionSigned};
|
||||||
@ -137,7 +137,7 @@ pub struct OpBuiltPayload {
|
|||||||
/// The built block
|
/// The built block
|
||||||
pub(crate) block: Arc<SealedBlock<OpBlock>>,
|
pub(crate) block: Arc<SealedBlock<OpBlock>>,
|
||||||
/// Block execution data for the payload, if any.
|
/// Block execution data for the payload, if any.
|
||||||
pub(crate) executed_block: Option<ExecutedBlock<OpPrimitives>>,
|
pub(crate) executed_block: Option<ExecutedBlockWithTrieUpdates<OpPrimitives>>,
|
||||||
/// The fees of the block
|
/// The fees of the block
|
||||||
pub(crate) fees: U256,
|
pub(crate) fees: U256,
|
||||||
/// The blobs, proofs, and commitments in the block. If the block is pre-cancun, this will be
|
/// The blobs, proofs, and commitments in the block. If the block is pre-cancun, this will be
|
||||||
@ -159,7 +159,7 @@ impl OpBuiltPayload {
|
|||||||
fees: U256,
|
fees: U256,
|
||||||
chain_spec: Arc<OpChainSpec>,
|
chain_spec: Arc<OpChainSpec>,
|
||||||
attributes: OpPayloadBuilderAttributes,
|
attributes: OpPayloadBuilderAttributes,
|
||||||
executed_block: Option<ExecutedBlock<OpPrimitives>>,
|
executed_block: Option<ExecutedBlockWithTrieUpdates<OpPrimitives>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { id, block, executed_block, fees, sidecars: Vec::new(), chain_spec, attributes }
|
Self { id, block, executed_block, fees, sidecars: Vec::new(), chain_spec, attributes }
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ impl BuiltPayload for OpBuiltPayload {
|
|||||||
self.fees
|
self.fees
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executed_block(&self) -> Option<ExecutedBlock<OpPrimitives>> {
|
fn executed_block(&self) -> Option<ExecutedBlockWithTrieUpdates<OpPrimitives>> {
|
||||||
self.executed_block.clone()
|
self.executed_block.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ impl BuiltPayload for &OpBuiltPayload {
|
|||||||
(**self).fees()
|
(**self).fees()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executed_block(&self) -> Option<ExecutedBlock<OpPrimitives>> {
|
fn executed_block(&self) -> Option<ExecutedBlockWithTrieUpdates<OpPrimitives>> {
|
||||||
self.executed_block.clone()
|
self.executed_block.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use alloy_primitives::U256;
|
use alloy_primitives::U256;
|
||||||
use reth_chain_state::{CanonStateNotification, ExecutedBlock};
|
use reth_chain_state::{CanonStateNotification, ExecutedBlockWithTrieUpdates};
|
||||||
use reth_payload_builder_primitives::PayloadBuilderError;
|
use reth_payload_builder_primitives::PayloadBuilderError;
|
||||||
use reth_payload_primitives::{PayloadKind, PayloadTypes};
|
use reth_payload_primitives::{PayloadKind, PayloadTypes};
|
||||||
use reth_primitives::Block;
|
use reth_primitives::Block;
|
||||||
@ -90,7 +90,7 @@ impl PayloadJob for TestPayloadJob {
|
|||||||
self.attr.payload_id(),
|
self.attr.payload_id(),
|
||||||
Arc::new(Block::default().seal_slow()),
|
Arc::new(Block::default().seal_slow()),
|
||||||
U256::ZERO,
|
U256::ZERO,
|
||||||
Some(ExecutedBlock::default()),
|
Some(ExecutedBlockWithTrieUpdates::default()),
|
||||||
Some(Default::default()),
|
Some(Default::default()),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use alloy_eips::{
|
|||||||
use alloy_primitives::{Address, B256, U256};
|
use alloy_primitives::{Address, B256, U256};
|
||||||
use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId};
|
use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use reth_chain_state::ExecutedBlock;
|
use reth_chain_state::ExecutedBlockWithTrieUpdates;
|
||||||
use reth_primitives::{NodePrimitives, SealedBlock};
|
use reth_primitives::{NodePrimitives, SealedBlock};
|
||||||
|
|
||||||
/// Represents a built payload type that contains a built `SealedBlock` and can be converted into
|
/// Represents a built payload type that contains a built `SealedBlock` and can be converted into
|
||||||
@ -22,7 +22,7 @@ pub trait BuiltPayload: Send + Sync + fmt::Debug {
|
|||||||
fn fees(&self) -> U256;
|
fn fees(&self) -> U256;
|
||||||
|
|
||||||
/// Returns the entire execution data for the built block, if available.
|
/// Returns the entire execution data for the built block, if available.
|
||||||
fn executed_block(&self) -> Option<ExecutedBlock<Self::Primitives>> {
|
fn executed_block(&self) -> Option<ExecutedBlockWithTrieUpdates<Self::Primitives>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -787,7 +787,7 @@ mod tests {
|
|||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use reth_chain_state::{
|
use reth_chain_state::{
|
||||||
test_utils::TestBlockBuilder, CanonStateNotification, CanonStateSubscriptions,
|
test_utils::TestBlockBuilder, CanonStateNotification, CanonStateSubscriptions,
|
||||||
CanonicalInMemoryState, ExecutedBlock, NewCanonicalChain,
|
CanonicalInMemoryState, ExecutedBlock, ExecutedBlockWithTrieUpdates, NewCanonicalChain,
|
||||||
};
|
};
|
||||||
use reth_chainspec::{
|
use reth_chainspec::{
|
||||||
ChainSpec, ChainSpecBuilder, ChainSpecProvider, EthereumHardfork, MAINNET,
|
ChainSpec, ChainSpecBuilder, ChainSpecProvider, EthereumHardfork, MAINNET,
|
||||||
@ -930,7 +930,7 @@ mod tests {
|
|||||||
let execution_outcome =
|
let execution_outcome =
|
||||||
ExecutionOutcome { receipts: block_receipts.into(), ..Default::default() };
|
ExecutionOutcome { receipts: block_receipts.into(), ..Default::default() };
|
||||||
|
|
||||||
ExecutedBlock::new(
|
ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)),
|
Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)),
|
||||||
execution_outcome.into(),
|
execution_outcome.into(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
@ -1059,7 +1059,7 @@ mod tests {
|
|||||||
let in_memory_block_senders =
|
let in_memory_block_senders =
|
||||||
first_in_mem_block.senders().expect("failed to recover senders");
|
first_in_mem_block.senders().expect("failed to recover senders");
|
||||||
let chain = NewCanonicalChain::Commit {
|
let chain = NewCanonicalChain::Commit {
|
||||||
new: vec![ExecutedBlock::new(
|
new: vec![ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(
|
Arc::new(RecoveredBlock::new_sealed(
|
||||||
first_in_mem_block.clone(),
|
first_in_mem_block.clone(),
|
||||||
in_memory_block_senders,
|
in_memory_block_senders,
|
||||||
@ -1095,13 +1095,15 @@ mod tests {
|
|||||||
assert_eq!(provider.find_block_by_hash(first_db_block.hash(), BlockSource::Pending)?, None);
|
assert_eq!(provider.find_block_by_hash(first_db_block.hash(), BlockSource::Pending)?, None);
|
||||||
|
|
||||||
// Insert the last block into the pending state
|
// Insert the last block into the pending state
|
||||||
provider.canonical_in_memory_state.set_pending_block(ExecutedBlock {
|
provider.canonical_in_memory_state.set_pending_block(ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
block: ExecutedBlock {
|
||||||
last_in_mem_block.clone(),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
||||||
Default::default(),
|
last_in_mem_block.clone(),
|
||||||
)),
|
Default::default(),
|
||||||
execution_output: Default::default(),
|
)),
|
||||||
hashed_state: Default::default(),
|
execution_output: Default::default(),
|
||||||
|
hashed_state: Default::default(),
|
||||||
|
},
|
||||||
trie: Default::default(),
|
trie: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1153,7 +1155,7 @@ mod tests {
|
|||||||
let in_memory_block_senders =
|
let in_memory_block_senders =
|
||||||
first_in_mem_block.senders().expect("failed to recover senders");
|
first_in_mem_block.senders().expect("failed to recover senders");
|
||||||
let chain = NewCanonicalChain::Commit {
|
let chain = NewCanonicalChain::Commit {
|
||||||
new: vec![ExecutedBlock::new(
|
new: vec![ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(
|
Arc::new(RecoveredBlock::new_sealed(
|
||||||
first_in_mem_block.clone(),
|
first_in_mem_block.clone(),
|
||||||
in_memory_block_senders,
|
in_memory_block_senders,
|
||||||
@ -1207,13 +1209,15 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Set the block as pending
|
// Set the block as pending
|
||||||
provider.canonical_in_memory_state.set_pending_block(ExecutedBlock {
|
provider.canonical_in_memory_state.set_pending_block(ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
block: ExecutedBlock {
|
||||||
block.clone(),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
||||||
block.senders().unwrap(),
|
block.clone(),
|
||||||
)),
|
block.senders().unwrap(),
|
||||||
execution_output: Default::default(),
|
)),
|
||||||
hashed_state: Default::default(),
|
execution_output: Default::default(),
|
||||||
|
hashed_state: Default::default(),
|
||||||
|
},
|
||||||
trie: Default::default(),
|
trie: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1290,7 +1294,7 @@ mod tests {
|
|||||||
let in_memory_block_senders =
|
let in_memory_block_senders =
|
||||||
first_in_mem_block.senders().expect("failed to recover senders");
|
first_in_mem_block.senders().expect("failed to recover senders");
|
||||||
let chain = NewCanonicalChain::Commit {
|
let chain = NewCanonicalChain::Commit {
|
||||||
new: vec![ExecutedBlock::new(
|
new: vec![ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(
|
Arc::new(RecoveredBlock::new_sealed(
|
||||||
first_in_mem_block.clone(),
|
first_in_mem_block.clone(),
|
||||||
in_memory_block_senders,
|
in_memory_block_senders,
|
||||||
@ -1855,7 +1859,7 @@ mod tests {
|
|||||||
.first()
|
.first()
|
||||||
.map(|block| {
|
.map(|block| {
|
||||||
let senders = block.senders().expect("failed to recover senders");
|
let senders = block.senders().expect("failed to recover senders");
|
||||||
ExecutedBlock::new(
|
ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)),
|
Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)),
|
||||||
Arc::new(ExecutionOutcome {
|
Arc::new(ExecutionOutcome {
|
||||||
bundle: BundleState::new(
|
bundle: BundleState::new(
|
||||||
@ -1990,15 +1994,19 @@ mod tests {
|
|||||||
|
|
||||||
// adding a pending block to state can test pending() and pending_state_by_hash() function
|
// adding a pending block to state can test pending() and pending_state_by_hash() function
|
||||||
let pending_block = database_blocks[database_blocks.len() - 1].clone();
|
let pending_block = database_blocks[database_blocks.len() - 1].clone();
|
||||||
only_database_provider.canonical_in_memory_state.set_pending_block(ExecutedBlock {
|
only_database_provider.canonical_in_memory_state.set_pending_block(
|
||||||
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
ExecutedBlockWithTrieUpdates {
|
||||||
pending_block.clone(),
|
block: ExecutedBlock {
|
||||||
Default::default(),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
||||||
)),
|
pending_block.clone(),
|
||||||
execution_output: Default::default(),
|
Default::default(),
|
||||||
hashed_state: Default::default(),
|
)),
|
||||||
trie: Default::default(),
|
execution_output: Default::default(),
|
||||||
});
|
hashed_state: Default::default(),
|
||||||
|
},
|
||||||
|
trie: Default::default(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pending_block.hash(),
|
pending_block.hash(),
|
||||||
@ -2113,13 +2121,15 @@ mod tests {
|
|||||||
|
|
||||||
// Set the pending block in memory
|
// Set the pending block in memory
|
||||||
let pending_block = in_memory_blocks.last().unwrap();
|
let pending_block = in_memory_blocks.last().unwrap();
|
||||||
provider.canonical_in_memory_state.set_pending_block(ExecutedBlock {
|
provider.canonical_in_memory_state.set_pending_block(ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
block: ExecutedBlock {
|
||||||
pending_block.clone(),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
||||||
Default::default(),
|
pending_block.clone(),
|
||||||
)),
|
Default::default(),
|
||||||
execution_output: Default::default(),
|
)),
|
||||||
hashed_state: Default::default(),
|
execution_output: Default::default(),
|
||||||
|
hashed_state: Default::default(),
|
||||||
|
},
|
||||||
trie: Default::default(),
|
trie: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1479,7 +1479,7 @@ mod tests {
|
|||||||
use alloy_primitives::B256;
|
use alloy_primitives::B256;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use reth_chain_state::{ExecutedBlock, NewCanonicalChain};
|
use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates, NewCanonicalChain};
|
||||||
use reth_db::models::AccountBeforeTx;
|
use reth_db::models::AccountBeforeTx;
|
||||||
use reth_execution_types::ExecutionOutcome;
|
use reth_execution_types::ExecutionOutcome;
|
||||||
use reth_primitives::{RecoveredBlock, SealedBlock};
|
use reth_primitives::{RecoveredBlock, SealedBlock};
|
||||||
@ -1581,7 +1581,7 @@ mod tests {
|
|||||||
let in_memory_block_senders =
|
let in_memory_block_senders =
|
||||||
first_in_mem_block.senders().expect("failed to recover senders");
|
first_in_mem_block.senders().expect("failed to recover senders");
|
||||||
let chain = NewCanonicalChain::Commit {
|
let chain = NewCanonicalChain::Commit {
|
||||||
new: vec![ExecutedBlock::new(
|
new: vec![ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(
|
Arc::new(RecoveredBlock::new_sealed(
|
||||||
first_in_mem_block.clone(),
|
first_in_mem_block.clone(),
|
||||||
in_memory_block_senders,
|
in_memory_block_senders,
|
||||||
@ -1623,13 +1623,15 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Insert the last block into the pending state
|
// Insert the last block into the pending state
|
||||||
provider.canonical_in_memory_state.set_pending_block(ExecutedBlock {
|
provider.canonical_in_memory_state.set_pending_block(ExecutedBlockWithTrieUpdates {
|
||||||
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
block: ExecutedBlock {
|
||||||
last_in_mem_block.clone(),
|
recovered_block: Arc::new(RecoveredBlock::new_sealed(
|
||||||
Default::default(),
|
last_in_mem_block.clone(),
|
||||||
)),
|
Default::default(),
|
||||||
execution_output: Default::default(),
|
)),
|
||||||
hashed_state: Default::default(),
|
execution_output: Default::default(),
|
||||||
|
hashed_state: Default::default(),
|
||||||
|
},
|
||||||
trie: Default::default(),
|
trie: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1689,7 +1691,7 @@ mod tests {
|
|||||||
let in_memory_block_senders =
|
let in_memory_block_senders =
|
||||||
first_in_mem_block.senders().expect("failed to recover senders");
|
first_in_mem_block.senders().expect("failed to recover senders");
|
||||||
let chain = NewCanonicalChain::Commit {
|
let chain = NewCanonicalChain::Commit {
|
||||||
new: vec![ExecutedBlock::new(
|
new: vec![ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(
|
Arc::new(RecoveredBlock::new_sealed(
|
||||||
first_in_mem_block.clone(),
|
first_in_mem_block.clone(),
|
||||||
in_memory_block_senders,
|
in_memory_block_senders,
|
||||||
@ -1795,7 +1797,7 @@ mod tests {
|
|||||||
.first()
|
.first()
|
||||||
.map(|block| {
|
.map(|block| {
|
||||||
let senders = block.senders().expect("failed to recover senders");
|
let senders = block.senders().expect("failed to recover senders");
|
||||||
ExecutedBlock::new(
|
ExecutedBlockWithTrieUpdates::new(
|
||||||
Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)),
|
Arc::new(RecoveredBlock::new_sealed(block.clone(), senders)),
|
||||||
Arc::new(ExecutionOutcome {
|
Arc::new(ExecutionOutcome {
|
||||||
bundle: BundleState::new(
|
bundle: BundleState::new(
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use crate::{
|
|||||||
StorageLocation, TrieWriter,
|
StorageLocation, TrieWriter,
|
||||||
};
|
};
|
||||||
use alloy_consensus::BlockHeader;
|
use alloy_consensus::BlockHeader;
|
||||||
use reth_chain_state::ExecutedBlock;
|
use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates};
|
||||||
use reth_db::transaction::{DbTx, DbTxMut};
|
use reth_db::transaction::{DbTx, DbTxMut};
|
||||||
use reth_errors::ProviderResult;
|
use reth_errors::ProviderResult;
|
||||||
use reth_primitives::{NodePrimitives, StaticFileSegment};
|
use reth_primitives::{NodePrimitives, StaticFileSegment};
|
||||||
@ -132,7 +132,7 @@ where
|
|||||||
+ StaticFileProviderFactory,
|
+ StaticFileProviderFactory,
|
||||||
{
|
{
|
||||||
/// Writes executed blocks and receipts to storage.
|
/// Writes executed blocks and receipts to storage.
|
||||||
pub fn save_blocks<N>(&self, blocks: Vec<ExecutedBlock<N>>) -> ProviderResult<()>
|
pub fn save_blocks<N>(&self, blocks: Vec<ExecutedBlockWithTrieUpdates<N>>) -> ProviderResult<()>
|
||||||
where
|
where
|
||||||
N: NodePrimitives<SignedTx: SignedTransaction>,
|
N: NodePrimitives<SignedTx: SignedTransaction>,
|
||||||
ProviderDB: BlockWriter<Block = N::Block> + StateWriter<Receipt = N::Receipt>,
|
ProviderDB: BlockWriter<Block = N::Block> + StateWriter<Receipt = N::Receipt>,
|
||||||
@ -160,7 +160,11 @@ where
|
|||||||
// * trie updates (cannot naively extend, need helper)
|
// * trie updates (cannot naively extend, need helper)
|
||||||
// * indices (already done basically)
|
// * indices (already done basically)
|
||||||
// Insert the blocks
|
// Insert the blocks
|
||||||
for ExecutedBlock { recovered_block, execution_output, hashed_state, trie } in blocks {
|
for ExecutedBlockWithTrieUpdates {
|
||||||
|
block: ExecutedBlock { recovered_block, execution_output, hashed_state },
|
||||||
|
trie,
|
||||||
|
} in blocks
|
||||||
|
{
|
||||||
self.database()
|
self.database()
|
||||||
.insert_block(Arc::unwrap_or_clone(recovered_block), StorageLocation::Both)?;
|
.insert_block(Arc::unwrap_or_clone(recovered_block), StorageLocation::Both)?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user