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};
9
10pub fn eip7623_check_gas_floor(gas: &mut Gas, init_and_floor_gas: InitialAndFloorGas) {
12 if gas.spent_sub_refunded() < init_and_floor_gas.floor_gas {
15 gas.set_spent(init_and_floor_gas.floor_gas);
16 gas.set_refund(0);
18 }
19}
20
21pub 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]
32pub fn reimburse_caller<CTX: ContextTr>(
33 context: &mut CTX,
34 gas: &Gas,
35 additional_refund: U256,
36) -> Result<(), <CTX::Db as Database>::Error> {
37 let basefee = context.block().basefee() as u128;
38 let caller = context.tx().caller();
39 let effective_gas_price = context.tx().effective_gas_price(basefee);
40
41 context.journal_mut().balance_incr(
43 caller,
44 U256::from(
45 effective_gas_price.saturating_mul((gas.remaining() + gas.refunded() as u64) as u128),
46 ) + additional_refund,
47 )?;
48
49 Ok(())
50}
51
52#[inline]
54pub fn reward_beneficiary<CTX: ContextTr>(
55 context: &mut CTX,
56 gas: &Gas,
57) -> Result<(), <CTX::Db as Database>::Error> {
58 let beneficiary = context.block().beneficiary();
59 let basefee = context.block().basefee() as u128;
60 let effective_gas_price = context.tx().effective_gas_price(basefee);
61
62 let coinbase_gas_price = if context.cfg().spec().into().is_enabled_in(SpecId::LONDON) {
65 effective_gas_price.saturating_sub(basefee)
66 } else {
67 effective_gas_price
68 };
69
70 context.journal_mut().balance_incr(
72 beneficiary,
73 U256::from(coinbase_gas_price * gas.used() as u128),
74 )?;
75
76 Ok(())
77}
78
79pub fn output<CTX: ContextTr<Journal: JournalTr>, HALTREASON: HaltReasonTr>(
83 context: &mut CTX,
84 result: FrameResult,
87) -> ExecutionResult<HALTREASON> {
88 let gas_refunded = result.gas().refunded() as u64;
90 let gas_used = result.gas().used();
91 let output = result.output();
92 let instruction_result = result.into_interpreter_result();
93
94 let logs = context.journal_mut().take_logs();
96
97 match SuccessOrHalt::<HALTREASON>::from(instruction_result.result) {
98 SuccessOrHalt::Success(reason) => ExecutionResult::Success {
99 reason,
100 gas_used,
101 gas_refunded,
102 logs,
103 output,
104 },
105 SuccessOrHalt::Revert => ExecutionResult::Revert {
106 gas_used,
107 output: output.into_data(),
108 },
109 SuccessOrHalt::Halt(reason) => ExecutionResult::Halt { reason, gas_used },
110 flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => {
112 panic!(
113 "Encountered unexpected internal return flag: {flag:?} with instruction result: {instruction_result:?}"
114 )
115 }
116 }
117}