1use alloy_consensus::crypto::RecoveryError;
4use alloy_evm::overrides::StateOverrideError;
5use alloy_primitives::{B256, Bytes, SignatureError, TxHash, U256};
6use alloy_rpc_types::BlockNumberOrTag;
7use alloy_signer::Error as SignerError;
8use alloy_transport::TransportError;
9use anvil_core::eth::wallet::WalletError;
10use anvil_rpc::{
11 error::{ErrorCode, RpcError},
12 response::ResponseResult,
13};
14use foundry_evm::{backend::DatabaseError, decode::RevertDecoder};
15use revm::{
16 context_interface::result::{EVMError, InvalidHeader, InvalidTransaction},
17 interpreter::InstructionResult,
18};
19use serde::Serialize;
20use tempo_revm::TempoInvalidTransaction;
21use tokio::time::Duration;
22
23#[cfg(feature = "base")]
24mod base;
25#[cfg(feature = "optimism")]
26mod optimism;
27
28pub(crate) type Result<T> = std::result::Result<T, BlockchainError>;
29
30#[derive(Debug, thiserror::Error)]
31pub enum BlockchainError {
32 #[error(transparent)]
33 Pool(#[from] PoolError),
34 #[error("No signer available")]
35 NoSignerAvailable,
36 #[error("Chain Id not available")]
37 ChainIdNotAvailable,
38 #[error("Invalid input: `max_priority_fee_per_gas` greater than `max_fee_per_gas`")]
39 InvalidFeeInput,
40 #[error("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")]
41 ConflictingFeeFields,
42 #[error("Transaction data is empty")]
43 EmptyRawTransactionData,
44 #[error("Failed to decode signed transaction")]
45 FailedToDecodeSignedTransaction,
46 #[error("Failed to decode transaction")]
47 FailedToDecodeTransaction,
48 #[error("Failed to decode receipt")]
49 FailedToDecodeReceipt,
50 #[error("Cannot EIP-2718 encode transaction type 0x{0:x}")]
51 UnsupportedTransactionEncoding(u8),
52 #[error("Failed to decode state")]
53 FailedToDecodeStateDump,
54 #[error("Prevrandao not in the EVM's environment after merge")]
55 PrevrandaoNotSet,
56 #[error(transparent)]
57 SignatureError(#[from] SignatureError),
58 #[error(transparent)]
59 RecoveryError(#[from] RecoveryError),
60 #[error(transparent)]
61 SignerError(#[from] SignerError),
62 #[error("Rpc Endpoint not implemented")]
63 RpcUnimplemented,
64 #[error("Rpc error {0:?}")]
65 RpcError(RpcError),
66 #[error(transparent)]
67 InvalidTransaction(#[from] InvalidTransactionError),
68 #[error(transparent)]
69 FeeHistory(#[from] FeeHistoryError),
70 #[error(transparent)]
71 AlloyForkProvider(#[from] TransportError),
72 #[error("EVM error {0:?}")]
73 EvmError(InstructionResult),
74 #[error("Evm override error: {0}")]
75 EvmOverrideError(String),
76 #[error("Invalid url {0:?}")]
77 InvalidUrl(String),
78 #[error("unsupported fork network for chain {chain_id}: {reason}")]
79 UnsupportedForkNetwork { chain_id: u64, reason: &'static str },
80 #[error("Internal error: {0:?}")]
81 Internal(String),
82 #[error("BlockOutOfRangeError: block height is {0} but requested was {1}")]
83 BlockOutOfRange(u64, u64),
84 #[error("Resource not found")]
85 BlockNotFound,
86 #[error("unknown block")]
87 UnknownBlock,
88 #[error("transaction not found")]
90 TransactionNotFound,
91 #[error("Required data unavailable")]
92 DataUnavailable,
93 #[error("historical state needed to replay block {0} is not available")]
95 HistoricalStateUnavailable(u64),
96 #[error("Trie error: {0}")]
97 TrieError(String),
98 #[error("{0}")]
99 UintConversion(&'static str),
100 #[error("State override error: {0}")]
101 StateOverrideError(String),
102 #[error("Timestamp error: {0}")]
103 TimestampError(String),
104 #[error(transparent)]
105 DatabaseError(#[from] DatabaseError),
106 #[error(
107 "EIP-1559 style fee params (maxFeePerGas or maxPriorityFeePerGas) received but they are not supported by the current hardfork.\n\nYou can use them by running anvil with '--hardfork london' or later."
108 )]
109 EIP1559TransactionUnsupportedAtHardfork,
110 #[error(
111 "Access list received but is not supported by the current hardfork.\n\nYou can use it by running anvil with '--hardfork berlin' or later."
112 )]
113 EIP2930TransactionUnsupportedAtHardfork,
114 #[error(
115 "EIP-4844 fields received but is not supported by the current hardfork.\n\nYou can use it by running anvil with '--hardfork cancun' or later."
116 )]
117 EIP4844TransactionUnsupportedAtHardfork,
118 #[error(
119 "EIP-7702 fields received but is not supported by the current hardfork.\n\nYou can use it by running anvil with '--hardfork prague' or later."
120 )]
121 EIP7702TransactionUnsupportedAtHardfork,
122 #[cfg_attr(
125 all(feature = "base", feature = "optimism"),
126 error(
127 "op-stack deposit tx received but is not supported.\n\nYou can use it by running anvil with '--optimism' or '--network base'."
128 )
129 )]
130 #[cfg_attr(
131 all(feature = "base", not(feature = "optimism")),
132 error(
133 "op-stack deposit tx received but is not supported.\n\nYou can use it by running anvil with '--network base'."
134 )
135 )]
136 #[cfg_attr(
137 not(feature = "base"),
138 error(
139 "op-stack deposit tx received but is not supported.\n\nYou can use it by running anvil with '--optimism'."
140 )
141 )]
142 DepositTransactionUnsupported,
143 #[error(
144 "tempo transaction received but is not supported.\n\nYou can use it by running anvil with '--tempo'."
145 )]
146 TempoTransactionUnsupported,
147 #[cfg(feature = "base")]
148 #[error("Base transactions require native Base execution; run Anvil with --network base")]
149 BaseTransactionUnsupported,
150 #[error("Unknown transaction type not supported")]
151 UnknownTransactionType,
152 #[error("Excess blob gas not set.")]
153 ExcessBlobGasNotSet,
154 #[error("{0}")]
155 Message(String),
156 #[error("Transaction {hash} was added to the mempool but wasn't confirmed within {duration:?}")]
157 TransactionConfirmationTimeout {
158 hash: B256,
160 duration: Duration,
162 },
163 #[error("Invalid transaction request: {0}")]
164 InvalidTransactionRequest(String),
165 #[cfg(feature = "base")]
166 #[error("EIP-8130 transaction rejected: {0}")]
167 Eip8130TransactionRejected(String),
168 #[error("filter not found")]
169 FilterNotFound,
170}
171
172impl From<eyre::Report> for BlockchainError {
173 fn from(err: eyre::Report) -> Self {
174 Self::Message(err.to_string())
175 }
176}
177
178impl From<RpcError> for BlockchainError {
179 fn from(err: RpcError) -> Self {
180 Self::RpcError(err)
181 }
182}
183
184impl<T> From<EVMError<T>> for BlockchainError
185where
186 T: Into<Self>,
187{
188 fn from(err: EVMError<T>) -> Self {
189 match err {
190 EVMError::Transaction(err) => InvalidTransactionError::from(err).into(),
191 EVMError::Header(err) => match err {
192 InvalidHeader::ExcessBlobGasNotSet => Self::ExcessBlobGasNotSet,
193 InvalidHeader::PrevrandaoNotSet => Self::PrevrandaoNotSet,
194 },
195 EVMError::Database(err) => err.into(),
196 EVMError::Custom(err) => Self::Message(err),
197 EVMError::CustomAny(err) => Self::Message(err.to_string()),
198 }
199 }
200}
201
202impl<T> From<EVMError<T, TempoInvalidTransaction>> for BlockchainError
203where
204 T: Into<Self>,
205{
206 fn from(err: EVMError<T, TempoInvalidTransaction>) -> Self {
207 match err {
208 EVMError::Transaction(err) => match err {
209 TempoInvalidTransaction::EthInvalidTransaction(err) => {
210 InvalidTransactionError::from(err).into()
211 }
212 err => Self::Message(format!("tempo transaction error: {err}")),
213 },
214 EVMError::Header(err) => match err {
215 InvalidHeader::ExcessBlobGasNotSet => Self::ExcessBlobGasNotSet,
216 InvalidHeader::PrevrandaoNotSet => Self::PrevrandaoNotSet,
217 },
218 EVMError::Database(err) => err.into(),
219 EVMError::Custom(err) => Self::Message(err),
220 EVMError::CustomAny(err) => Self::Message(err.to_string()),
221 }
222 }
223}
224
225impl From<WalletError> for BlockchainError {
226 fn from(value: WalletError) -> Self {
227 Self::Message(value.to_string())
228 }
229}
230
231impl<E> From<StateOverrideError<E>> for BlockchainError
232where
233 E: Into<Self>,
234{
235 fn from(value: StateOverrideError<E>) -> Self {
236 match value {
237 StateOverrideError::InvalidBytecode(err) => Self::StateOverrideError(err.to_string()),
238 StateOverrideError::BothStateAndStateDiff(addr) => Self::StateOverrideError(format!(
239 "state and state_diff can't be used together for account {addr}",
240 )),
241 StateOverrideError::Database(err) => err.into(),
242 }
243 }
244}
245
246#[derive(Debug, thiserror::Error)]
248pub enum PoolError {
249 #[error("Transaction with cyclic dependent transactions")]
250 CyclicTransaction,
251 #[error("Tx: [{0:?}] insufficient gas price to replace existing transaction")]
253 ReplacementUnderpriced(TxHash),
254 #[error("Tx: [{0:?}] already Imported")]
255 AlreadyImported(TxHash),
256}
257
258#[derive(Debug, thiserror::Error)]
260pub enum FeeHistoryError {
261 #[error("requested block range is out of bounds")]
262 InvalidBlockRange,
263 #[error("reward percentiles must be strictly increasing and between 0 and 100")]
264 InvalidRewardPercentiles,
265 #[error("could not find block number requested: {0}")]
266 BlockNotFound(BlockNumberOrTag),
267}
268
269#[derive(Debug)]
270pub struct ErrDetail {
271 pub detail: String,
272}
273
274#[derive(Debug, thiserror::Error)]
276pub enum InvalidTransactionError {
277 #[error("nonce too low")]
279 NonceTooLow,
280 #[error("Nonce too high")]
283 NonceTooHigh,
284 #[error("nonce has max value")]
287 NonceMaxValue,
288 #[error("insufficient funds for transfer")]
290 InsufficientFundsForTransfer,
291 #[error("max initcode size exceeded")]
293 MaxInitCodeSizeExceeded,
294 #[error("Insufficient funds for gas * price + value")]
296 InsufficientFunds,
297 #[error("gas uint64 overflow")]
299 GasUintOverflow,
300 #[error("intrinsic gas too low")]
303 GasTooLow,
304 #[error("intrinsic gas too high -- {}",.0.detail)]
306 GasTooHigh(ErrDetail),
307 #[error("max priority fee per gas higher than max fee per gas")]
310 TipAboveFeeCap,
311 #[error("max fee per gas less than block base fee")]
313 FeeCapTooLow,
314 #[error("Out of gas: gas required exceeds allowance: {0:?}")]
316 BasicOutOfGas(u128),
317 #[error("execution reverted: {0:?}")]
319 Revert(Option<Bytes>),
320 #[error("sender not an eoa")]
322 SenderNoEOA,
323 #[error("invalid chain id for signer")]
325 InvalidChainId,
326 #[error("Incompatible EIP-155 transaction, signed for another chain")]
328 IncompatibleEIP155,
329 #[error("Access lists are not supported before the Berlin hardfork")]
331 AccessListNotSupported,
332 #[error("Block `blob_gas_price` is greater than tx-specified `max_fee_per_blob_gas`")]
335 BlobFeeCapTooLow(u128, u128),
336 #[error("Block `blob_versioned_hashes` is not supported before the Cancun hardfork")]
339 BlobVersionedHashesNotSupported,
340 #[error("`max_fee_per_blob_gas` is not supported for blocks before the Cancun hardfork.")]
342 MaxFeePerBlobGasNotSupported,
343 #[error("`blob_hashes` are required for EIP-4844 transactions")]
345 NoBlobHashes,
346 #[error("too many blobs in one transaction, have: {0}, max: {1}")]
347 TooManyBlobs(usize, usize),
348 #[error(transparent)]
350 BlobTransactionValidationError(#[from] alloy_consensus::BlobTransactionValidationError),
351 #[error("Blob transaction can't be a create transaction. `to` must be present.")]
353 BlobCreateTransaction,
354 #[error("Blob transaction contains a versioned hash with an incorrect version")]
356 BlobVersionNotSupported,
357 #[error("EIP-4844 blob transactions are not supported on Monad")]
359 MonadBlobTransactionUnsupported,
360 #[error("There should be at least one blob in a Blob transaction.")]
362 EmptyBlobs,
363 #[error("EIP-7702 authorization lists are not supported before the Prague hardfork")]
365 AuthorizationListNotSupported,
366 #[error("Transaction gas limit is greater than the block gas limit, gas_limit: {0}, cap: {1}")]
367 TxGasLimitGreaterThanCap(u64, u64),
368 #[error(transparent)]
370 Revm(revm::context_interface::result::InvalidTransaction),
371 #[error("op-deposit failure post regolith")]
373 DepositTxErrorPostRegolith,
374 #[error("missing enveloped transaction")]
376 MissingEnvelopedTx,
377 #[cfg(feature = "base")]
379 #[error("EIP-8130 transaction rejected: {0}")]
380 Eip8130(String),
381 #[error("native value transfer not allowed in Tempo mode")]
383 TempoNativeValueTransfer,
384 #[error("Tempo tx valid_before ({valid_before}) must be > current time + 3s ({min_allowed})")]
386 TempoValidBeforeExpired { valid_before: u64, min_allowed: u64 },
387 #[error(
389 "Tempo expiring nonce tx valid_before ({valid_before}) must be <= current time + {max_expiry_secs}s ({max_allowed})"
390 )]
391 TempoValidBeforeTooFar { valid_before: u64, max_expiry_secs: u64, max_allowed: u64 },
392 #[error(
394 "Tempo tx valid_after ({valid_after}) must be <= current time + {max_valid_after_secs}s ({max_allowed})"
395 )]
396 TempoValidAfterTooFar { valid_after: u64, max_valid_after_secs: u64, max_allowed: u64 },
397 #[error("Tempo tx has too many authorizations ({count}), max allowed is {max}")]
399 TempoTooManyAuthorizations { count: usize, max: usize },
400 #[error("insufficient fee token balance: have {balance}, need {required}")]
402 TempoInsufficientFeeTokenBalance { balance: U256, required: U256 },
403}
404
405impl From<InvalidTransaction> for InvalidTransactionError {
406 fn from(err: InvalidTransaction) -> Self {
407 match err {
408 InvalidTransaction::InvalidChainId => Self::InvalidChainId,
409 InvalidTransaction::PriorityFeeGreaterThanMaxFee => Self::TipAboveFeeCap,
410 InvalidTransaction::GasPriceLessThanBasefee => Self::FeeCapTooLow,
411 InvalidTransaction::CallerGasLimitMoreThanBlock => {
412 Self::GasTooHigh(ErrDetail { detail: String::from("CallerGasLimitMoreThanBlock") })
413 }
414 InvalidTransaction::CallGasCostMoreThanGasLimit { .. } => {
415 Self::GasTooHigh(ErrDetail { detail: String::from("CallGasCostMoreThanGasLimit") })
416 }
417 InvalidTransaction::GasFloorMoreThanGasLimit { .. } => {
418 Self::GasTooHigh(ErrDetail { detail: String::from("GasFloorMoreThanGasLimit") })
419 }
420 InvalidTransaction::RejectCallerWithCode => Self::SenderNoEOA,
421 InvalidTransaction::LackOfFundForMaxFee { .. } => Self::InsufficientFunds,
422 InvalidTransaction::OverflowPaymentInTransaction => Self::GasUintOverflow,
423 InvalidTransaction::NonceOverflowInTransaction => Self::NonceMaxValue,
424 InvalidTransaction::CreateInitCodeSizeLimit => Self::MaxInitCodeSizeExceeded,
425 InvalidTransaction::NonceTooHigh { .. } => Self::NonceTooHigh,
426 InvalidTransaction::NonceTooLow { .. } => Self::NonceTooLow,
427 InvalidTransaction::AccessListNotSupported => Self::AccessListNotSupported,
428 InvalidTransaction::BlobGasPriceGreaterThanMax {
429 block_blob_gas_price,
430 tx_max_fee_per_blob_gas,
431 } => Self::BlobFeeCapTooLow(block_blob_gas_price, tx_max_fee_per_blob_gas),
432 InvalidTransaction::BlobVersionedHashesNotSupported => {
433 Self::BlobVersionedHashesNotSupported
434 }
435 InvalidTransaction::MaxFeePerBlobGasNotSupported => Self::MaxFeePerBlobGasNotSupported,
436 InvalidTransaction::BlobCreateTransaction => Self::BlobCreateTransaction,
437 InvalidTransaction::BlobVersionNotSupported => Self::BlobVersionNotSupported,
438 InvalidTransaction::EmptyBlobs => Self::EmptyBlobs,
439 InvalidTransaction::TooManyBlobs { have, max } => Self::TooManyBlobs(have, max),
440 InvalidTransaction::AuthorizationListNotSupported => {
441 Self::AuthorizationListNotSupported
442 }
443 InvalidTransaction::TxGasLimitGreaterThanCap { gas_limit, cap } => {
444 Self::TxGasLimitGreaterThanCap(gas_limit, cap)
445 }
446
447 InvalidTransaction::AuthorizationListInvalidFields
448 | InvalidTransaction::Eip1559NotSupported
449 | InvalidTransaction::Eip2930NotSupported
450 | InvalidTransaction::Eip4844NotSupported
451 | InvalidTransaction::Eip7702NotSupported
452 | InvalidTransaction::EmptyAuthorizationList
453 | InvalidTransaction::Eip7873NotSupported
454 | InvalidTransaction::Eip7873MissingTarget
455 | InvalidTransaction::MissingChainId
456 | InvalidTransaction::Str(_) => Self::Revm(err),
457 }
458 }
459}
460
461pub(crate) trait ToRpcResponseResult {
463 fn to_rpc_result(self) -> ResponseResult;
464}
465
466pub fn to_rpc_result<T: Serialize>(val: T) -> ResponseResult {
468 match serde_json::to_value(val) {
469 Ok(success) => ResponseResult::Success(success),
470 Err(err) => {
471 error!(%err, "Failed serialize rpc response");
472 ResponseResult::error(RpcError::internal_error())
473 }
474 }
475}
476
477impl<T: Serialize> ToRpcResponseResult for Result<T> {
478 fn to_rpc_result(self) -> ResponseResult {
479 match self {
480 Ok(val) => to_rpc_result(val),
481 Err(err) => match err {
482 BlockchainError::Pool(err) => {
483 error!(%err, "txpool error");
484 match err {
485 PoolError::CyclicTransaction => {
486 RpcError::transaction_rejected("Cyclic transaction detected")
487 }
488 PoolError::ReplacementUnderpriced(_) => {
489 RpcError::transaction_rejected("replacement transaction underpriced")
490 }
491 PoolError::AlreadyImported(_) => {
492 RpcError::transaction_rejected("transaction already imported")
493 }
494 }
495 }
496 BlockchainError::NoSignerAvailable => {
497 RpcError::invalid_params("No Signer available")
498 }
499 BlockchainError::ChainIdNotAvailable => {
500 RpcError::invalid_params("Chain Id not available")
501 }
502 BlockchainError::TransactionConfirmationTimeout { hash, .. } => RpcError {
503 code: ErrorCode::ServerError(4),
504 message: "Transaction confirmation timeout".into(),
505 data: Some(serde_json::Value::String(hash.to_string())),
506 },
507 BlockchainError::InvalidTransaction(err) => match err {
508 InvalidTransactionError::Revert(data) => {
509 let mut msg = "execution reverted".to_string();
511 if let Some(reason) = data
512 .as_ref()
513 .and_then(|data| RevertDecoder::new().maybe_decode(data, None))
514 {
515 msg = format!("{msg}: {reason}");
516 }
517 RpcError {
518 code: ErrorCode::ExecutionError,
520 message: msg.into(),
521 data: serde_json::to_value(data).ok(),
522 }
523 }
524 InvalidTransactionError::GasTooLow => {
525 RpcError {
527 code: ErrorCode::ServerError(-32000),
528 message: err.to_string().into(),
529 data: None,
530 }
531 }
532 InvalidTransactionError::GasTooHigh(_) => {
533 RpcError {
535 code: ErrorCode::ServerError(-32000),
536 message: err.to_string().into(),
537 data: None,
538 }
539 }
540 _ => RpcError::transaction_rejected(err.to_string()),
541 },
542 BlockchainError::FeeHistory(err) => RpcError::invalid_params(err.to_string()),
543 BlockchainError::EmptyRawTransactionData => {
544 RpcError::invalid_params("Empty transaction data")
545 }
546 BlockchainError::FailedToDecodeSignedTransaction => {
547 RpcError::invalid_params("Failed to decode transaction")
548 }
549 BlockchainError::FailedToDecodeTransaction => {
550 RpcError::invalid_params("Failed to decode transaction")
551 }
552 BlockchainError::FailedToDecodeReceipt => {
553 RpcError::invalid_params("Failed to decode receipt")
554 }
555 BlockchainError::UnsupportedTransactionEncoding(_) => {
556 RpcError::internal_error_with(err.to_string())
557 }
558 BlockchainError::FailedToDecodeStateDump => {
559 RpcError::invalid_params("Failed to decode state dump")
560 }
561 BlockchainError::SignerError(err) => RpcError::invalid_params(err.to_string()),
562 BlockchainError::SignatureError(err) => RpcError::invalid_params(err.to_string()),
563 BlockchainError::RpcUnimplemented => {
564 RpcError::internal_error_with("Not implemented")
565 }
566 BlockchainError::PrevrandaoNotSet => RpcError::internal_error_with(err.to_string()),
567 BlockchainError::RpcError(err) => err,
568 BlockchainError::InvalidFeeInput => RpcError::invalid_params(
569 "Invalid input: `max_priority_fee_per_gas` greater than `max_fee_per_gas`",
570 ),
571 err @ BlockchainError::ConflictingFeeFields => {
572 RpcError::invalid_params(err.to_string())
573 }
574 BlockchainError::AlloyForkProvider(err) => {
575 error!(target: "backend", %err, "fork provider error");
576 match err {
577 TransportError::ErrorResp(err) => RpcError {
578 code: ErrorCode::from(err.code),
579 message: err.message,
580 data: err.data.and_then(|data| serde_json::to_value(data).ok()),
581 },
582 err => RpcError::internal_error_with(format!("Fork Error: {err:?}")),
583 }
584 }
585 err @ BlockchainError::EvmError(_) => RpcError {
586 code: ErrorCode::TransactionRejected,
589 message: err.to_string().into(),
590 data: None,
591 },
592 #[cfg(feature = "base")]
593 err @ BlockchainError::Eip8130TransactionRejected(_) => RpcError {
594 code: ErrorCode::TransactionRejected,
595 message: err.to_string().into(),
596 data: None,
597 },
598 err @ BlockchainError::EvmOverrideError(_) => {
599 RpcError::invalid_params(err.to_string())
600 }
601 err @ BlockchainError::InvalidUrl(_) => RpcError::invalid_params(err.to_string()),
602 err @ BlockchainError::UnsupportedForkNetwork { .. } => {
603 RpcError::invalid_params(err.to_string())
604 }
605 BlockchainError::Internal(err) => RpcError::internal_error_with(err),
606 err @ BlockchainError::BlockOutOfRange(_, _) => {
607 RpcError::invalid_params(err.to_string())
608 }
609 err @ BlockchainError::BlockNotFound => RpcError {
610 code: ErrorCode::ServerError(-32001),
612 message: err.to_string().into(),
613 data: None,
614 },
615 err @ BlockchainError::TransactionNotFound => RpcError {
616 code: ErrorCode::ServerError(-32001),
617 message: err.to_string().into(),
618 data: None,
619 },
620 err @ BlockchainError::DataUnavailable => {
621 RpcError::internal_error_with(err.to_string())
622 }
623 err @ BlockchainError::HistoricalStateUnavailable(_) => RpcError {
624 code: ErrorCode::ServerError(-32000),
625 message: err.to_string().into(),
626 data: None,
627 },
628 err @ BlockchainError::TrieError(_) => {
629 RpcError::internal_error_with(err.to_string())
630 }
631 BlockchainError::UintConversion(err) => RpcError::invalid_params(err),
632 err @ BlockchainError::StateOverrideError(_) => {
633 RpcError::invalid_params(err.to_string())
634 }
635 err @ BlockchainError::TimestampError(_) => {
636 RpcError::invalid_params(err.to_string())
637 }
638 BlockchainError::DatabaseError(err) => {
639 RpcError::internal_error_with(err.to_string())
640 }
641 err @ BlockchainError::EIP1559TransactionUnsupportedAtHardfork => {
642 RpcError::invalid_params(err.to_string())
643 }
644 err @ BlockchainError::EIP2930TransactionUnsupportedAtHardfork => {
645 RpcError::invalid_params(err.to_string())
646 }
647 err @ BlockchainError::EIP4844TransactionUnsupportedAtHardfork => {
648 RpcError::invalid_params(err.to_string())
649 }
650 err @ BlockchainError::EIP7702TransactionUnsupportedAtHardfork => {
651 RpcError::invalid_params(err.to_string())
652 }
653 err @ BlockchainError::DepositTransactionUnsupported => {
654 RpcError::invalid_params(err.to_string())
655 }
656 #[cfg(feature = "base")]
657 err @ BlockchainError::BaseTransactionUnsupported => {
658 RpcError::invalid_params(err.to_string())
659 }
660 err @ BlockchainError::TempoTransactionUnsupported => {
661 RpcError::invalid_params(err.to_string())
662 }
663 err @ BlockchainError::ExcessBlobGasNotSet => {
664 RpcError::invalid_params(err.to_string())
665 }
666 err @ BlockchainError::Message(_) => RpcError::internal_error_with(err.to_string()),
667 err @ BlockchainError::UnknownTransactionType => {
668 RpcError::invalid_params(err.to_string())
669 }
670 err @ BlockchainError::InvalidTransactionRequest(_) => {
671 RpcError::invalid_params(err.to_string())
672 }
673 err @ BlockchainError::RecoveryError(_) => {
674 RpcError::invalid_params(err.to_string())
675 }
676 BlockchainError::FilterNotFound => RpcError {
677 code: ErrorCode::ServerError(-32000),
678 message: "filter not found".into(),
679 data: None,
680 },
681 err @ BlockchainError::UnknownBlock => RpcError {
682 code: ErrorCode::ServerError(-32000),
683 message: err.to_string().into(),
684 data: None,
685 },
686 }
687 .into(),
688 }
689 }
690}