From 4aa835a23df041e76304299ab666293d7f94d756 Mon Sep 17 00:00:00 2001 From: Daniil Naumetc <11177808+kekonen@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:50:29 +0100 Subject: [PATCH] feat: Convert optimism panic into graceful error (#982) * feat(crates): custom evm error targeting optimism * fix(crates): alloc String * Update crates/primitives/src/result.rs Co-authored-by: rakita --------- Co-authored-by: rakita --- crates/primitives/src/result.rs | 7 ++++++- crates/revm/src/optimism/handler_register.rs | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/crates/primitives/src/result.rs b/crates/primitives/src/result.rs index c91c9052eb..b765dd7aef 100644 --- a/crates/primitives/src/result.rs +++ b/crates/primitives/src/result.rs @@ -1,5 +1,5 @@ use crate::{Address, Bytes, Log, State, U256}; -use alloc::{boxed::Box, vec::Vec}; +use alloc::{boxed::Box, string::String, vec::Vec}; use core::fmt; /// Result of EVM execution. @@ -135,6 +135,10 @@ pub enum EVMError { Header(InvalidHeader), /// Database error. Database(DBError), + /// Custom error. + /// + /// Useful for handler registers where custom logic would want to return their own custom error. + Custom(String), } #[cfg(feature = "std")] @@ -146,6 +150,7 @@ impl fmt::Display for EVMError { EVMError::Transaction(e) => write!(f, "Transaction error: {e:?}"), EVMError::Header(e) => write!(f, "Header error: {e:?}"), EVMError::Database(e) => write!(f, "Database error: {e}"), + EVMError::Custom(e) => write!(f, "Custom error: {e}"), } } } diff --git a/crates/revm/src/optimism/handler_register.rs b/crates/revm/src/optimism/handler_register.rs index e3ff387fda..b0a5c91cdd 100644 --- a/crates/revm/src/optimism/handler_register.rs +++ b/crates/revm/src/optimism/handler_register.rs @@ -125,7 +125,9 @@ pub fn deduct_caller( if context.evm.env.tx.optimism.source_hash.is_none() { // get envelope let Some(enveloped_tx) = context.evm.env.tx.optimism.enveloped_tx.clone() else { - panic!("[OPTIMISM] Failed to load enveloped transaction."); + return Err(EVMError::Custom( + "[OPTIMISM] Failed to load enveloped transaction.".to_string(), + )); }; let tx_l1_cost = context @@ -166,11 +168,15 @@ pub fn reward_beneficiary( // If the transaction is not a deposit transaction, fees are paid out // to both the Base Fee Vault as well as the L1 Fee Vault. let Some(l1_block_info) = context.evm.l1_block_info.clone() else { - panic!("[OPTIMISM] Failed to load L1 block information."); + return Err(EVMError::Custom( + "[OPTIMISM] Failed to load L1 block information.".to_string(), + )); }; let Some(enveloped_tx) = &context.evm.env.tx.optimism.enveloped_tx else { - panic!("[OPTIMISM] Failed to load enveloped transaction."); + return Err(EVMError::Custom( + "[OPTIMISM] Failed to load enveloped transaction.".to_string(), + )); }; let l1_cost = l1_block_info.calculate_tx_l1_cost(enveloped_tx, SPEC::SPEC_ID); @@ -181,7 +187,9 @@ pub fn reward_beneficiary( .journaled_state .load_account(optimism::L1_FEE_RECIPIENT, &mut context.evm.db) else { - panic!("[OPTIMISM] Failed to load L1 Fee Vault account"); + return Err(EVMError::Custom( + "[OPTIMISM] Failed to load L1 Fee Vault account.".to_string(), + )); }; l1_fee_vault_account.mark_touch(); l1_fee_vault_account.info.balance += l1_cost; @@ -192,7 +200,9 @@ pub fn reward_beneficiary( .journaled_state .load_account(optimism::BASE_FEE_RECIPIENT, &mut context.evm.db) else { - panic!("[OPTIMISM] Failed to load Base Fee Vault account"); + return Err(EVMError::Custom( + "[OPTIMISM] Failed to load Base Fee Vault account.".to_string(), + )); }; base_fee_vault_account.mark_touch(); base_fee_vault_account.info.balance += context