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 self.as_invalid_tx_err()
11 .is_some_and(|err| matches!(err, InvalidTransaction::NonceTooLow { .. }))
12 }
13
14 fn is_gas_limit_too_high(&self) -> bool {
16 self.as_invalid_tx_err().is_some_and(|err| {
17 matches!(
18 err,
19 InvalidTransaction::TxGasLimitGreaterThanCap { .. }
20 | InvalidTransaction::CallerGasLimitMoreThanBlock
21 )
22 })
23 }
24
25 fn is_gas_limit_too_low(&self) -> bool {
27 self.as_invalid_tx_err().is_some_and(|err| {
28 matches!(
29 err,
30 InvalidTransaction::CallGasCostMoreThanGasLimit { .. }
31 | InvalidTransaction::GasFloorMoreThanGasLimit { .. }
32 )
33 })
34 }
35
36 fn as_invalid_tx_err(&self) -> Option<&InvalidTransaction>;
40}
41
42impl InvalidTxError for InvalidTransaction {
43 fn as_invalid_tx_err(&self) -> Option<&InvalidTransaction> {
44 Some(self)
45 }
46}
47
48pub trait EvmError: Sized + Error + Send + Sync + 'static {
57 type InvalidTransaction: InvalidTxError;
60
61 fn as_invalid_tx_err(&self) -> Option<&Self::InvalidTransaction>;
63
64 fn try_into_invalid_tx_err(self) -> Result<Self::InvalidTransaction, Self>;
66
67 fn is_invalid_tx_err(&self) -> bool {
69 self.as_invalid_tx_err().is_some()
70 }
71}
72
73impl<DBError, TxError> EvmError for EVMError<DBError, TxError>
74where
75 DBError: Error + Send + Sync + 'static,
76 TxError: InvalidTxError,
77{
78 type InvalidTransaction = TxError;
79
80 fn as_invalid_tx_err(&self) -> Option<&Self::InvalidTransaction> {
81 match self {
82 Self::Transaction(err) => Some(err),
83 _ => None,
84 }
85 }
86
87 fn try_into_invalid_tx_err(self) -> Result<Self::InvalidTransaction, Self> {
88 match self {
89 Self::Transaction(err) => Ok(err),
90 err => Err(err),
91 }
92 }
93}
94
95#[cfg(feature = "op")]
96impl InvalidTxError for op_revm::OpTransactionError {
97 fn as_invalid_tx_err(&self) -> Option<&InvalidTransaction> {
98 match self {
99 Self::Base(tx) => Some(tx),
100 _ => None,
101 }
102 }
103}