11use alloy_consensus:: { Transaction , Typed2718 , constants:: KECCAK_EMPTY , transaction:: Recovered } ;
22use alloy_primitives:: { Address , B256 , U256 } ;
33use alloy_provider:: { Provider , RootProvider } ;
4- use anyhow:: Result ;
54use async_trait:: async_trait;
6- use jsonrpsee:: { core:: RpcResult , types :: ErrorObject } ;
5+ use jsonrpsee:: core:: RpcResult ;
76use op_alloy_consensus:: interop:: CROSS_L2_INBOX_ADDRESS ;
87use op_alloy_network:: Optimism ;
98use op_revm:: { OpSpecId , l1block:: L1BlockInfo } ;
9+ use reth_errors:: RethError ;
1010use reth_optimism_evm:: extract_l1_info_from_tx;
11- use reth_rpc_eth_types:: { EthApiError , RpcInvalidTransactionError } ;
11+ use reth_rpc_eth_types:: { EthApiError , RpcInvalidTransactionError , SignError } ;
1212use tracing:: warn;
1313
1414/// Account info for a given address
@@ -21,14 +21,17 @@ pub struct AccountInfo {
2121/// Interface for fetching account info for a given address
2222#[ async_trait]
2323pub trait AccountInfoLookup : Send + Sync {
24- async fn fetch_account_info ( & self , address : Address ) -> Result < AccountInfo > ;
24+ async fn fetch_account_info ( & self , address : Address ) -> RpcResult < AccountInfo > ;
2525}
2626
2727/// Implementation of the `AccountInfoLookup` trait for the `RootProvider`
2828#[ async_trait]
2929impl AccountInfoLookup for RootProvider < Optimism > {
30- async fn fetch_account_info ( & self , address : Address ) -> Result < AccountInfo > {
31- let account = self . get_account ( address) . await ?;
30+ async fn fetch_account_info ( & self , address : Address ) -> RpcResult < AccountInfo > {
31+ let account = self
32+ . get_account ( address)
33+ . await
34+ . map_err ( |_| EthApiError :: Signing ( SignError :: NoAccount ) ) ?;
3235 Ok ( AccountInfo {
3336 balance : account. balance ,
3437 nonce : account. nonce ,
@@ -40,33 +43,34 @@ impl AccountInfoLookup for RootProvider<Optimism> {
4043/// Interface for fetching L1 block info for a given block number
4144#[ async_trait]
4245pub trait L1BlockInfoLookup : Send + Sync {
43- async fn fetch_l1_block_info ( & self ) -> Result < L1BlockInfo > ;
46+ async fn fetch_l1_block_info ( & self ) -> RpcResult < L1BlockInfo > ;
4447}
4548
4649/// Implementation of the `L1BlockInfoLookup` trait for the `RootProvider`
4750#[ async_trait]
4851impl L1BlockInfoLookup for RootProvider < Optimism > {
49- async fn fetch_l1_block_info ( & self ) -> Result < L1BlockInfo > {
52+ async fn fetch_l1_block_info ( & self ) -> RpcResult < L1BlockInfo > {
5053 let block_number = self
5154 . get_block_number ( )
5255 . await
53- . map_err ( |e| ErrorObject :: owned ( 11 , e . to_string ( ) , Some ( 2 ) ) ) ?;
56+ . map_err ( |_| EthApiError :: InternalEthError . into_rpc_err ( ) ) ?;
5457 let block = self
5558 . get_block_by_number ( block_number. into ( ) )
5659 . full ( )
5760 . await
58- . map_err ( |e| ErrorObject :: owned ( 11 , e . to_string ( ) , Some ( 2 ) ) ) ?;
61+ . map_err ( |_| EthApiError :: HeaderNotFound ( block_number . into ( ) ) . into_rpc_err ( ) ) ?;
5962
6063 if let Some ( block) = block {
6164 let txs = block. transactions . clone ( ) ;
6265 let first_tx = txs. first_transaction ( ) ;
6366 if let Some ( first_tx) = first_tx {
64- let l1_block_info = extract_l1_info_from_tx ( & first_tx. clone ( ) ) ?;
67+ let l1_block_info = extract_l1_info_from_tx ( & first_tx. clone ( ) )
68+ . map_err ( |e| EthApiError :: Internal ( RethError :: msg ( e. to_string ( ) ) ) ) ?;
6569 return Ok ( l1_block_info) ;
6670 }
6771 }
68- warn ! ( "Failed to fetch L1 block info" ) ;
69- Err ( anyhow :: anyhow! ( "Failed to fetch L1 block info" ) )
72+ warn ! ( message = "Failed to fetch L1 block info" ) ;
73+ Err ( EthApiError :: InternalEthError . into_rpc_err ( ) )
7074 }
7175}
7276
@@ -85,8 +89,8 @@ pub async fn validate_tx<T: Transaction>(
8589) -> RpcResult < ( ) > {
8690 // skip eip4844 transactions
8791 if txn. is_eip4844 ( ) {
88- let obj = ErrorObject :: owned ( 11 , "EIP-4844 transactions are not supported" , Some ( 2 ) ) ;
89- return Err ( RpcInvalidTransactionError :: other ( obj ) . into_rpc_err ( ) ) ;
92+ warn ! ( message = "EIP-4844 transactions are not supported" ) ;
93+ return Err ( RpcInvalidTransactionError :: TxTypeNotSupported . into_rpc_err ( ) ) ;
9094 }
9195
9296 // from: https://github.com/paradigmxyz/reth/blob/3b0d98f3464b504d96154b787a860b2488a61b3e/crates/optimism/txpool/src/supervisor/client.rs#L76-L84
@@ -97,8 +101,8 @@ pub async fn validate_tx<T: Transaction>(
97101 . iter ( )
98102 . filter ( |entry| entry. address == CROSS_L2_INBOX_ADDRESS ) ;
99103 if inbox_entries. count ( ) > 0 {
100- let obj = ErrorObject :: owned ( 11 , "Interop transactions are not supported" , Some ( 2 ) ) ;
101- return Err ( RpcInvalidTransactionError :: other ( obj ) . into_rpc_err ( ) ) ;
104+ warn ! ( message = "Interop transactions are not supported" ) ;
105+ return Err ( RpcInvalidTransactionError :: TxTypeNotSupported . into_rpc_err ( ) ) ;
102106 }
103107 }
104108
@@ -110,7 +114,7 @@ pub async fn validate_tx<T: Transaction>(
110114 . into_rpc_err ( ) ) ;
111115 }
112116
113- // error if tx nonce is not the latest
117+ // error if tx nonce is not equal to or greater than the latest on chain
114118 // https://github.com/paradigmxyz/reth/blob/a047a055ab996f85a399f5cfb2fe15e350356546/crates/transaction-pool/src/validate/eth.rs#L611
115119 if txn. nonce ( ) < account. nonce {
116120 return Err (
@@ -131,6 +135,7 @@ pub async fn validate_tx<T: Transaction>(
131135
132136 // error if execution cost costs more than balance
133137 if txn_cost > account. balance {
138+ warn ! ( message = "Insufficient funds for transfer" ) ;
134139 return Err ( EthApiError :: InvalidTransaction (
135140 RpcInvalidTransactionError :: InsufficientFundsForTransfer ,
136141 )
@@ -142,10 +147,11 @@ pub async fn validate_tx<T: Transaction>(
142147 let l1_cost_addition = l1_block_info. calculate_tx_l1_cost ( data, OpSpecId :: ISTHMUS ) ;
143148 let l1_cost = txn_cost. saturating_add ( l1_cost_addition) ;
144149 if l1_cost > account. balance {
145- let obj = ErrorObject :: owned ( 11 , "Insufficient funds for L1 gas" , Some ( 2 ) ) ;
146- return Err (
147- EthApiError :: InvalidTransaction ( RpcInvalidTransactionError :: other ( obj) ) . into_rpc_err ( ) ,
148- ) ;
150+ warn ! ( message = "Insufficient funds for L1 gas" ) ;
151+ return Err ( EthApiError :: InvalidTransaction (
152+ RpcInvalidTransactionError :: InsufficientFundsForTransfer ,
153+ )
154+ . into_rpc_err ( ) ) ;
149155 }
150156 Ok ( ( ) )
151157}
@@ -271,10 +277,9 @@ mod tests {
271277 let envelope = OpTxEnvelope :: Eip1559 ( tx. into_signed ( signature) ) ;
272278 let recovered_tx = envelope. try_into_recovered ( ) . unwrap ( ) ;
273279
274- let obj = ErrorObject :: owned ( 11 , "Interop transactions are not supported" , Some ( 2 ) ) ;
275280 assert_eq ! (
276281 validate_tx( account, & recovered_tx, & data, & mut l1_block_info) . await ,
277- Err ( RpcInvalidTransactionError :: other ( obj ) . into_rpc_err( ) )
282+ Err ( RpcInvalidTransactionError :: TxTypeNotSupported . into_rpc_err( ) )
278283 ) ;
279284 }
280285
@@ -304,10 +309,9 @@ mod tests {
304309 . into_signed ( signature)
305310 . try_into_recovered ( )
306311 . expect ( "failed to recover tx" ) ;
307- let obj = ErrorObject :: owned ( 11 , "EIP-4844 transactions are not supported" , Some ( 2 ) ) ;
308312 assert_eq ! (
309313 validate_tx( account, & recovered_tx, & data, & mut l1_block_info) . await ,
310- Err ( RpcInvalidTransactionError :: other ( obj ) . into_rpc_err( ) )
314+ Err ( RpcInvalidTransactionError :: TxTypeNotSupported . into_rpc_err( ) )
311315 ) ;
312316 }
313317
@@ -438,13 +442,12 @@ mod tests {
438442 let envelope = OpTxEnvelope :: Eip1559 ( tx. into_signed ( signature) ) ;
439443 let recovered_tx = envelope. try_into_recovered ( ) . unwrap ( ) ;
440444
441- let obj = ErrorObject :: owned ( 11 , "Insufficient funds for L1 gas" , Some ( 2 ) ) ;
442445 assert_eq ! (
443446 validate_tx( account, & recovered_tx, & data, & mut l1_block_info) . await ,
444- Err (
445- EthApiError :: InvalidTransaction ( RpcInvalidTransactionError :: other( obj) , )
446- . into_rpc_err( )
447+ Err ( EthApiError :: InvalidTransaction (
448+ RpcInvalidTransactionError :: InsufficientFundsForTransfer
447449 )
450+ . into_rpc_err( ) )
448451 ) ;
449452 }
450453}
0 commit comments