revme/cmd/blockchaintest/
post_block.rs

1use context::{Block, ContextTr};
2use database::State;
3use primitives::{hardfork::SpecId, ONE_ETHER, ONE_GWEI};
4use revm::{handler::EvmTr, Database, SystemCallCommitEvm};
5use statetest_types::blockchain::Withdrawal;
6
7/// Post block transition that includes:
8///   * Block and uncle rewards before the Merge/Paris hardfork.
9///   * system calls
10///
11/// # Note
12///
13/// Uncle rewards are not implemented yet.
14#[inline]
15pub fn post_block_transition<
16    'a,
17    DB: Database + 'a,
18    EVM: SystemCallCommitEvm<Error: core::fmt::Debug>
19        + EvmTr<Context: ContextTr<Db = &'a mut State<DB>>>,
20>(
21    evm: &mut EVM,
22    block: impl Block,
23    withdrawals: &[Withdrawal],
24    spec: SpecId,
25) {
26    // block reward
27    let block_reward = block_reward(spec, 0);
28    if block_reward != 0 {
29        let _ = evm
30            .ctx_mut()
31            .db_mut()
32            .increment_balances(vec![(block.beneficiary(), block_reward)]);
33    }
34
35    // withdrawals
36    if spec.is_enabled_in(SpecId::SHANGHAI) {
37        for withdrawal in withdrawals {
38            evm.ctx_mut()
39                .db_mut()
40                .increment_balances(vec![(
41                    withdrawal.address,
42                    withdrawal.amount.to::<u128>().saturating_mul(ONE_GWEI),
43                )])
44                .expect("Db actions to pass");
45        }
46    }
47}
48
49/// Block reward for a block.
50#[inline]
51pub const fn block_reward(spec: SpecId, ommers: usize) -> u128 {
52    if spec.is_enabled_in(SpecId::MERGE) {
53        return 0;
54    }
55
56    let reward = if spec.is_enabled_in(SpecId::CONSTANTINOPLE) {
57        ONE_ETHER * 2
58    } else if spec.is_enabled_in(SpecId::BYZANTIUM) {
59        ONE_ETHER * 3
60    } else {
61        ONE_ETHER * 5
62    };
63
64    reward + (reward >> 5) * ommers as u128
65}