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 + Send + Sync
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 fn remove_block_and_execution_above(&self, block: BlockNumber) -> ProviderResult<()>;
26}
27
28impl<T: BlockExecutionWriter> BlockExecutionWriter for &T {
29 fn take_block_and_execution_above(
30 &self,
31 block: BlockNumber,
32 ) -> ProviderResult<Chain<Self::Primitives>> {
33 (*self).take_block_and_execution_above(block)
34 }
35
36 fn remove_block_and_execution_above(&self, block: BlockNumber) -> ProviderResult<()> {
37 (*self).remove_block_and_execution_above(block)
38 }
39}
40
41/// Block Writer
42#[auto_impl::auto_impl(&, Arc, Box)]
43pub trait BlockWriter: Send + Sync {
44 /// The body this writer can write.
45 type Block: Block;
46 /// The receipt type for [`ExecutionOutcome`].
47 type Receipt: Send + Sync;
48
49 /// Insert full block and make it canonical. Parent tx num and transition id is taken from
50 /// parent block in database.
51 ///
52 /// Return [`StoredBlockBodyIndices`] that contains indices of the first and last transactions
53 /// and transition in the block.
54 fn insert_block(
55 &self,
56 block: RecoveredBlock<Self::Block>,
57 ) -> ProviderResult<StoredBlockBodyIndices>;
58
59 /// Appends a batch of block bodies extending the canonical chain. This is invoked during
60 /// `Bodies` stage and does not write to `TransactionHashNumbers` and `TransactionSenders`
61 /// tables which are populated on later stages.
62 ///
63 /// Bodies are passed as [`Option`]s, if body is `None` the corresponding block is empty.
64 fn append_block_bodies(
65 &self,
66 bodies: Vec<(BlockNumber, Option<<Self::Block as Block>::Body>)>,
67 ) -> ProviderResult<()>;
68
69 /// Removes all blocks above the given block number from the database.
70 ///
71 /// Note: This does not remove state or execution data.
72 fn remove_blocks_above(&self, block: BlockNumber) -> ProviderResult<()>;
73
74 /// Removes all block bodies above the given block number from the database.
75 fn remove_bodies_above(&self, block: BlockNumber) -> ProviderResult<()>;
76
77 /// Appends a batch of sealed blocks to the blockchain, including sender information, and
78 /// updates the post-state.
79 ///
80 /// Inserts the blocks into the database and updates the state with
81 /// provided `BundleState`. The database's trie state is _not_ updated.
82 ///
83 /// # Parameters
84 ///
85 /// - `blocks`: Vector of `RecoveredBlock` instances to append.
86 /// - `state`: Post-state information to update after appending.
87 ///
88 /// # Returns
89 ///
90 /// Returns `Ok(())` on success, or an error if any operation fails.
91 fn append_blocks_with_state(
92 &self,
93 blocks: Vec<RecoveredBlock<Self::Block>>,
94 execution_outcome: &ExecutionOutcome<Self::Receipt>,
95 hashed_state: HashedPostStateSorted,
96 ) -> ProviderResult<()>;
97}