revme/cmd/blockchaintest/
pre_block.rs

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