Skip to content
This repository was archived by the owner on Oct 11, 2024. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 96 additions & 61 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,89 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
}
Ok(())
}

/// Set gas to the gas limit and spend it all.
#[cfg(not(feature = "optimism"))]
#[inline]
fn use_gas(
&mut self,
gas: &mut Gas,
gas_limit: u64,
ret_gas: Gas,
exit_reason: InstructionResult,
) -> Result<(), EVMError<DB::Error>> {
match exit_reason {
return_ok!() => {
gas.erase_cost(ret_gas.remaining());
gas.record_refund(ret_gas.refunded());
}
return_revert!() => {
gas.erase_cost(ret_gas.remaining());
}
_ => {}
}
Ok(())
}

/// Set gas to the gas limit and spend it all.
#[cfg(feature = "optimism")]
#[inline]
fn use_gas(
&mut self,
gas: &mut Gas,
is_deposit: bool,
tx_system: Option<bool>,
gas_limit: u64,
ret_gas: Gas,
exit_reason: InstructionResult,
) -> Result<(), EVMError<DB::Error>> {
match exit_reason {
return_ok!() => {
// On Optimism, deposit transactions report gas usage uniquely to other
// transactions due to them being pre-paid on L1.
//
// Hardfork Behavior:
// - Bedrock (success path):
// - Deposit transactions (non-system) report their gas limit as the usage.
// No refunds.
// - Deposit transactions (system) report 0 gas used. No refunds.
// - Regular transactions report gas usage as normal.
// - Regolith (success path):
// - Deposit transactions (all) report their gas used as normal. Refunds
// enabled.
// - Regular transactions report their gas used as normal.
if self.data.env.cfg.optimism && (!is_deposit || GSPEC::enabled(SpecId::REGOLITH)) {
// For regular transactions prior to Regolith and all transactions after
// Regolith, gas is reported as normal.
gas.erase_cost(ret_gas.remaining());
gas.record_refund(ret_gas.refunded());
} else if is_deposit && tx_system.unwrap_or(false) {
// System transactions were a special type of deposit transaction in
// the Bedrock hardfork that did not incur any gas costs.
gas.erase_cost(gas_limit);
}
}
return_revert!() => {
// On Optimism, deposit transactions report gas usage uniquely to other
// transactions due to them being pre-paid on L1.
//
// Hardfork Behavior:
// - Bedrock (revert path):
// - Deposit transactions (all) report the gas limit as the amount of gas
// used on failure. No refunds.
// - Regular transactions receive a refund on remaining gas as normal.
// - Regolith (revert path):
// - Deposit transactions (all) report the actual gas used as the amount of
// gas used on failure. Refunds on remaining gas enabled.
// - Regular transactions receive a refund on remaining gas as normal.
if self.data.env.cfg.optimism && (!is_deposit || GSPEC::enabled(SpecId::REGOLITH)) {
gas.erase_cost(ret_gas.remaining());
}
}
_ => {}
}
Ok(())
}
}

impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact<DB::Error>
Expand Down Expand Up @@ -191,6 +274,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact<DB::Error>
let tx_gas_limit = env.tx.gas_limit;
let tx_is_create = env.tx.transact_to.is_create();
let effective_gas_price = env.effective_gas_price();

#[cfg(feature = "optimism")]
let (tx_mint, tx_system, tx_l1_cost, is_deposit) = (
env.tx.optimism.mint,
Expand Down Expand Up @@ -289,72 +373,23 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact<DB::Error>
}
};

// set gas with gas limit and spend it all. Gas is going to be reimbursed when
// transaction is returned successfully.
// Spend the gas limit. Gas is reimbursed when the tx returns successfully.
let mut gas = Gas::new(tx_gas_limit);
gas.record_cost(tx_gas_limit);

if crate::USE_GAS {
match exit_reason {
return_ok!() => {
#[cfg(not(feature = "optimism"))]
{
gas.erase_cost(ret_gas.remaining());
gas.record_refund(ret_gas.refunded());
}
#[cfg(not(feature = "optimism"))]
self.use_gas(&mut gas, tx_gas_limit, ret_gas, exit_reason)?;

// On Optimism, deposit transactions report gas usage uniquely to other
// transactions due to them being pre-paid on L1.
//
// Hardfork Behavior:
// - Bedrock (success path):
// - Deposit transactions (non-system) report their gas limit as the usage.
// No refunds.
// - Deposit transactions (system) report 0 gas used. No refunds.
// - Regular transactions report gas usage as normal.
// - Regolith (success path):
// - Deposit transactions (all) report their gas used as normal. Refunds
// enabled.
// - Regular transactions report their gas used as normal.
#[cfg(feature = "optimism")]
if self.data.env.cfg.optimism
&& (!is_deposit || GSPEC::enabled(SpecId::REGOLITH))
{
// For regular transactions prior to Regolith and all transactions after
// Regolith, gas is reported as normal.
gas.erase_cost(ret_gas.remaining());
gas.record_refund(ret_gas.refunded());
} else if is_deposit && tx_system.unwrap_or(false) {
// System transactions were a special type of deposit transaction in
// the Bedrock hardfork that did not incur any gas costs.
gas.erase_cost(tx_gas_limit);
}
}
return_revert!() => {
#[cfg(not(feature = "optimism"))]
gas.erase_cost(ret_gas.remaining());

// On Optimism, deposit transactions report gas usage uniquely to other
// transactions due to them being pre-paid on L1.
//
// Hardfork Behavior:
// - Bedrock (revert path):
// - Deposit transactions (all) report the gas limit as the amount of gas
// used on failure. No refunds.
// - Regular transactions receive a refund on remaining gas as normal.
// - Regolith (revert path):
// - Deposit transactions (all) report the actual gas used as the amount of
// gas used on failure. Refunds on remaining gas enabled.
// - Regular transactions receive a refund on remaining gas as normal.
#[cfg(feature = "optimism")]
if self.data.env.cfg.optimism
&& (!is_deposit || GSPEC::enabled(SpecId::REGOLITH))
{
gas.erase_cost(ret_gas.remaining());
}
}
_ => {}
}
#[cfg(feature = "optimism")]
self.use_gas(
&mut gas,
is_deposit,
tx_system,
tx_gas_limit,
ret_gas,
exit_reason,
)?;
}

let (state, logs, gas_used, gas_refunded) = self.finalize::<GSPEC>(&gas);
Expand Down