revm_handler/
post_execution.rs1use super::frame_data::FrameResult;
2use context_interface::ContextTr;
3use context_interface::{
4 journaled_state::JournalTr,
5 result::{ExecutionResult, HaltReasonTr},
6 Block, Cfg, Database, Transaction,
7};
8use interpreter::{Gas, InitialAndFloorGas, SuccessOrHalt};
9use primitives::{hardfork::SpecId, U256};
10use state::EvmState;
11
12pub fn eip7623_check_gas_floor(gas: &mut Gas, init_and_floor_gas: InitialAndFloorGas) {
13 if gas.spent_sub_refunded() < init_and_floor_gas.floor_gas {
16 gas.set_spent(init_and_floor_gas.floor_gas);
17 gas.set_refund(0);
19 }
20}
21
22pub fn refund(spec: SpecId, gas: &mut Gas, eip7702_refund: i64) {
23 gas.record_refund(eip7702_refund);
24 gas.set_final_refund(spec.is_enabled_in(SpecId::LONDON));
28}
29
30#[inline]
31pub fn reimburse_caller<CTX: ContextTr>(
32 context: &mut CTX,
33 gas: &mut Gas,
34 additional_refund: U256,
35) -> Result<(), <CTX::Db as Database>::Error> {
36 let basefee = context.block().basefee() as u128;
37 let caller = context.tx().caller();
38 let effective_gas_price = context.tx().effective_gas_price(basefee);
39
40 context.journal_mut().balance_incr(
42 caller,
43 U256::from(
44 effective_gas_price.saturating_mul((gas.remaining() + gas.refunded() as u64) as u128),
45 ) + additional_refund,
46 )?;
47
48 Ok(())
49}
50
51#[inline]
52pub fn reward_beneficiary<CTX: ContextTr>(
53 context: &mut CTX,
54 gas: &mut Gas,
55) -> Result<(), <CTX::Db as Database>::Error> {
56 let beneficiary = context.block().beneficiary();
57 let basefee = context.block().basefee() as u128;
58 let effective_gas_price = context.tx().effective_gas_price(basefee);
59
60 let coinbase_gas_price = if context.cfg().spec().into().is_enabled_in(SpecId::LONDON) {
63 effective_gas_price.saturating_sub(basefee)
64 } else {
65 effective_gas_price
66 };
67
68 context.journal_mut().balance_incr(
70 beneficiary,
71 U256::from(coinbase_gas_price * (gas.spent() - gas.refunded() as u64) as u128),
72 )?;
73
74 Ok(())
75}
76
77pub fn output<CTX: ContextTr<Journal: JournalTr<State = EvmState>>, HALTREASON: HaltReasonTr>(
81 context: &mut CTX,
82 result: FrameResult,
85) -> ExecutionResult<HALTREASON> {
86 let gas_refunded = result.gas().refunded() as u64;
88 let final_gas_used = result.gas().spent() - gas_refunded;
89 let output = result.output();
90 let instruction_result = result.into_interpreter_result();
91
92 let logs = context.journal_mut().take_logs();
94
95 match SuccessOrHalt::<HALTREASON>::from(instruction_result.result) {
96 SuccessOrHalt::Success(reason) => ExecutionResult::Success {
97 reason,
98 gas_used: final_gas_used,
99 gas_refunded,
100 logs,
101 output,
102 },
103 SuccessOrHalt::Revert => ExecutionResult::Revert {
104 gas_used: final_gas_used,
105 output: output.into_data(),
106 },
107 SuccessOrHalt::Halt(reason) => ExecutionResult::Halt {
108 reason,
109 gas_used: final_gas_used,
110 },
111 flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => {
113 panic!(
114 "Encountered unexpected internal return flag: {:?} with instruction result: {:?}",
115 flag, instruction_result
116 )
117 }
118 }
119}