revm/handler/mainnet/
post_execution.rsuse crate::{
interpreter::{Gas, SuccessOrHalt},
primitives::{
db::Database, EVMError, ExecutionResult, ResultAndState, Spec, SpecId, SpecId::LONDON, U256,
},
Context, FrameResult,
};
#[inline]
pub fn end<EXT, DB: Database>(
_context: &mut Context<EXT, DB>,
evm_output: Result<ResultAndState, EVMError<DB::Error>>,
) -> Result<ResultAndState, EVMError<DB::Error>> {
evm_output
}
#[inline]
pub fn clear<EXT, DB: Database>(context: &mut Context<EXT, DB>) {
let _ = context.evm.take_error();
context.evm.inner.journaled_state.clear();
}
#[inline]
pub fn reward_beneficiary<SPEC: Spec, EXT, DB: Database>(
context: &mut Context<EXT, DB>,
gas: &Gas,
) -> Result<(), EVMError<DB::Error>> {
let beneficiary = context.evm.env.block.coinbase;
let effective_gas_price = context.evm.env.effective_gas_price();
let coinbase_gas_price = if SPEC::enabled(LONDON) {
effective_gas_price.saturating_sub(context.evm.env.block.basefee)
} else {
effective_gas_price
};
let coinbase_account = context
.evm
.inner
.journaled_state
.load_account(beneficiary, &mut context.evm.inner.db)?;
coinbase_account.data.mark_touch();
coinbase_account.data.info.balance = coinbase_account
.data
.info
.balance
.saturating_add(coinbase_gas_price * U256::from(gas.spent() - gas.refunded() as u64));
Ok(())
}
pub fn refund<SPEC: Spec, EXT, DB: Database>(
_context: &mut Context<EXT, DB>,
gas: &mut Gas,
eip7702_refund: i64,
) {
gas.record_refund(eip7702_refund);
gas.set_final_refund(SPEC::SPEC_ID.is_enabled_in(SpecId::LONDON));
}
#[inline]
pub fn reimburse_caller<SPEC: Spec, EXT, DB: Database>(
context: &mut Context<EXT, DB>,
gas: &Gas,
) -> Result<(), EVMError<DB::Error>> {
let caller = context.evm.env.tx.caller;
let effective_gas_price = context.evm.env.effective_gas_price();
let caller_account = context
.evm
.inner
.journaled_state
.load_account(caller, &mut context.evm.inner.db)?;
caller_account.data.info.balance =
caller_account.data.info.balance.saturating_add(
effective_gas_price * U256::from(gas.remaining() + gas.refunded() as u64),
);
Ok(())
}
#[inline]
pub fn output<EXT, DB: Database>(
context: &mut Context<EXT, DB>,
result: FrameResult,
) -> Result<ResultAndState, EVMError<DB::Error>> {
context.evm.take_error()?;
let gas_refunded = result.gas().refunded() as u64;
let final_gas_used = result.gas().spent() - gas_refunded;
let output = result.output();
let instruction_result = result.into_interpreter_result();
let (state, logs) = context.evm.journaled_state.finalize();
let result = match instruction_result.result.into() {
SuccessOrHalt::Success(reason) => ExecutionResult::Success {
reason,
gas_used: final_gas_used,
gas_refunded,
logs,
output,
},
SuccessOrHalt::Revert => ExecutionResult::Revert {
gas_used: final_gas_used,
output: output.into_data(),
},
SuccessOrHalt::Halt(reason) => ExecutionResult::Halt {
reason,
gas_used: final_gas_used,
},
flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => {
panic!(
"Encountered unexpected internal return flag: {:?} with instruction result: {:?}",
flag, instruction_result
)
}
};
Ok(ResultAndState { result, state })
}