revme/cmd/blockchaintest/
pre_block.rs

1//! Pre block state transition
2
3use revm::{
4    context::{Block, ContextTr},
5    database::{Database, State},
6    handler::EvmTr,
7    primitives::{address, hardfork::SpecId, Address, B256},
8    SystemCallCommitEvm,
9};
10
11/// Pre block state transition
12///
13/// # Note
14///
15/// Contains only withdrawal processing. And it is missing block hash system call.
16pub fn pre_block_transition<
17    'a,
18    DB: Database + 'a,
19    EVM: SystemCallCommitEvm<Error: core::fmt::Debug>
20        + EvmTr<Context: ContextTr<Db = &'a mut State<DB>>>,
21>(
22    evm: &mut EVM,
23    spec: SpecId,
24    parent_block_hash: Option<B256>,
25    parent_beacon_block_root: Option<B256>,
26) {
27    // skip system calls for block number 0 (Gensis block)
28    if evm.ctx().block().number() == 0 {
29        return;
30    }
31
32    // blockhash system call
33    if let Some(parent_block_hash) = parent_block_hash {
34        system_call_eip2935_blockhash(spec, parent_block_hash, evm);
35    }
36
37    if let Some(parent_beacon_block_root) = parent_beacon_block_root {
38        system_call_eip4788_beacon_root(spec, parent_beacon_block_root, evm);
39    }
40}
41
42pub const HISTORY_STORAGE_ADDRESS: Address = address!("0x0000F90827F1C53a10cb7A02335B175320002935");
43
44/// Blockhash system callEIP-2935
45#[inline]
46pub(crate) fn system_call_eip2935_blockhash(
47    spec: SpecId,
48    parent_block_hash: B256,
49    evm: &mut impl SystemCallCommitEvm<Error: core::fmt::Debug>,
50) -> bool {
51    if !spec.is_enabled_in(SpecId::PRAGUE) {
52        return true;
53    }
54
55    let _ = match evm.system_call_commit(HISTORY_STORAGE_ADDRESS, parent_block_hash.0.into()) {
56        Ok(res) => res,
57        Err(e) => {
58            panic!("System call failed: {e:?}");
59        }
60    };
61
62    true
63}
64
65pub const BEACON_ROOTS_ADDRESS: Address = address!("000F3df6D732807Ef1319fB7B8bB8522d0Beac02");
66
67/// Beacon root system call EIP-4788
68pub(crate) fn system_call_eip4788_beacon_root(
69    spec: SpecId,
70    parent_beacon_block_root: B256,
71    evm: &mut impl SystemCallCommitEvm<Error: core::fmt::Debug>,
72) -> bool {
73    if !spec.is_enabled_in(SpecId::CANCUN) {
74        return true;
75    }
76
77    let _ = match evm.system_call_commit(BEACON_ROOTS_ADDRESS, parent_beacon_block_root.0.into()) {
78        Ok(res) => res,
79        Err(e) => {
80            panic!("System call failed: {e:?}");
81        }
82    };
83
84    true
85}