revm_handler/
post_execution.rs1use super::frame_data::FrameResult;
2use context_interface::ContextTr;
3use context_interface::{
4 journaled_state::Journal,
5 result::{ExecutionResult, HaltReasonTr, ResultAndState},
6 Block, Cfg, Database, Transaction,
7};
8use interpreter::{Gas, InitialAndFloorGas, SuccessOrHalt};
9use primitives::{Log, U256};
10use specification::hardfork::SpecId;
11use state::EvmState;
12use std::vec::Vec;
13
14pub fn eip7623_check_gas_floor(gas: &mut Gas, init_and_floor_gas: InitialAndFloorGas) {
15 if gas.spent_sub_refunded() < init_and_floor_gas.floor_gas {
18 gas.set_spent(init_and_floor_gas.floor_gas);
19 gas.set_refund(0);
21 }
22}
23
24pub fn refund(spec: SpecId, gas: &mut Gas, eip7702_refund: i64) {
25 gas.record_refund(eip7702_refund);
26 gas.set_final_refund(spec.is_enabled_in(SpecId::LONDON));
30}
31
32pub fn reimburse_caller<CTX: ContextTr>(
33 context: &mut CTX,
34 gas: &mut Gas,
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 let caller_account = context.journal().load_account(caller)?;
42
43 let reimbursed =
44 effective_gas_price.saturating_mul((gas.remaining() + gas.refunded() as u64) as u128);
45 caller_account.data.info.balance = caller_account
46 .data
47 .info
48 .balance
49 .saturating_add(U256::from(reimbursed));
50
51 Ok(())
52}
53
54pub fn reward_beneficiary<CTX: ContextTr>(
55 context: &mut CTX,
56 gas: &mut Gas,
57) -> Result<(), <CTX::Db as Database>::Error> {
58 let block = context.block();
59 let tx = context.tx();
60 let beneficiary = block.beneficiary();
61 let basefee = block.basefee() as u128;
62 let effective_gas_price = tx.effective_gas_price(basefee);
63
64 let coinbase_gas_price = if context.cfg().spec().into().is_enabled_in(SpecId::LONDON) {
67 effective_gas_price.saturating_sub(basefee)
68 } else {
69 effective_gas_price
70 };
71
72 let coinbase_account = context.journal().load_account(beneficiary)?;
73
74 coinbase_account.data.mark_touch();
75 coinbase_account.data.info.balance =
76 coinbase_account
77 .data
78 .info
79 .balance
80 .saturating_add(U256::from(
81 coinbase_gas_price * (gas.spent() - gas.refunded() as u64) as u128,
82 ));
83
84 Ok(())
85}
86
87pub fn output<
91 CTX: ContextTr<Journal: Journal<FinalOutput = (EvmState, Vec<Log>)>>,
92 HALTREASON: HaltReasonTr,
93>(
94 context: &mut CTX,
95 result: FrameResult,
98) -> ResultAndState<HALTREASON> {
99 let gas_refunded = result.gas().refunded() as u64;
101 let final_gas_used = result.gas().spent() - gas_refunded;
102 let output = result.output();
103 let instruction_result = result.into_interpreter_result();
104
105 let (state, logs) = context.journal().finalize();
107
108 let result = match SuccessOrHalt::<HALTREASON>::from(instruction_result.result) {
109 SuccessOrHalt::Success(reason) => ExecutionResult::Success {
110 reason,
111 gas_used: final_gas_used,
112 gas_refunded,
113 logs,
114 output,
115 },
116 SuccessOrHalt::Revert => ExecutionResult::Revert {
117 gas_used: final_gas_used,
118 output: output.into_data(),
119 },
120 SuccessOrHalt::Halt(reason) => ExecutionResult::Halt {
121 reason,
122 gas_used: final_gas_used,
123 },
124 flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => {
126 panic!(
127 "Encountered unexpected internal return flag: {:?} with instruction result: {:?}",
128 flag, instruction_result
129 )
130 }
131 };
132
133 ResultAndState { result, state }
134}