Skip to content

Commit

Permalink
Merge pull request #5 from anton-rs/refcell/gas-refactor
Browse files Browse the repository at this point in the history
feat: Refactor gas usage
  • Loading branch information
refcell authored Sep 5, 2023
2 parents ae76b7e + 8eab1ad commit f2d59b9
Showing 1 changed file with 96 additions and 61 deletions.
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

0 comments on commit f2d59b9

Please sign in to comment.