From 128e440c5edef97cfbbcb59be3f4ca6c14e6231e Mon Sep 17 00:00:00 2001 From: Andreas Bigger Date: Tue, 5 Sep 2023 16:34:50 -0400 Subject: [PATCH 1/2] Refactor l1 cost and mint computations --- crates/revm/src/evm_impl.rs | 85 ++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 25 deletions(-) diff --git a/crates/revm/src/evm_impl.rs b/crates/revm/src/evm_impl.rs index f04028f64a..b1c1e652dc 100644 --- a/crates/revm/src/evm_impl.rs +++ b/crates/revm/src/evm_impl.rs @@ -91,6 +91,52 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, } Ok(()) } + + /// If the transaction is not a deposit transaction, subtract the L1 data fee from the + /// caller's balance directly after minting the requested amount of ETH. + #[cfg(feature = "optimism")] + fn remove_l1_cost( + is_deposit: bool, + tx_caller: B160, + tx_l1_cost: Option, + db: &mut DB, + journal: &mut JournaledState, + ) -> Result<(), EVMError> { + if is_deposit { + return Ok(()); + } + if let Some(l1_cost) = tx_l1_cost { + let acc = journal + .load_account(tx_caller, db) + .map_err(EVMError::Database)? + .0; + let res = acc.info.balance.saturating_sub(l1_cost); + acc.info.balance = res; + } + Ok(()) + } + + /// If the transaction is a deposit with a `mint` value, add the mint value + /// in wei to the caller's balance. This should be persisted to the database + /// prior to the rest of execution. + #[cfg(feature = "optimism")] + fn commit_mint_value( + tx_caller: B160, + tx_mint: Option, + db: &mut DB, + journal: &mut JournaledState, + ) -> Result<(), EVMError> { + if let Some(mint) = tx_mint { + journal + .load_account(tx_caller, db) + .map_err(EVMError::Database)? + .0 + .info + .balance += U256::from(mint); + journal.checkpoint(); + } + Ok(()) + } } impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact @@ -158,31 +204,20 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact #[cfg(feature = "optimism")] if self.data.env.cfg.optimism { - // If the transaction is a deposit with a `Some` `mint` value, add the minted value - // in wei to the caller's balance. This should be persisted to the database prior - // to the rest of execution below. - if let Some(mint) = tx_mint { - journal - .load_account(tx_caller, self.data.db) - .map_err(EVMError::Database)? - .0 - .info - .balance += U256::from(mint); - journal.checkpoint(); - } - - // If the transaction is not a deposit transaction, subtract the L1 data fee from the - // caller's balance directly after minting the requested amount of ETH. - if !is_deposit { - if let Some(l1_cost) = tx_l1_cost { - journal - .load_account(tx_caller, self.data.db) - .map_err(EVMError::Database)? - .0 - .info - .balance -= l1_cost; - } - } + EVMImpl::::commit_mint_value( + tx_caller, + tx_mint, + self.data.db, + journal, + )?; + + EVMImpl::::remove_l1_cost( + is_deposit, + tx_caller, + tx_l1_cost, + self.data.db, + journal, + )?; } let (caller_account, _) = journal From 6b868b3828332b625ffbc6f71aded6b00a25a5b4 Mon Sep 17 00:00:00 2001 From: Andreas Bigger Date: Tue, 5 Sep 2023 18:43:29 -0400 Subject: [PATCH 2/2] l1 cost erroring --- crates/revm/src/evm_impl.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/revm/src/evm_impl.rs b/crates/revm/src/evm_impl.rs index b1c1e652dc..6468842546 100644 --- a/crates/revm/src/evm_impl.rs +++ b/crates/revm/src/evm_impl.rs @@ -110,8 +110,21 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, .load_account(tx_caller, db) .map_err(EVMError::Database)? .0; - let res = acc.info.balance.saturating_sub(l1_cost); - acc.info.balance = res; + if l1_cost.gt(&acc.info.balance) { + let x = l1_cost.as_limbs(); + let u64_cost = if x[1] == 0 && x[2] == 0 && x[3] == 0 { + x[0] + } else { + u64::MAX + }; + return Err(EVMError::Transaction( + InvalidTransaction::LackOfFundForMaxFee { + fee: u64_cost, + balance: acc.info.balance, + }, + )); + } + acc.info.balance = acc.info.balance.saturating_sub(l1_cost); } Ok(()) }