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
52#[inline]
53pub fn reward_beneficiary<CTX: ContextTr>(
54 context: &mut CTX,
55 gas: &mut Gas,
56) -> Result<(), <CTX::Db as Database>::Error> {
57 let block = context.block();
58 let tx = context.tx();
59 let beneficiary = block.beneficiary();
60 let basefee = block.basefee() as u128;
61 let effective_gas_price = 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 let coinbase_account = context.journal().load_account(beneficiary)?;
72
73 coinbase_account.data.mark_touch();
74 coinbase_account.data.info.balance =
75 coinbase_account
76 .data
77 .info
78 .balance
79 .saturating_add(U256::from(
80 coinbase_gas_price * (gas.spent() - gas.refunded() as u64) as u128,
81 ));
82
83 Ok(())
84}
85
86pub fn output<
90 CTX: ContextTr<Journal: JournalTr<FinalOutput = JournalOutput>>,
91 HALTREASON: HaltReasonTr,
92>(
93 context: &mut CTX,
94 result: FrameResult,
97) -> ResultAndState<HALTREASON> {
98 let gas_refunded = result.gas().refunded() as u64;
100 let final_gas_used = result.gas().spent() - gas_refunded;
101 let output = result.output();
102 let instruction_result = result.into_interpreter_result();
103
104 let JournalOutput { state, logs } = context.journal().finalize();
106
107 let result = match SuccessOrHalt::<HALTREASON>::from(instruction_result.result) {
108 SuccessOrHalt::Success(reason) => ExecutionResult::Success {
109 reason,
110 gas_used: final_gas_used,
111 gas_refunded,
112 logs,
113 output,
114 },
115 SuccessOrHalt::Revert => ExecutionResult::Revert {
116 gas_used: final_gas_used,
117 output: output.into_data(),
118 },
119 SuccessOrHalt::Halt(reason) => ExecutionResult::Halt {
120 reason,
121 gas_used: final_gas_used,
122 },
123 flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => {
125 panic!(
126 "Encountered unexpected internal return flag: {:?} with instruction result: {:?}",
127 flag, instruction_result
128 )
129 }
130 };
131
132 ResultAndState { result, state }
133}