Skip to main content

reth_storage_api/
block_writer.rs

1use crate::NodePrimitivesProvider;
2use alloc::vec::Vec;
3use alloy_primitives::BlockNumber;
4use reth_db_models::StoredBlockBodyIndices;
5use reth_execution_types::{Chain, ExecutionOutcome};
6use reth_primitives_traits::{Block, NodePrimitives, RecoveredBlock};
7use reth_storage_errors::provider::ProviderResult;
8use reth_trie_common::HashedPostStateSorted;
9
10/// `BlockExecution` Writer
11pub trait BlockExecutionWriter:
12    NodePrimitivesProvider<Primitives: NodePrimitives<Block = Self::Block>> + BlockWriter
13{
14    /// Take all of the blocks above the provided number and their execution result
15    ///
16    /// The passed block number will stay in the database.
17    fn take_block_and_execution_above(
18        &self,
19        block: BlockNumber,
20    ) -> ProviderResult<Chain<Self::Primitives>>;
21
22    /// Remove all of the blocks above the provided number and their execution result
23    ///
24    /// The passed block number will stay in the database.
25    ///
26    /// Returns the persistence frontiers after removal.
27    fn remove_block_and_execution_above(
28        &self,
29        block: BlockNumber,
30    ) -> ProviderResult<PersistenceFrontiers>;
31}
32
33impl<T: BlockExecutionWriter> BlockExecutionWriter for &T {
34    fn take_block_and_execution_above(
35        &self,
36        block: BlockNumber,
37    ) -> ProviderResult<Chain<Self::Primitives>> {
38        (*self).take_block_and_execution_above(block)
39    }
40
41    fn remove_block_and_execution_above(
42        &self,
43        block: BlockNumber,
44    ) -> ProviderResult<PersistenceFrontiers> {
45        (*self).remove_block_and_execution_above(block)
46    }
47}
48
49/// The database and state/trie persistence frontiers.
50///
51/// The state/trie frontier is never ahead of the database frontier.
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53pub struct PersistenceFrontiers {
54    /// The highest block whose non-state/trie outputs are persisted.
55    pub db_tip: BlockNumber,
56    /// The highest block whose state/trie outputs are persisted.
57    pub partial_state_trie: BlockNumber,
58}
59
60/// Block Writer
61#[auto_impl::auto_impl(&, Arc, Box)]
62pub trait BlockWriter {
63    /// The body this writer can write.
64    type Block: Block;
65    /// The receipt type for [`ExecutionOutcome`].
66    type Receipt: Send + Sync;
67
68    /// Insert full block and make it canonical. Parent tx num and transition id is taken from
69    /// parent block in database.
70    ///
71    /// Return [`StoredBlockBodyIndices`] that contains indices of the first and last transactions
72    /// and transition in the block.
73    fn insert_block(
74        &self,
75        block: &RecoveredBlock<Self::Block>,
76    ) -> ProviderResult<StoredBlockBodyIndices>;
77
78    /// Appends a batch of block bodies extending the canonical chain. This is invoked during
79    /// `Bodies` stage and does not write to `TransactionHashNumbers` and `TransactionSenders`
80    /// tables which are populated on later stages.
81    ///
82    /// Bodies are passed as [`Option`]s, if body is `None` the corresponding block is empty.
83    fn append_block_bodies(
84        &self,
85        bodies: Vec<(BlockNumber, Option<&<Self::Block as Block>::Body>)>,
86    ) -> ProviderResult<()>;
87
88    /// Removes all blocks above the given block number from the database.
89    ///
90    /// Note: This does not remove state or execution data.
91    fn remove_blocks_above(&self, block: BlockNumber) -> ProviderResult<()>;
92
93    /// Removes all block bodies above the given block number from the database.
94    fn remove_bodies_above(&self, block: BlockNumber) -> ProviderResult<()>;
95
96    /// Appends a batch of sealed blocks to the blockchain, including sender information, and
97    /// updates the post-state.
98    ///
99    /// Inserts the blocks into the database and updates the state with
100    /// provided execution state. The database's trie state is _not_ updated.
101    ///
102    /// # Parameters
103    ///
104    /// - `blocks`: Vector of `RecoveredBlock` instances to append.
105    /// - `state`: Post-state information to update after appending.
106    ///
107    /// # Returns
108    ///
109    /// Returns `Ok(())` on success, or an error if any operation fails.
110    fn append_blocks_with_state(
111        &self,
112        blocks: Vec<RecoveredBlock<Self::Block>>,
113        execution_outcome: &ExecutionOutcome<Self::Receipt>,
114        hashed_state: HashedPostStateSorted,
115    ) -> ProviderResult<()>;
116}