revm_handler/
post_execution.rs1use super::frame_data::FrameResult;
2use context::JournalOutput;
3use context_interface::ContextTr;
4use context_interface::{
5 journaled_state::JournalTr,
6 result::{ExecutionResult, HaltReasonTr, ResultAndState},
7 Block, Cfg, Database, Transaction,
8};
9use interpreter::{Gas, InitialAndFloorGas, SuccessOrHalt};
10use primitives::{hardfork::SpecId, U256};
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
30pub fn reimburse_caller<CTX: ContextTr>(
31 context: &mut CTX,
32 gas: &mut Gas,
33) -> Result<(), <CTX::Db as Database>::Error> {
34 let basefee = context.block().basefee() as u128;
35 let caller = context.tx().caller();
36 let effective_gas_price = context.tx().effective_gas_price(basefee);
37
38 let caller_account = context.journal().load_account(caller)?;
40
41 let reimbursed =
42 effective_gas_price.saturating_mul((gas.remaining() + gas.refunded() as u64) as u128);
43 caller_account.data.info.balance = caller_account
44 .data
45 .info
46 .balance
47 .saturating_add(U256::from(reimbursed));
48
49 Ok(())
50}
51
52pub fn reward_beneficiary<CTX: ContextTr>(
53 context: &mut CTX,
54 gas: &mut Gas,
55) -> Result<(), <CTX::Db as Database>::Error> {
56 let block = context.block();
57 let tx = context.tx();
58 let beneficiary = block.beneficiary();
59 let basefee = block.basefee() as u128;
60 let effective_gas_price = 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 let coinbase_account = context.journal().load_account(beneficiary)?;
71
72 coinbase_account.data.mark_touch();
73 coinbase_account.data.info.balance =
74 coinbase_account
75 .data
76 .info
77 .balance
78 .saturating_add(U256::from(
79 coinbase_gas_price * (gas.spent() - gas.refunded() as u64) as u128,
80 ));
81
82 Ok(())
83}
84
85pub fn output<
89 CTX: ContextTr<Journal: JournalTr<FinalOutput = JournalOutput>>,
90 HALTREASON: HaltReasonTr,
91>(
92 context: &mut CTX,
93 result: FrameResult,
96) -> ResultAndState<HALTREASON> {
97 let gas_refunded = result.gas().refunded() as u64;
99 let final_gas_used = result.gas().spent() - gas_refunded;
100 let output = result.output();
101 let instruction_result = result.into_interpreter_result();
102
103 let JournalOutput { state, logs } = context.journal().finalize();
105
106 let result = match SuccessOrHalt::<HALTREASON>::from(instruction_result.result) {
107 SuccessOrHalt::Success(reason) => ExecutionResult::Success {
108 reason,
109 gas_used: final_gas_used,
110 gas_refunded,
111 logs,
112 output,
113 },
114 SuccessOrHalt::Revert => ExecutionResult::Revert {
115 gas_used: final_gas_used,
116 output: output.into_data(),
117 },
118 SuccessOrHalt::Halt(reason) => ExecutionResult::Halt {
119 reason,
120 gas_used: final_gas_used,
121 },
122 flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => {
124 panic!(
125 "Encountered unexpected internal return flag: {:?} with instruction result: {:?}",
126 flag, instruction_result
127 )
128 }
129 };
130
131 ResultAndState { result, state }
132}