Skip to main content

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) -> Result<(), EVM::Error> {
26    // skip system calls for block number 0 (Gensis block)
27    if evm.ctx().block().number() == 0 {
28        return Ok(());
29    }
30
31    // beacon root system call, which runs before the blockhash one
32    if let Some(parent_beacon_block_root) = parent_beacon_block_root {
33        if spec.is_enabled_in(SpecId::CANCUN) {
34            system_call_eip4788_beacon_root(evm, parent_beacon_block_root)?;
35        }
36    }
37
38    // blockhash system call
39    if let Some(parent_block_hash) = parent_block_hash {
40        if spec.is_enabled_in(SpecId::PRAGUE) {
41            system_call_eip2935_blockhash(evm, parent_block_hash)?;
42        }
43    }
44
45    Ok(())
46}
47
48pub const HISTORY_STORAGE_ADDRESS: Address = address!("0x0000F90827F1C53a10cb7A02335B175320002935");
49
50/// Blockhash system callEIP-2935
51#[inline]
52pub(crate) fn system_call_eip2935_blockhash<EVM>(
53    evm: &mut EVM,
54    parent_block_hash: B256,
55) -> Result<(), EVM::Error>
56where
57    EVM: SystemCallCommitEvm<Error: core::fmt::Debug>,
58{
59    evm.system_call_commit(HISTORY_STORAGE_ADDRESS, parent_block_hash.0.into())?;
60    Ok(())
61}
62
63pub const BEACON_ROOTS_ADDRESS: Address = address!("000F3df6D732807Ef1319fB7B8bB8522d0Beac02");
64
65/// Beacon root system call EIP-4788
66pub(crate) fn system_call_eip4788_beacon_root<EVM>(
67    evm: &mut EVM,
68    parent_beacon_block_root: B256,
69) -> Result<(), EVM::Error>
70where
71    EVM: SystemCallCommitEvm<Error: core::fmt::Debug>,
72{
73    evm.system_call_commit(BEACON_ROOTS_ADDRESS, parent_beacon_block_root.0.into())?;
74    Ok(())
75}