revm_handler/
post_execution.rs1use crate::FrameResult;
2use context_interface::{
3 journaled_state::JournalTr,
4 result::{ExecutionResult, HaltReasonTr},
5 Block, Cfg, ContextTr, Database, Transaction,
6};
7use interpreter::{Gas, InitialAndFloorGas, SuccessOrHalt};
8use primitives::{hardfork::SpecId, U256};
9use state::EvmState;
10
11pub 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) {
24 gas.record_refund(eip7702_refund);
25 gas.set_final_refund(spec.is_enabled_in(SpecId::LONDON));
29}
30
31#[inline]
33pub fn reimburse_caller<CTX: ContextTr>(
34 context: &mut CTX,
35 gas: &mut Gas,
36 additional_refund: U256,
37) -> Result<(), <CTX::Db as Database>::Error> {
38 let basefee = context.block().basefee() as u128;
39 let caller = context.tx().caller();
40 let effective_gas_price = context.tx().effective_gas_price(basefee);
41
42 context.journal_mut().balance_incr(
44 caller,
45 U256::from(
46 effective_gas_price.saturating_mul((gas.remaining() + gas.refunded() as u64) as u128),
47 ) + additional_refund,
48 )?;
49
50 Ok(())
51}
52
53#[inline]
55pub fn reward_beneficiary<CTX: ContextTr>(
56 context: &mut CTX,
57 gas: &mut Gas,
58) -> Result<(), <CTX::Db as Database>::Error> {
59 let beneficiary = context.block().beneficiary();
60 let basefee = context.block().basefee() as u128;
61 let effective_gas_price = context.tx().effective_gas_price(basefee);
62
63 let coinbase_gas_price = if context.cfg().spec().into().is_enabled_in(SpecId::LONDON) {
66 effective_gas_price.saturating_sub(basefee)
67 } else {
68 effective_gas_price
69 };
70
71 context.journal_mut().balance_incr(
73 beneficiary,
74 U256::from(coinbase_gas_price * (gas.spent() - gas.refunded() as u64) as u128),
75 )?;
76
77 Ok(())
78}
79
80pub fn output<CTX: ContextTr<Journal: JournalTr<State = EvmState>>, HALTREASON: HaltReasonTr>(
84 context: &mut CTX,
85 result: FrameResult,
88) -> ExecutionResult<HALTREASON> {
89 let gas_refunded = result.gas().refunded() as u64;
91 let final_gas_used = result.gas().spent() - gas_refunded;
92 let output = result.output();
93 let instruction_result = result.into_interpreter_result();
94
95 let logs = context.journal_mut().take_logs();
97
98 match SuccessOrHalt::<HALTREASON>::from(instruction_result.result) {
99 SuccessOrHalt::Success(reason) => ExecutionResult::Success {
100 reason,
101 gas_used: final_gas_used,
102 gas_refunded,
103 logs,
104 output,
105 },
106 SuccessOrHalt::Revert => ExecutionResult::Revert {
107 gas_used: final_gas_used,
108 output: output.into_data(),
109 },
110 SuccessOrHalt::Halt(reason) => ExecutionResult::Halt {
111 reason,
112 gas_used: final_gas_used,
113 },
114 flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => {
116 panic!(
117 "Encountered unexpected internal return flag: {flag:?} with instruction result: {instruction_result:?}"
118 )
119 }
120 }
121}