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
//! [`ExecutionDataProvider`] implementations used by the tree.

use alloy_primitives::{BlockHash, BlockNumber};
use reth_primitives::ForkBlock;
use reth_provider::{BlockExecutionForkProvider, ExecutionDataProvider, ExecutionOutcome};
use std::collections::BTreeMap;

/// Structure that combines references of required data to be a [`ExecutionDataProvider`].
#[derive(Clone, Debug)]
pub struct BundleStateDataRef<'a> {
    /// The execution outcome after execution of one or more transactions and/or blocks.
    pub execution_outcome: &'a ExecutionOutcome,
    /// The blocks in the sidechain.
    pub sidechain_block_hashes: &'a BTreeMap<BlockNumber, BlockHash>,
    /// The blocks in the canonical chain.
    pub canonical_block_hashes: &'a BTreeMap<BlockNumber, BlockHash>,
    /// Canonical fork
    pub canonical_fork: ForkBlock,
}

impl<'a> ExecutionDataProvider for BundleStateDataRef<'a> {
    fn execution_outcome(&self) -> &ExecutionOutcome {
        self.execution_outcome
    }

    fn block_hash(&self, block_number: BlockNumber) -> Option<BlockHash> {
        let block_hash = self.sidechain_block_hashes.get(&block_number).copied();
        if block_hash.is_some() {
            return block_hash;
        }

        self.canonical_block_hashes.get(&block_number).copied()
    }
}

impl<'a> BlockExecutionForkProvider for BundleStateDataRef<'a> {
    fn canonical_fork(&self) -> ForkBlock {
        self.canonical_fork
    }
}

/// Structure that owns the relevant data needs to be a [`ExecutionDataProvider`]
#[derive(Clone, Debug)]
pub struct ExecutionData {
    /// Execution outcome.
    pub execution_outcome: ExecutionOutcome,
    /// Parent block hashes needs for evm BLOCKHASH opcode.
    /// NOTE: it does not mean that all hashes are there but all until finalized are there.
    /// Other hashes can be obtained from provider
    pub parent_block_hashes: BTreeMap<BlockNumber, BlockHash>,
    /// Canonical block where state forked from.
    pub canonical_fork: ForkBlock,
}

impl ExecutionDataProvider for ExecutionData {
    fn execution_outcome(&self) -> &ExecutionOutcome {
        &self.execution_outcome
    }

    fn block_hash(&self, block_number: BlockNumber) -> Option<BlockHash> {
        self.parent_block_hashes.get(&block_number).copied()
    }
}

impl BlockExecutionForkProvider for ExecutionData {
    fn canonical_fork(&self) -> ForkBlock {
        self.canonical_fork
    }
}