1use core::{any::Any, error::Error};
4use revm::context_interface::result::{EVMError, InvalidTransaction};
5
6pub trait InvalidTxError: Error + Send + Sync + Any + 'static {
8 fn is_nonce_too_low(&self) -> bool;
10
11 fn as_invalid_tx_err(&self) -> Option<&InvalidTransaction>;
15}
16
17impl InvalidTxError for InvalidTransaction {
18 fn is_nonce_too_low(&self) -> bool {
19 matches!(self, Self::NonceTooLow { .. })
20 }
21
22 fn as_invalid_tx_err(&self) -> Option<&InvalidTransaction> {
23 Some(self)
24 }
25}
26
27pub trait EvmError: Sized + Error + Send + Sync + 'static {
36 type InvalidTransaction: InvalidTxError;
39
40 fn as_invalid_tx_err(&self) -> Option<&Self::InvalidTransaction>;
42
43 fn try_into_invalid_tx_err(self) -> Result<Self::InvalidTransaction, Self>;
45
46 fn is_invalid_tx_err(&self) -> bool {
48 self.as_invalid_tx_err().is_some()
49 }
50}
51
52impl<DBError, TxError> EvmError for EVMError<DBError, TxError>
53where
54 DBError: Error + Send + Sync + 'static,
55 TxError: InvalidTxError,
56{
57 type InvalidTransaction = TxError;
58
59 fn as_invalid_tx_err(&self) -> Option<&Self::InvalidTransaction> {
60 match self {
61 Self::Transaction(err) => Some(err),
62 _ => None,
63 }
64 }
65
66 fn try_into_invalid_tx_err(self) -> Result<Self::InvalidTransaction, Self> {
67 match self {
68 Self::Transaction(err) => Ok(err),
69 err => Err(err),
70 }
71 }
72}
73
74#[cfg(feature = "op")]
75impl InvalidTxError for op_revm::OpTransactionError {
76 fn is_nonce_too_low(&self) -> bool {
77 matches!(self, Self::Base(tx) if tx.is_nonce_too_low())
78 }
79
80 fn as_invalid_tx_err(&self) -> Option<&InvalidTransaction> {
81 match self {
82 Self::Base(tx) => Some(tx),
83 _ => None,
84 }
85 }
86}