Skip to main content

reth_execution_types/
execute.rs

1use alloc::sync::Arc;
2use alloy_primitives::{Address, B256, U256};
3use reth_primitives_traits::{Account, Block, Bytecode, RecoveredBlock};
4use reth_trie_common::bundle_state::{BundleAccount, BundleState};
5
6pub use evm2::block::BlockExecutionResult;
7
8/// [`BlockExecutionResult`] combined with state.
9#[derive(
10    Debug,
11    Clone,
12    PartialEq,
13    Eq,
14    derive_more::AsRef,
15    derive_more::AsMut,
16    derive_more::Deref,
17    derive_more::DerefMut,
18)]
19pub struct BlockExecutionOutput<T> {
20    /// All the receipts of the transactions in the block.
21    #[as_ref]
22    #[as_mut]
23    #[deref]
24    #[deref_mut]
25    pub result: BlockExecutionResult<T>,
26    /// The changed state of the block after execution.
27    pub state: BundleState,
28}
29
30impl<T> From<evm2::block::BlockExecutionOutput<T>> for BlockExecutionOutput<T> {
31    fn from(output: evm2::block::BlockExecutionOutput<T>) -> Self {
32        Self { result: output.result, state: output.state }
33    }
34}
35
36impl<T> BlockExecutionOutput<T> {
37    /// Combines execution results with their persistent state.
38    pub const fn new(result: BlockExecutionResult<T>, state: BundleState) -> Self {
39        Self { result, state }
40    }
41
42    /// Return bytecode if known.
43    pub fn bytecode(&self, code_hash: &B256) -> Option<Bytecode> {
44        self.state.bytecode(code_hash).map(Bytecode)
45    }
46
47    /// Get account if account is known.
48    pub fn account(&self, address: &Address) -> Option<Option<Account>> {
49        self.state.account(address).map(|a| a.info.as_ref().map(Into::into))
50    }
51
52    /// Returns the state [`BundleAccount`] for the given address.
53    pub fn account_state(&self, address: &Address) -> Option<&BundleAccount> {
54        self.state.account(address)
55    }
56
57    /// Get storage if value is known.
58    ///
59    /// This means that depending on status we can potentially return `U256::ZERO`.
60    pub fn storage(&self, address: &Address, storage_key: U256) -> Option<U256> {
61        self.state.storage(address, storage_key)
62    }
63}
64
65impl<T> Default for BlockExecutionOutput<T> {
66    fn default() -> Self {
67        Self {
68            result: BlockExecutionResult {
69                receipts: Default::default(),
70                requests: Default::default(),
71                gas_used: 0,
72                blob_gas_used: 0,
73            },
74            state: Default::default(),
75        }
76    }
77}
78
79/// A recovered block and its shared execution output.
80///
81/// The execution output contains the block's receipts.
82#[derive(Debug)]
83pub struct RecoveredBlockAndExecutionOutput<B: Block, R> {
84    block: Arc<RecoveredBlock<B>>,
85    execution_output: Arc<BlockExecutionOutput<R>>,
86}
87
88impl<B: Block, R> RecoveredBlockAndExecutionOutput<B, R> {
89    /// Creates a block with its execution output.
90    pub const fn new(
91        block: Arc<RecoveredBlock<B>>,
92        execution_output: Arc<BlockExecutionOutput<R>>,
93    ) -> Self {
94        Self { block, execution_output }
95    }
96
97    /// Returns the recovered block.
98    pub const fn block(&self) -> &Arc<RecoveredBlock<B>> {
99        &self.block
100    }
101
102    /// Returns the execution output.
103    pub const fn execution_output(&self) -> &Arc<BlockExecutionOutput<R>> {
104        &self.execution_output
105    }
106
107    /// Consumes the container and returns its shared parts.
108    pub fn into_parts(self) -> (Arc<RecoveredBlock<B>>, Arc<BlockExecutionOutput<R>>) {
109        (self.block, self.execution_output)
110    }
111}