chore(evm): use provider errors (#5649)

This commit is contained in:
Roman Krasiuk
2023-12-01 04:35:45 -08:00
committed by GitHub
parent 2144b97df0
commit 67d93e822e
8 changed files with 37 additions and 28 deletions

View File

@ -1,4 +1,4 @@
use crate::RethError;
use crate::provider::ProviderError;
use reth_primitives::{
revm_primitives::EVMError, BlockNumHash, Bloom, GotExpected, GotExpectedBoxed,
PruneSegmentError, B256,
@ -15,7 +15,7 @@ pub enum BlockValidationError {
hash: B256,
/// The EVM error.
#[source]
error: Box<EVMError<RethError>>,
error: Box<EVMError<ProviderError>>,
},
/// Error when recovering the sender for a transaction
#[error("failed to recover sender for transaction")]
@ -127,11 +127,14 @@ pub enum BlockExecutionError {
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum OptimismBlockExecutionError {
/// Error when trying to parse L1 block info
#[error("Could not get L1 block info from L2 block: {message:?}")]
#[error("could not get L1 block info from L2 block: {message:?}")]
L1BlockInfoError {
/// The inner error message
message: String,
},
/// Thrown when force deploy of create2deployer code fails.
#[error("failed to force create2deployer account code")]
ForceCreate2DeployerFail,
}
impl BlockExecutionError {

View File

@ -13,7 +13,7 @@ use crate::metrics::PayloadBuilderMetrics;
use alloy_rlp::Encodable;
use futures_core::ready;
use futures_util::FutureExt;
use reth_interfaces::{RethError, RethResult};
use reth_interfaces::RethResult;
use reth_payload_builder::{
database::CachedReads, error::PayloadBuilderError, BuiltPayload, KeepPayloadJobAlive,
PayloadBuilderAttributes, PayloadId, PayloadJob, PayloadJobGenerator,
@ -30,7 +30,9 @@ use reth_primitives::{
Block, BlockNumberOrTag, Bytes, ChainSpec, Header, IntoRecoveredTransaction, Receipt, Receipts,
SealedBlock, Withdrawal, B256, EMPTY_OMMER_ROOT_HASH, U256,
};
use reth_provider::{BlockReaderIdExt, BlockSource, BundleStateWithReceipts, StateProviderFactory};
use reth_provider::{
BlockReaderIdExt, BlockSource, BundleStateWithReceipts, ProviderError, StateProviderFactory,
};
use reth_revm::{
database::StateProviderDatabase,
state_change::{apply_beacon_root_contract_call, post_block_withdrawals_balance_increments},
@ -1159,7 +1161,7 @@ impl WithdrawalsOutcome {
/// Returns the withdrawals root.
///
/// Returns `None` values pre shanghai
fn commit_withdrawals<DB: Database<Error = RethError>>(
fn commit_withdrawals<DB: Database<Error = ProviderError>>(
db: &mut State<DB>,
chain_spec: &ChainSpec,
timestamp: u64,

View File

@ -60,9 +60,7 @@ where
// the above check for empty blocks will never be hit on OP chains.
reth_revm::optimism::ensure_create2_deployer(chain_spec.clone(), attributes.timestamp, &mut db)
.map_err(|_| {
PayloadBuilderError::Internal(RethError::Custom(
"Failed to force create2deployer account code".to_string(),
))
PayloadBuilderError::Optimism(OptimismPayloadBuilderError::ForceCreate2DeployerFail)
})?;
let mut receipts = Vec::new();

View File

@ -22,7 +22,7 @@ pub enum PayloadBuilderError {
Internal(#[from] RethError),
/// Unrecoverable error during evm execution.
#[error("evm execution error: {0}")]
EvmExecutionError(EVMError<RethError>),
EvmExecutionError(EVMError<ProviderError>),
/// Thrown if the payload requests withdrawals before Shanghai activation.
#[error("withdrawals set before Shanghai activation")]
WithdrawalsBeforeShanghai,
@ -39,22 +39,23 @@ impl From<ProviderError> for PayloadBuilderError {
}
/// Optimism specific payload building errors.
#[cfg(feature = "optimism")]
#[derive(Debug, thiserror::Error)]
pub enum OptimismPayloadBuilderError {
/// Thrown when a transaction fails to convert to a
/// [reth_primitives::TransactionSignedEcRecovered].
#[cfg(feature = "optimism")]
#[error("failed to convert deposit transaction to TransactionSignedEcRecovered")]
TransactionEcRecoverFailed,
/// Thrown when the L1 block info could not be parsed from the calldata of the
/// first transaction supplied in the payload attributes.
#[cfg(feature = "optimism")]
#[error("failed to parse L1 block info from L1 info tx calldata")]
L1BlockInfoParseFailed,
/// Thrown when a database account could not be loaded.
#[error("failed to load account {0:?}")]
#[cfg(feature = "optimism")]
AccountLoadFailed(revm_primitives::Address),
/// Thrown when force deploy of create2deployer code fails.
#[error("failed to force create2deployer account code")]
ForceCreate2DeployerFail,
}
impl From<oneshot::error::RecvError> for PayloadBuilderError {

View File

@ -1,6 +1,6 @@
use reth_interfaces::RethError;
use reth_primitives::{Address, B256, KECCAK_EMPTY, U256};
use reth_provider::StateProvider;
use reth_provider::{ProviderError, StateProvider};
use revm::{
db::{CacheDB, DatabaseRef},
primitives::{AccountInfo, Bytecode},
@ -40,7 +40,7 @@ impl<DB: StateProvider> StateProviderDatabase<DB> {
}
impl<DB: StateProvider> Database for StateProviderDatabase<DB> {
type Error = RethError;
type Error = ProviderError;
fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
Ok(self.0.basic_account(address)?.map(|account| AccountInfo {

View File

@ -180,9 +180,9 @@ where
// If the canyon hardfork is active at the current timestamp, and it was not active at the
// previous block timestamp (heuristically, block time is not perfectly constant at 2s), and the
// chain is an optimism chain, then we need to force-deploy the create2 deployer contract.
if chain_spec.is_fork_active_at_timestamp(Hardfork::Canyon, timestamp) &&
!chain_spec.is_fork_active_at_timestamp(Hardfork::Canyon, timestamp - 2) &&
chain_spec.is_optimism()
if chain_spec.is_optimism() &&
chain_spec.is_fork_active_at_timestamp(Hardfork::Canyon, timestamp) &&
!chain_spec.is_fork_active_at_timestamp(Hardfork::Canyon, timestamp - 2)
{
trace!(target: "evm", "Forcing create2 deployer contract deployment on Canyon transition");

View File

@ -1,5 +1,7 @@
use crate::processor::{verify_receipt, EVMProcessor};
use reth_interfaces::executor::{BlockExecutionError, BlockValidationError};
use reth_interfaces::executor::{
BlockExecutionError, BlockValidationError, OptimismBlockExecutionError,
};
use reth_primitives::{
revm::compat::into_reth_log, revm_primitives::ResultAndState, Address, Block, Hardfork,
Receipt, U256,
@ -74,7 +76,11 @@ impl<'a> BlockExecutor for EVMProcessor<'a> {
// so we can safely assume that this will always be triggered upon the transition and that
// the above check for empty blocks will never be hit on OP chains.
super::ensure_create2_deployer(self.chain_spec().clone(), block.timestamp, self.db_mut())
.map_err(|_| BlockExecutionError::ProviderError)?;
.map_err(|_| {
BlockExecutionError::OptimismBlockExecution(
OptimismBlockExecutionError::ForceCreate2DeployerFail,
)
})?;
let mut cumulative_gas_used = 0;
let mut receipts = Vec::with_capacity(block.body.len());

View File

@ -4,17 +4,16 @@ use crate::{
stack::{InspectorStack, InspectorStackConfig},
state_change::{apply_beacon_root_contract_call, post_block_balance_increments},
};
use reth_interfaces::{
executor::{BlockExecutionError, BlockValidationError},
RethError,
};
use reth_interfaces::executor::{BlockExecutionError, BlockValidationError};
use reth_primitives::{
revm::env::{fill_cfg_and_block_env, fill_tx_env},
Address, Block, BlockNumber, Bloom, ChainSpec, GotExpected, Hardfork, Header, PruneMode,
PruneModes, PruneSegmentError, Receipt, ReceiptWithBloom, Receipts, TransactionSigned, B256,
MINIMUM_PRUNING_DISTANCE, U256,
};
use reth_provider::{BlockExecutor, BlockExecutorStats, PrunableBlockExecutor, StateProvider};
use reth_provider::{
BlockExecutor, BlockExecutorStats, ProviderError, PrunableBlockExecutor, StateProvider,
};
use revm::{
db::{states::bundle_state::BundleRetention, StateDBBox},
primitives::ResultAndState,
@ -53,7 +52,7 @@ pub struct EVMProcessor<'a> {
/// The configured chain-spec
pub(crate) chain_spec: Arc<ChainSpec>,
/// revm instance that contains database and env environment.
pub(crate) evm: EVM<StateDBBox<'a, RethError>>,
pub(crate) evm: EVM<StateDBBox<'a, ProviderError>>,
/// Hook and inspector stack that we want to invoke on that hook.
stack: InspectorStack,
/// The collection of receipts.
@ -115,7 +114,7 @@ impl<'a> EVMProcessor<'a> {
/// Create a new EVM processor with the given revm state.
pub fn new_with_state(
chain_spec: Arc<ChainSpec>,
revm_state: StateDBBox<'a, RethError>,
revm_state: StateDBBox<'a, ProviderError>,
) -> Self {
let mut evm = EVM::new();
evm.database(revm_state);
@ -143,7 +142,7 @@ impl<'a> EVMProcessor<'a> {
}
/// Returns a reference to the database
pub fn db_mut(&mut self) -> &mut StateDBBox<'a, RethError> {
pub fn db_mut(&mut self) -> &mut StateDBBox<'a, ProviderError> {
// Option will be removed from EVM in the future.
// as it is always some.
// https://github.com/bluealloy/revm/issues/697