|
|
|
|
@ -20,7 +20,6 @@ use std::fmt::Debug;
|
|
|
|
|
|
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
|
|
|
extern crate alloc;
|
|
|
|
|
|
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
|
|
|
use alloc::{fmt::Debug, vec::Vec};
|
|
|
|
|
|
|
|
|
|
@ -128,10 +127,10 @@ pub trait Consensus: Debug + Send + Sync {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Consensus Errors
|
|
|
|
|
#[derive(thiserror_no_std::Error, Debug, PartialEq, Eq, Clone)]
|
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, derive_more::Display)]
|
|
|
|
|
pub enum ConsensusError {
|
|
|
|
|
/// Error when the gas used in the header exceeds the gas limit.
|
|
|
|
|
#[error("block used gas ({gas_used}) is greater than gas limit ({gas_limit})")]
|
|
|
|
|
#[display(fmt = "block used gas ({gas_used}) is greater than gas limit ({gas_limit})")]
|
|
|
|
|
HeaderGasUsedExceedsGasLimit {
|
|
|
|
|
/// The gas used in the block header.
|
|
|
|
|
gas_used: u64,
|
|
|
|
|
@ -140,7 +139,9 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when block gas used doesn't match expected value
|
|
|
|
|
#[error("block gas used mismatch: {gas}; gas spent by each transaction: {gas_spent_by_tx:?}")]
|
|
|
|
|
#[display(
|
|
|
|
|
fmt = "block gas used mismatch: {gas}; gas spent by each transaction: {gas_spent_by_tx:?}"
|
|
|
|
|
)]
|
|
|
|
|
BlockGasUsed {
|
|
|
|
|
/// The gas diff.
|
|
|
|
|
gas: GotExpected<u64>,
|
|
|
|
|
@ -149,38 +150,38 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the hash of block ommer is different from the expected hash.
|
|
|
|
|
#[error("mismatched block ommer hash: {0}")]
|
|
|
|
|
#[display(fmt = "mismatched block ommer hash: {_0}")]
|
|
|
|
|
BodyOmmersHashDiff(GotExpectedBoxed<B256>),
|
|
|
|
|
|
|
|
|
|
/// Error when the state root in the block is different from the expected state root.
|
|
|
|
|
#[error("mismatched block state root: {0}")]
|
|
|
|
|
#[display(fmt = "mismatched block state root: {_0}")]
|
|
|
|
|
BodyStateRootDiff(GotExpectedBoxed<B256>),
|
|
|
|
|
|
|
|
|
|
/// Error when the transaction root in the block is different from the expected transaction
|
|
|
|
|
/// root.
|
|
|
|
|
#[error("mismatched block transaction root: {0}")]
|
|
|
|
|
#[display(fmt = "mismatched block transaction root: {_0}")]
|
|
|
|
|
BodyTransactionRootDiff(GotExpectedBoxed<B256>),
|
|
|
|
|
|
|
|
|
|
/// Error when the receipt root in the block is different from the expected receipt root.
|
|
|
|
|
#[error("receipt root mismatch: {0}")]
|
|
|
|
|
#[display(fmt = "receipt root mismatch: {_0}")]
|
|
|
|
|
BodyReceiptRootDiff(GotExpectedBoxed<B256>),
|
|
|
|
|
|
|
|
|
|
/// Error when header bloom filter is different from the expected bloom filter.
|
|
|
|
|
#[error("header bloom filter mismatch: {0}")]
|
|
|
|
|
#[display(fmt = "header bloom filter mismatch: {_0}")]
|
|
|
|
|
BodyBloomLogDiff(GotExpectedBoxed<Bloom>),
|
|
|
|
|
|
|
|
|
|
/// Error when the withdrawals root in the block is different from the expected withdrawals
|
|
|
|
|
/// root.
|
|
|
|
|
#[error("mismatched block withdrawals root: {0}")]
|
|
|
|
|
#[display(fmt = "mismatched block withdrawals root: {_0}")]
|
|
|
|
|
BodyWithdrawalsRootDiff(GotExpectedBoxed<B256>),
|
|
|
|
|
|
|
|
|
|
/// Error when the requests root in the block is different from the expected requests
|
|
|
|
|
/// root.
|
|
|
|
|
#[error("mismatched block requests root: {0}")]
|
|
|
|
|
#[display(fmt = "mismatched block requests root: {_0}")]
|
|
|
|
|
BodyRequestsRootDiff(GotExpectedBoxed<B256>),
|
|
|
|
|
|
|
|
|
|
/// Error when a block with a specific hash and number is already known.
|
|
|
|
|
#[error("block with [hash={hash}, number={number}] is already known")]
|
|
|
|
|
#[display(fmt = "block with [hash={hash}, number={number}] is already known")]
|
|
|
|
|
BlockKnown {
|
|
|
|
|
/// The hash of the known block.
|
|
|
|
|
hash: BlockHash,
|
|
|
|
|
@ -189,15 +190,15 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the parent hash of a block is not known.
|
|
|
|
|
#[error("block parent [hash={hash}] is not known")]
|
|
|
|
|
#[display(fmt = "block parent [hash={hash}] is not known")]
|
|
|
|
|
ParentUnknown {
|
|
|
|
|
/// The hash of the unknown parent block.
|
|
|
|
|
hash: BlockHash,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the block number does not match the parent block number.
|
|
|
|
|
#[error(
|
|
|
|
|
"block number {block_number} does not match parent block number {parent_block_number}"
|
|
|
|
|
#[display(
|
|
|
|
|
fmt = "block number {block_number} does not match parent block number {parent_block_number}"
|
|
|
|
|
)]
|
|
|
|
|
ParentBlockNumberMismatch {
|
|
|
|
|
/// The parent block number.
|
|
|
|
|
@ -207,11 +208,13 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the parent hash does not match the expected parent hash.
|
|
|
|
|
#[error("mismatched parent hash: {0}")]
|
|
|
|
|
#[display(fmt = "mismatched parent hash: {_0}")]
|
|
|
|
|
ParentHashMismatch(GotExpectedBoxed<B256>),
|
|
|
|
|
|
|
|
|
|
/// Error when the block timestamp is in the future compared to our clock time.
|
|
|
|
|
#[error("block timestamp {timestamp} is in the future compared to our clock time {present_timestamp}")]
|
|
|
|
|
#[display(
|
|
|
|
|
fmt = "block timestamp {timestamp} is in the future compared to our clock time {present_timestamp}"
|
|
|
|
|
)]
|
|
|
|
|
TimestampIsInFuture {
|
|
|
|
|
/// The block's timestamp.
|
|
|
|
|
timestamp: u64,
|
|
|
|
|
@ -220,82 +223,84 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the base fee is missing.
|
|
|
|
|
#[error("base fee missing")]
|
|
|
|
|
#[display(fmt = "base fee missing")]
|
|
|
|
|
BaseFeeMissing,
|
|
|
|
|
|
|
|
|
|
/// Error when there is a transaction signer recovery error.
|
|
|
|
|
#[error("transaction signer recovery error")]
|
|
|
|
|
#[display(fmt = "transaction signer recovery error")]
|
|
|
|
|
TransactionSignerRecoveryError,
|
|
|
|
|
|
|
|
|
|
/// Error when the extra data length exceeds the maximum allowed.
|
|
|
|
|
#[error("extra data {len} exceeds max length")]
|
|
|
|
|
#[display(fmt = "extra data {len} exceeds max length")]
|
|
|
|
|
ExtraDataExceedsMax {
|
|
|
|
|
/// The length of the extra data.
|
|
|
|
|
len: usize,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the difficulty after a merge is not zero.
|
|
|
|
|
#[error("difficulty after merge is not zero")]
|
|
|
|
|
#[display(fmt = "difficulty after merge is not zero")]
|
|
|
|
|
TheMergeDifficultyIsNotZero,
|
|
|
|
|
|
|
|
|
|
/// Error when the nonce after a merge is not zero.
|
|
|
|
|
#[error("nonce after merge is not zero")]
|
|
|
|
|
#[display(fmt = "nonce after merge is not zero")]
|
|
|
|
|
TheMergeNonceIsNotZero,
|
|
|
|
|
|
|
|
|
|
/// Error when the ommer root after a merge is not empty.
|
|
|
|
|
#[error("ommer root after merge is not empty")]
|
|
|
|
|
#[display(fmt = "ommer root after merge is not empty")]
|
|
|
|
|
TheMergeOmmerRootIsNotEmpty,
|
|
|
|
|
|
|
|
|
|
/// Error when the withdrawals root is missing.
|
|
|
|
|
#[error("missing withdrawals root")]
|
|
|
|
|
#[display(fmt = "missing withdrawals root")]
|
|
|
|
|
WithdrawalsRootMissing,
|
|
|
|
|
|
|
|
|
|
/// Error when the requests root is missing.
|
|
|
|
|
#[error("missing requests root")]
|
|
|
|
|
#[display(fmt = "missing requests root")]
|
|
|
|
|
RequestsRootMissing,
|
|
|
|
|
|
|
|
|
|
/// Error when an unexpected withdrawals root is encountered.
|
|
|
|
|
#[error("unexpected withdrawals root")]
|
|
|
|
|
#[display(fmt = "unexpected withdrawals root")]
|
|
|
|
|
WithdrawalsRootUnexpected,
|
|
|
|
|
|
|
|
|
|
/// Error when an unexpected requests root is encountered.
|
|
|
|
|
#[error("unexpected requests root")]
|
|
|
|
|
#[display(fmt = "unexpected requests root")]
|
|
|
|
|
RequestsRootUnexpected,
|
|
|
|
|
|
|
|
|
|
/// Error when withdrawals are missing.
|
|
|
|
|
#[error("missing withdrawals")]
|
|
|
|
|
#[display(fmt = "missing withdrawals")]
|
|
|
|
|
BodyWithdrawalsMissing,
|
|
|
|
|
|
|
|
|
|
/// Error when requests are missing.
|
|
|
|
|
#[error("missing requests")]
|
|
|
|
|
#[display(fmt = "missing requests")]
|
|
|
|
|
BodyRequestsMissing,
|
|
|
|
|
|
|
|
|
|
/// Error when blob gas used is missing.
|
|
|
|
|
#[error("missing blob gas used")]
|
|
|
|
|
#[display(fmt = "missing blob gas used")]
|
|
|
|
|
BlobGasUsedMissing,
|
|
|
|
|
|
|
|
|
|
/// Error when unexpected blob gas used is encountered.
|
|
|
|
|
#[error("unexpected blob gas used")]
|
|
|
|
|
#[display(fmt = "unexpected blob gas used")]
|
|
|
|
|
BlobGasUsedUnexpected,
|
|
|
|
|
|
|
|
|
|
/// Error when excess blob gas is missing.
|
|
|
|
|
#[error("missing excess blob gas")]
|
|
|
|
|
#[display(fmt = "missing excess blob gas")]
|
|
|
|
|
ExcessBlobGasMissing,
|
|
|
|
|
|
|
|
|
|
/// Error when unexpected excess blob gas is encountered.
|
|
|
|
|
#[error("unexpected excess blob gas")]
|
|
|
|
|
#[display(fmt = "unexpected excess blob gas")]
|
|
|
|
|
ExcessBlobGasUnexpected,
|
|
|
|
|
|
|
|
|
|
/// Error when the parent beacon block root is missing.
|
|
|
|
|
#[error("missing parent beacon block root")]
|
|
|
|
|
#[display(fmt = "missing parent beacon block root")]
|
|
|
|
|
ParentBeaconBlockRootMissing,
|
|
|
|
|
|
|
|
|
|
/// Error when an unexpected parent beacon block root is encountered.
|
|
|
|
|
#[error("unexpected parent beacon block root")]
|
|
|
|
|
#[display(fmt = "unexpected parent beacon block root")]
|
|
|
|
|
ParentBeaconBlockRootUnexpected,
|
|
|
|
|
|
|
|
|
|
/// Error when blob gas used exceeds the maximum allowed.
|
|
|
|
|
#[error("blob gas used {blob_gas_used} exceeds maximum allowance {max_blob_gas_per_block}")]
|
|
|
|
|
#[display(
|
|
|
|
|
fmt = "blob gas used {blob_gas_used} exceeds maximum allowance {max_blob_gas_per_block}"
|
|
|
|
|
)]
|
|
|
|
|
BlobGasUsedExceedsMaxBlobGasPerBlock {
|
|
|
|
|
/// The actual blob gas used.
|
|
|
|
|
blob_gas_used: u64,
|
|
|
|
|
@ -304,8 +309,8 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when blob gas used is not a multiple of blob gas per blob.
|
|
|
|
|
#[error(
|
|
|
|
|
"blob gas used {blob_gas_used} is not a multiple of blob gas per blob {blob_gas_per_blob}"
|
|
|
|
|
#[display(
|
|
|
|
|
fmt = "blob gas used {blob_gas_used} is not a multiple of blob gas per blob {blob_gas_per_blob}"
|
|
|
|
|
)]
|
|
|
|
|
BlobGasUsedNotMultipleOfBlobGasPerBlob {
|
|
|
|
|
/// The actual blob gas used.
|
|
|
|
|
@ -315,8 +320,8 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when excess blob gas is not a multiple of blob gas per blob.
|
|
|
|
|
#[error(
|
|
|
|
|
"excess blob gas {excess_blob_gas} is not a multiple of blob gas per blob {blob_gas_per_blob}"
|
|
|
|
|
#[display(
|
|
|
|
|
fmt = "excess blob gas {excess_blob_gas} is not a multiple of blob gas per blob {blob_gas_per_blob}"
|
|
|
|
|
)]
|
|
|
|
|
ExcessBlobGasNotMultipleOfBlobGasPerBlob {
|
|
|
|
|
/// The actual excess blob gas.
|
|
|
|
|
@ -326,23 +331,20 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the blob gas used in the header does not match the expected blob gas used.
|
|
|
|
|
#[error("blob gas used mismatch: {0}")]
|
|
|
|
|
#[display(fmt = "blob gas used mismatch: {_0}")]
|
|
|
|
|
BlobGasUsedDiff(GotExpected<u64>),
|
|
|
|
|
|
|
|
|
|
/// Error for a transaction that violates consensus.
|
|
|
|
|
#[error(transparent)]
|
|
|
|
|
InvalidTransaction(#[from] InvalidTransactionError),
|
|
|
|
|
InvalidTransaction(InvalidTransactionError),
|
|
|
|
|
|
|
|
|
|
/// Error when the block's base fee is different from the expected base fee.
|
|
|
|
|
#[error("block base fee mismatch: {0}")]
|
|
|
|
|
#[display(fmt = "block base fee mismatch: {_0}")]
|
|
|
|
|
BaseFeeDiff(GotExpected<u64>),
|
|
|
|
|
|
|
|
|
|
/// Error when there is an invalid excess blob gas.
|
|
|
|
|
#[error(
|
|
|
|
|
"invalid excess blob gas: {diff}; \
|
|
|
|
|
#[display(fmt = "invalid excess blob gas: {diff}; \
|
|
|
|
|
parent excess blob gas: {parent_excess_blob_gas}, \
|
|
|
|
|
parent blob gas used: {parent_blob_gas_used}"
|
|
|
|
|
)]
|
|
|
|
|
parent blob gas used: {parent_blob_gas_used}")]
|
|
|
|
|
ExcessBlobGasDiff {
|
|
|
|
|
/// The excess blob gas diff.
|
|
|
|
|
diff: GotExpected<u64>,
|
|
|
|
|
@ -353,7 +355,7 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the child gas limit exceeds the maximum allowed increase.
|
|
|
|
|
#[error("child gas_limit {child_gas_limit} max increase is {parent_gas_limit}/1024")]
|
|
|
|
|
#[display(fmt = "child gas_limit {child_gas_limit} max increase is {parent_gas_limit}/1024")]
|
|
|
|
|
GasLimitInvalidIncrease {
|
|
|
|
|
/// The parent gas limit.
|
|
|
|
|
parent_gas_limit: u64,
|
|
|
|
|
@ -364,14 +366,16 @@ pub enum ConsensusError {
|
|
|
|
|
/// Error indicating that the child gas limit is below the minimum allowed limit.
|
|
|
|
|
///
|
|
|
|
|
/// This error occurs when the child gas limit is less than the specified minimum gas limit.
|
|
|
|
|
#[error("child gas limit {child_gas_limit} is below the minimum allowed limit ({MINIMUM_GAS_LIMIT})")]
|
|
|
|
|
#[display(
|
|
|
|
|
fmt = "child gas limit {child_gas_limit} is below the minimum allowed limit ({MINIMUM_GAS_LIMIT})"
|
|
|
|
|
)]
|
|
|
|
|
GasLimitInvalidMinimum {
|
|
|
|
|
/// The child gas limit.
|
|
|
|
|
child_gas_limit: u64,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the child gas limit exceeds the maximum allowed decrease.
|
|
|
|
|
#[error("child gas_limit {child_gas_limit} max decrease is {parent_gas_limit}/1024")]
|
|
|
|
|
#[display(fmt = "child gas_limit {child_gas_limit} max decrease is {parent_gas_limit}/1024")]
|
|
|
|
|
GasLimitInvalidDecrease {
|
|
|
|
|
/// The parent gas limit.
|
|
|
|
|
parent_gas_limit: u64,
|
|
|
|
|
@ -380,7 +384,9 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/// Error when the block timestamp is in the past compared to the parent timestamp.
|
|
|
|
|
#[error("block timestamp {timestamp} is in the past compared to the parent timestamp {parent_timestamp}")]
|
|
|
|
|
#[display(
|
|
|
|
|
fmt = "block timestamp {timestamp} is in the past compared to the parent timestamp {parent_timestamp}"
|
|
|
|
|
)]
|
|
|
|
|
TimestampIsInPast {
|
|
|
|
|
/// The parent block's timestamp.
|
|
|
|
|
parent_timestamp: u64,
|
|
|
|
|
@ -389,6 +395,16 @@ pub enum ConsensusError {
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
|
impl std::error::Error for ConsensusError {
|
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
|
|
|
match self {
|
|
|
|
|
Self::InvalidTransaction(err) => std::error::Error::source(err),
|
|
|
|
|
_ => Option::None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ConsensusError {
|
|
|
|
|
/// Returns `true` if the error is a state root error.
|
|
|
|
|
pub const fn is_state_root_error(&self) -> bool {
|
|
|
|
|
@ -396,7 +412,16 @@ impl ConsensusError {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<InvalidTransactionError> for ConsensusError {
|
|
|
|
|
fn from(value: InvalidTransactionError) -> Self {
|
|
|
|
|
Self::InvalidTransaction(value)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// `HeaderConsensusError` combines a `ConsensusError` with the `SealedHeader` it relates to.
|
|
|
|
|
#[derive(thiserror_no_std::Error, Debug)]
|
|
|
|
|
#[error("Consensus error: {0}, Invalid header: {1:?}")]
|
|
|
|
|
#[derive(derive_more::Display, Debug)]
|
|
|
|
|
#[display(fmt = "Consensus error: {_0}, Invalid header: {_1:?}")]
|
|
|
|
|
pub struct HeaderConsensusError(ConsensusError, SealedHeader);
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
|
impl std::error::Error for HeaderConsensusError {}
|
|
|
|
|
|