reth_provider/traits/
block.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use alloy_consensus::Header;
use alloy_primitives::BlockNumber;
use reth_db_api::models::StoredBlockBodyIndices;
use reth_execution_types::{Chain, ExecutionOutcome};
use reth_primitives::SealedBlockWithSenders;
use reth_storage_errors::provider::ProviderResult;
use reth_trie::{updates::TrieUpdates, HashedPostStateSorted};

/// An enum that represents the storage location for a piece of data.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum StorageLocation {
    /// Write only to static files.
    StaticFiles,
    /// Write only to the database.
    Database,
    /// Write to both the database and static files.
    Both,
}

impl StorageLocation {
    /// Returns true if the storage location includes static files.
    pub const fn static_files(&self) -> bool {
        matches!(self, Self::StaticFiles | Self::Both)
    }

    /// Returns true if the storage location includes the database.
    pub const fn database(&self) -> bool {
        matches!(self, Self::Database | Self::Both)
    }
}

/// BlockExecution Writer
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait BlockExecutionWriter: BlockWriter + Send + Sync {
    /// Take all of the blocks above the provided number and their execution result
    ///
    /// The passed block number will stay in the database.
    fn take_block_and_execution_above(
        &self,
        block: BlockNumber,
        remove_transactions_from: StorageLocation,
    ) -> ProviderResult<Chain>;

    /// Remove all of the blocks above the provided number and their execution result
    ///
    /// The passed block number will stay in the database.
    fn remove_block_and_execution_above(
        &self,
        block: BlockNumber,
        remove_transactions_from: StorageLocation,
    ) -> ProviderResult<()>;
}

/// This just receives state, or [`ExecutionOutcome`], from the provider
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait StateReader: Send + Sync {
    /// Get the [`ExecutionOutcome`] for the given block
    fn get_state(&self, block: BlockNumber) -> ProviderResult<Option<ExecutionOutcome>>;
}

/// Block Writer
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait BlockWriter: Send + Sync {
    /// The body this writer can write.
    type Body: Send + Sync;

    /// Insert full block and make it canonical. Parent tx num and transition id is taken from
    /// parent block in database.
    ///
    /// Return [StoredBlockBodyIndices] that contains indices of the first and last transactions and
    /// transition in the block.
    fn insert_block(
        &self,
        block: SealedBlockWithSenders<Header, Self::Body>,
        write_transactions_to: StorageLocation,
    ) -> ProviderResult<StoredBlockBodyIndices>;

    /// Appends a batch of block bodies extending the canonical chain. This is invoked during
    /// `Bodies` stage and does not write to `TransactionHashNumbers` and `TransactionSenders`
    /// tables which are populated on later stages.
    ///
    /// Bodies are passed as [`Option`]s, if body is `None` the corresponding block is empty.
    fn append_block_bodies(
        &self,
        bodies: Vec<(BlockNumber, Option<Self::Body>)>,
        write_transactions_to: StorageLocation,
    ) -> ProviderResult<()>;

    /// Removes all blocks above the given block number from the database.
    ///
    /// Note: This does not remove state or execution data.
    fn remove_blocks_above(
        &self,
        block: BlockNumber,
        remove_transactions_from: StorageLocation,
    ) -> ProviderResult<()>;

    /// Removes all block bodies above the given block number from the database.
    fn remove_bodies_above(
        &self,
        block: BlockNumber,
        remove_transactions_from: StorageLocation,
    ) -> ProviderResult<()>;

    /// Appends a batch of sealed blocks to the blockchain, including sender information, and
    /// updates the post-state.
    ///
    /// Inserts the blocks into the database and updates the state with
    /// provided `BundleState`.
    ///
    /// # Parameters
    ///
    /// - `blocks`: Vector of `SealedBlockWithSenders` instances to append.
    /// - `state`: Post-state information to update after appending.
    ///
    /// # Returns
    ///
    /// Returns `Ok(())` on success, or an error if any operation fails.
    fn append_blocks_with_state(
        &self,
        blocks: Vec<SealedBlockWithSenders<Header, Self::Body>>,
        execution_outcome: ExecutionOutcome,
        hashed_state: HashedPostStateSorted,
        trie_updates: TrieUpdates,
    ) -> ProviderResult<()>;
}