chore: refactor BlockExecutionError into validation and internal errors (#9911)

This commit is contained in:
Dan Cline
2024-07-30 14:30:30 -04:00
committed by GitHub
parent dec0c44035
commit 9586b9a4f5
6 changed files with 72 additions and 33 deletions

View File

@@ -289,10 +289,7 @@ impl InsertBlockErrorKind {
true
}
// these are internal errors, not caused by an invalid block
BlockExecutionError::LatestBlock(_) |
BlockExecutionError::Pruning(_) |
BlockExecutionError::AppendChainDoesntConnect { .. } |
BlockExecutionError::Other(_) => false,
BlockExecutionError::Internal(_) => false,
}
}
Self::Tree(err) => {

View File

@@ -19,7 +19,9 @@ use reth_beacon_consensus::BeaconEngineMessage;
use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_consensus::{Consensus, ConsensusError, PostExecutionInput};
use reth_engine_primitives::EngineTypes;
use reth_execution_errors::{BlockExecutionError, BlockValidationError};
use reth_execution_errors::{
BlockExecutionError, BlockValidationError, InternalBlockExecutionError,
};
use reth_execution_types::ExecutionOutcome;
use reth_primitives::{
eip4844::calculate_excess_blob_gas, proofs, Block, BlockBody, BlockHash, BlockHashOrNumber,
@@ -377,7 +379,7 @@ impl StorageInner {
trace!(target: "consensus::auto", transactions=?&block.body, "executing transactions");
let mut db = StateProviderDatabase::new(
provider.latest().map_err(BlockExecutionError::LatestBlock)?,
provider.latest().map_err(InternalBlockExecutionError::LatestBlock)?,
);
// execute the block

View File

@@ -116,15 +116,67 @@ pub enum BlockValidationError {
/// `BlockExecutor` Errors
#[derive(thiserror_no_std::Error, Debug)]
pub enum BlockExecutionError {
/// Validation error, transparently wrapping `BlockValidationError`
/// Validation error, transparently wrapping [`BlockValidationError`]
#[error(transparent)]
Validation(#[from] BlockValidationError),
/// Pruning error, transparently wrapping `PruneSegmentError`
#[error(transparent)]
Pruning(#[from] PruneSegmentError),
/// Consensus error, transparently wrapping `ConsensusError`
/// Consensus error, transparently wrapping [`ConsensusError`]
#[error(transparent)]
Consensus(#[from] ConsensusError),
/// Internal, i.e. non consensus or validation related Block Executor Errors
#[error(transparent)]
Internal(#[from] InternalBlockExecutionError),
}
impl From<ProviderError> for BlockExecutionError {
fn from(value: ProviderError) -> Self {
InternalBlockExecutionError::from(value).into()
}
}
impl From<PruneSegmentError> for BlockExecutionError {
fn from(value: PruneSegmentError) -> Self {
InternalBlockExecutionError::from(value).into()
}
}
impl BlockExecutionError {
/// Create a new [`BlockExecutionError::Internal`] variant, containing a
/// [`InternalBlockExecutionError::Other`] error.
#[cfg(feature = "std")]
pub fn other<E>(error: E) -> Self
where
E: std::error::Error + Send + Sync + 'static,
{
Self::Internal(InternalBlockExecutionError::other(error))
}
/// Create a new [`BlockExecutionError::Internal`] variant, containing a
/// [`InternalBlockExecutionError::Other`] error with the given message.
#[cfg(feature = "std")]
pub fn msg(msg: impl std::fmt::Display) -> Self {
Self::Internal(InternalBlockExecutionError::msg(msg))
}
/// Returns the inner `BlockValidationError` if the error is a validation error.
pub const fn as_validation(&self) -> Option<&BlockValidationError> {
match self {
Self::Validation(err) => Some(err),
_ => None,
}
}
/// Returns `true` if the error is a state root error.
pub const fn is_state_root_error(&self) -> bool {
matches!(self, Self::Validation(BlockValidationError::StateRoot(_)))
}
}
/// Internal (i.e., not validation or consensus related) `BlockExecutor` Errors
#[derive(thiserror_no_std::Error, Debug)]
pub enum InternalBlockExecutionError {
/// Pruning error, transparently wrapping [`PruneSegmentError`]
#[error(transparent)]
Pruning(#[from] PruneSegmentError),
/// Error when appending chain on fork is not possible
#[error(
"appending chain on fork (other_chain_fork:?) is not possible as the tip is {chain_tip:?}"
@@ -144,8 +196,8 @@ pub enum BlockExecutionError {
Other(Box<dyn std::error::Error + Send + Sync>),
}
impl BlockExecutionError {
/// Create a new `BlockExecutionError::Other` variant.
impl InternalBlockExecutionError {
/// Create a new [`InternalBlockExecutionError::Other`] variant.
#[cfg(feature = "std")]
pub fn other<E>(error: E) -> Self
where
@@ -154,22 +206,9 @@ impl BlockExecutionError {
Self::Other(Box::new(error))
}
/// Create a new [`BlockExecutionError::Other`] from a given message.
/// Create a new [`InternalBlockExecutionError::Other`] from a given message.
#[cfg(feature = "std")]
pub fn msg(msg: impl std::fmt::Display) -> Self {
Self::Other(msg.to_string().into())
}
/// Returns the inner `BlockValidationError` if the error is a validation error.
pub const fn as_validation(&self) -> Option<&BlockValidationError> {
match self {
Self::Validation(err) => Some(err),
_ => None,
}
}
/// Returns `true` if the error is a state root error.
pub const fn is_state_root_error(&self) -> bool {
matches!(self, Self::Validation(BlockValidationError::StateRoot(_)))
}
}

View File

@@ -1,7 +1,7 @@
//! Contains [Chain], a chain of blocks and their final state.
use crate::ExecutionOutcome;
use reth_execution_errors::BlockExecutionError;
use reth_execution_errors::{BlockExecutionError, InternalBlockExecutionError};
use reth_primitives::{
Address, BlockHash, BlockNumHash, BlockNumber, ForkBlock, Receipt, SealedBlock,
SealedBlockWithSenders, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, TxHash,
@@ -261,10 +261,11 @@ impl Chain {
let chain_tip = self.tip();
let other_fork_block = other.fork_block();
if chain_tip.hash() != other_fork_block.hash {
return Err(BlockExecutionError::AppendChainDoesntConnect {
return Err(InternalBlockExecutionError::AppendChainDoesntConnect {
chain_tip: Box::new(chain_tip.num_hash()),
other_chain_fork: Box::new(other_fork_block),
})
}
.into())
}
// Insert blocks from other chain

View File

@@ -93,7 +93,7 @@ where
}
match ready!(this.tasks.poll_next_unpin(cx)) {
Some(res) => Poll::Ready(Some(res.map_err(|e| BlockExecutionError::Other(e.into()))?)),
Some(res) => Poll::Ready(Some(res.map_err(BlockExecutionError::other)?)),
None => Poll::Ready(None),
}
}

View File

@@ -4,7 +4,7 @@ use crate::{
precompile::{Address, HashSet},
primitives::alloy_primitives::BlockNumber,
};
use reth_execution_errors::BlockExecutionError;
use reth_execution_errors::{BlockExecutionError, InternalBlockExecutionError};
use reth_primitives::{Receipt, Receipts, Request, Requests};
use reth_prune_types::{PruneMode, PruneModes, PruneSegmentError, MINIMUM_PRUNING_DISTANCE};
use revm::db::states::bundle_state::BundleRetention;
@@ -118,7 +118,7 @@ impl BlockBatchRecord {
pub fn save_receipts(&mut self, receipts: Vec<Receipt>) -> Result<(), BlockExecutionError> {
let mut receipts = receipts.into_iter().map(Some).collect();
// Prune receipts if necessary.
self.prune_receipts(&mut receipts)?;
self.prune_receipts(&mut receipts).map_err(InternalBlockExecutionError::from)?;
// Save receipts.
self.receipts.push(receipts);
Ok(())