ethrex_blockchain/
error.rs1use ethrex_common::{
2 H256,
3 types::{BlobsBundleError, BlockHash},
4};
5use ethrex_rlp::error::RLPDecodeError;
6use ethrex_storage::error::StoreError;
7use ethrex_trie::TrieError;
8use ethrex_vm::EvmError;
9
10pub use ethrex_common::InvalidBlockError;
12
13#[derive(Debug, thiserror::Error)]
14pub enum ChainError {
15 #[error("Invalid Block: {0}")]
16 InvalidBlock(#[from] InvalidBlockError),
17 #[error("Parent block not found")]
18 ParentNotFound,
19 #[error("The post-state of the parent-block.")]
22 ParentStateNotFound,
23 #[error("DB error: {0}")]
24 StoreError(#[from] StoreError),
25 #[error("Trie error: {0}")]
26 TrieError(#[from] TrieError),
27 #[error("RLP decode error: {0}")]
28 RLPDecodeError(#[from] RLPDecodeError),
29 #[error("EVM error: {0}")]
30 EvmError(EvmError),
31 #[error("Invalid Transaction: {0}")]
32 InvalidTransaction(String),
33 #[error("Failed to generate witness: {0}")]
34 WitnessGeneration(String),
35 #[error("{0}")]
36 Custom(String),
37 #[error("Unknown Payload")]
38 UnknownPayload,
39}
40
41impl From<EvmError> for ChainError {
42 fn from(value: EvmError) -> Self {
43 match value {
44 EvmError::Transaction(err) => {
45 ChainError::InvalidBlock(InvalidBlockError::InvalidTransaction(err))
46 }
47 EvmError::InvalidDepositRequest => ChainError::InvalidBlock(
48 InvalidBlockError::InvalidTransaction("Invalid deposit request layout".to_string()),
49 ),
50 other_errors => ChainError::EvmError(other_errors),
51 }
52 }
53}
54
55#[cfg(feature = "metrics")]
56impl ChainError {
57 pub fn to_metric(&self) -> &str {
58 match self {
59 ChainError::InvalidBlock(_) => "invalid_block",
60 ChainError::ParentNotFound => "parent_not_found",
61 ChainError::ParentStateNotFound => "parent_state_not_found",
62 ChainError::StoreError(_) => "store_error",
63 ChainError::TrieError(_) => "trie_error",
64 ChainError::RLPDecodeError(_) => "rlp_decode_error",
65 ChainError::EvmError(_) => "evm_error",
66 ChainError::InvalidTransaction(_) => "invalid_transaction",
67 ChainError::WitnessGeneration(_) => "witness_generation",
68 ChainError::Custom(_) => "custom_error",
69 ChainError::UnknownPayload => "unknown_payload",
70 }
71 }
72}
73
74#[derive(Debug, thiserror::Error)]
75pub enum MempoolError {
76 #[error("No block header")]
77 NoBlockHeaderError,
78 #[error("DB error: {0}")]
79 StoreError(#[from] StoreError),
80 #[error("BlobsBundle error: {0}")]
81 BlobsBundleError(#[from] BlobsBundleError),
82 #[error("Transaction max init code size exceeded")]
83 TxMaxInitCodeSizeError,
84 #[error("Transaction encoded size ({actual} bytes) exceeds the {limit}-byte limit")]
85 TxSizeExceeded { actual: usize, limit: usize },
86 #[error("Transaction gas limit exceeded")]
87 TxGasLimitExceededError,
88 #[error(
89 "Transaction gas limit exceeds maximum. Transaction hash: {0}, transaction gas limit: {1}"
90 )]
91 TxMaxGasLimitExceededError(H256, u64),
92 #[error("Transaction priority fee above gas fee")]
93 TxGasOverflowError,
94 #[error("Transaction intrinsic gas overflow")]
95 TxTipAboveFeeCapError,
96 #[error("Transaction intrinsic gas cost above gas limit")]
97 TxIntrinsicGasCostAboveLimitError,
98 #[error("Transaction blob base fee too low")]
99 TxBlobBaseFeeTooLowError,
100 #[error("Blob transaction submited without blobs bundle")]
101 BlobTxNoBlobsBundle,
102 #[error("Nonce for account too low")]
103 NonceTooLow,
104 #[error("Nonce already used")]
105 InvalidNonce,
106 #[error("Transaction chain id mismatch, expected chain id: {0}")]
107 InvalidChainId(u64),
108 #[error("Account does not have enough balance to cover the tx cost")]
109 NotEnoughBalance,
110 #[error("Transaction gas fields are invalid")]
111 InvalidTxGasvalues,
112 #[error("Invalid pooled TxType, expected: {0}")]
113 InvalidPooledTxType(u8),
114 #[error("Invalid pooled transaction size, differs from expected")]
115 InvalidPooledTxSize,
116 #[error("Requested pooled transaction was not received")]
117 RequestedPooledTxNotFound,
118 #[error("Transaction sender is invalid {0}")]
119 InvalidTxSender(#[from] ethrex_crypto::CryptoError),
120 #[error("Attempted to replace a pooled transaction with an underpriced transaction")]
121 UnderpricedReplacement,
122}
123
124#[derive(Debug)]
125pub enum ForkChoiceElement {
126 Head,
127 Safe,
128 Finalized,
129}
130
131#[derive(Debug, thiserror::Error)]
132pub enum InvalidForkChoice {
133 #[error("DB error: {0}")]
134 StoreError(#[from] StoreError),
135 #[error("The node has not finished syncing.")]
136 Syncing,
137 #[error("Head hash value is invalid.")]
138 InvalidHeadHash,
139 #[error("New head block is already canonical. Skipping update.")]
140 NewHeadAlreadyCanonical,
141 #[error("A fork choice element ({:?}) was not found, but an ancestor was, so it's not a sync problem.", ._0)]
142 ElementNotFound(ForkChoiceElement),
143 #[error("Pre merge block can't be a fork choice update.")]
144 PreMergeBlock,
145 #[error("Safe, finalized and head blocks are not in the correct order.")]
146 Unordered,
147 #[error("The following blocks are not connected between each other: {:?}, {:?}", ._0, ._1)]
148 Disconnected(ForkChoiceElement, ForkChoiceElement),
149 #[error("Requested head is an invalid block.")]
150 InvalidHead,
151 #[error("Previously rejected block.")]
152 InvalidAncestor(BlockHash),
153 #[error("Cannot find link between Head and the canonical chain")]
154 UnlinkedHead,
155 #[error("Reorg depth {reorg_depth} exceeds the client's limit of {limit}")]
156 TooDeepReorg { reorg_depth: u64, limit: u64 },
157
158 #[error("State root of the new head is not reachable from the database")]
160 StateNotReachable,
161}