From bad7a4f0c90aebdc76a45e8fca8d2719b50d1ae1 Mon Sep 17 00:00:00 2001 From: Darshan Kathiriya <8559992+lakshya-sky@users.noreply.github.com> Date: Tue, 12 Nov 2024 05:31:32 -0500 Subject: [PATCH] use result for `TransactionCompact::fill`. (#12170) Co-authored-by: Emilia Hane Co-authored-by: dkathiriya --- Cargo.lock | 1 + crates/optimism/rpc/src/error.rs | 8 ++++- crates/optimism/rpc/src/eth/transaction.rs | 12 +++---- crates/rpc/rpc-eth-api/src/core.rs | 3 +- crates/rpc/rpc-eth-api/src/helpers/block.rs | 3 +- crates/rpc/rpc-eth-api/src/helpers/mod.rs | 1 - .../rpc-eth-api/src/helpers/transaction.rs | 6 ++-- crates/rpc/rpc-eth-api/src/lib.rs | 4 ++- crates/rpc/rpc-eth-api/src/types.rs | 15 ++++++-- .../src/error/api.rs} | 9 ++--- .../src/{error.rs => error/mod.rs} | 5 ++- crates/rpc/rpc-eth-types/src/simulate.rs | 11 +++--- crates/rpc/rpc-eth-types/src/transaction.rs | 5 ++- crates/rpc/rpc-types-compat/Cargo.toml | 1 + crates/rpc/rpc-types-compat/src/block.rs | 11 +++--- .../rpc/rpc-types-compat/src/transaction.rs | 14 ++++++-- crates/rpc/rpc/src/eth/filter.rs | 15 +++++--- crates/rpc/rpc/src/eth/helpers/types.rs | 9 +++-- crates/rpc/rpc/src/eth/pubsub.rs | 19 +++++++++-- crates/rpc/rpc/src/txpool.rs | 34 +++++++++++-------- 20 files changed, 124 insertions(+), 62 deletions(-) rename crates/rpc/{rpc-eth-api/src/helpers/error.rs => rpc-eth-types/src/error/api.rs} (87%) rename crates/rpc/rpc-eth-types/src/{error.rs => error/mod.rs} (99%) diff --git a/Cargo.lock b/Cargo.lock index 1bf11ac9ba..38a87ebf93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8958,6 +8958,7 @@ dependencies = [ "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-serde", + "jsonrpsee-types", "reth-primitives", "reth-trie-common", "serde", diff --git a/crates/optimism/rpc/src/error.rs b/crates/optimism/rpc/src/error.rs index ffc698b6e9..1dd7a639ea 100644 --- a/crates/optimism/rpc/src/error.rs +++ b/crates/optimism/rpc/src/error.rs @@ -1,6 +1,6 @@ //! RPC errors specific to OP. -use alloy_rpc_types_eth::error::EthRpcErrorCode; +use alloy_rpc_types_eth::{error::EthRpcErrorCode, BlockError}; use jsonrpsee_types::error::INTERNAL_ERROR_CODE; use reth_optimism_evm::OpBlockExecutionError; use reth_primitives::revm_primitives::{InvalidTransaction, OptimismInvalidTransaction}; @@ -113,3 +113,9 @@ impl From for jsonrpsee_types::error::ErrorObject<'static> ) } } + +impl From for OpEthApiError { + fn from(error: BlockError) -> Self { + Self::Eth(error.into()) + } +} diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 90e5e33feb..3ff7cb10df 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -15,7 +15,7 @@ use reth_rpc_eth_api::{ use reth_rpc_eth_types::utils::recover_raw_transaction; use reth_transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; -use crate::{OpEthApi, SequencerClient}; +use crate::{OpEthApi, OpEthApiError, SequencerClient}; impl EthTransactions for OpEthApi where @@ -76,12 +76,13 @@ where N: FullNodeComponents, { type Transaction = Transaction; + type Error = OpEthApiError; fn fill( &self, tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, - ) -> Self::Transaction { + ) -> Result { let from = tx.signer(); let TransactionSigned { transaction, signature, hash } = tx.into_signed(); @@ -106,8 +107,7 @@ where .inner .provider() .receipt_by_hash(hash) - .ok() // todo: change sig to return result - .flatten() + .map_err(Self::Error::from_eth_err)? .and_then(|receipt| receipt.deposit_receipt_version); let TransactionInfo { @@ -120,7 +120,7 @@ where }) .unwrap_or_else(|| inner.max_fee_per_gas()); - Transaction { + Ok(Transaction { inner: alloy_rpc_types_eth::Transaction { inner, block_hash, @@ -130,7 +130,7 @@ where effective_gas_price: Some(effective_gas_price), }, deposit_receipt_version, - } + }) } fn otterscan_api_truncate_input(tx: &mut Self::Transaction) { diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index 421c10f8b4..8072021d99 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -501,7 +501,8 @@ where trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash"); Ok(EthTransactions::transaction_by_hash(self, hash) .await? - .map(|tx| tx.into_transaction(self.tx_resp_builder()))) + .map(|tx| tx.into_transaction(self.tx_resp_builder())) + .transpose()?) } /// Handler for: `eth_getRawTransactionByBlockHashAndIndex` diff --git a/crates/rpc/rpc-eth-api/src/helpers/block.rs b/crates/rpc/rpc-eth-api/src/helpers/block.rs index e25ea84d69..7125857b89 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/block.rs @@ -64,8 +64,7 @@ pub trait EthBlocks: LoadBlock { full.into(), Some(block_hash), self.tx_resp_builder(), - ) - .map_err(Self::Error::from_eth_err)?; + )?; Ok(Some(block)) } } diff --git a/crates/rpc/rpc-eth-api/src/helpers/mod.rs b/crates/rpc/rpc-eth-api/src/helpers/mod.rs index 8adb0e281e..a881330b04 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/mod.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/mod.rs @@ -17,7 +17,6 @@ pub mod block; pub mod blocking_task; pub mod call; -pub mod error; pub mod fee; pub mod pending_block; pub mod receipt; diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 234008f21f..ca4b0322e7 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -208,7 +208,7 @@ pub trait EthTransactions: LoadTransaction { tx.clone().with_signer(*signer), tx_info, self.tx_resp_builder(), - ))) + )?)) } } @@ -233,7 +233,7 @@ pub trait EthTransactions: LoadTransaction { RpcNodeCore::pool(self).get_transaction_by_sender_and_nonce(sender, nonce) { let transaction = tx.transaction.clone().into_consensus(); - return Ok(Some(from_recovered(transaction.into(), self.tx_resp_builder()))); + return Ok(Some(from_recovered(transaction.into(), self.tx_resp_builder())?)); } } @@ -291,7 +291,7 @@ pub trait EthTransactions: LoadTransaction { ) }) }) - .ok_or(EthApiError::HeaderNotFound(block_id).into()) + .ok_or(EthApiError::HeaderNotFound(block_id))? .map(Some) } } diff --git a/crates/rpc/rpc-eth-api/src/lib.rs b/crates/rpc/rpc-eth-api/src/lib.rs index fa9737f84f..cb97a03e8b 100644 --- a/crates/rpc/rpc-eth-api/src/lib.rs +++ b/crates/rpc/rpc-eth-api/src/lib.rs @@ -20,12 +20,14 @@ pub mod node; pub mod pubsub; pub mod types; +pub use reth_rpc_eth_types::error::{ + AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError, +}; pub use reth_rpc_types_compat::TransactionCompat; pub use bundle::{EthBundleApiServer, EthCallBundleApiServer}; pub use core::{EthApiServer, FullEthApiServer}; pub use filter::EthFilterApiServer; -pub use helpers::error::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError}; pub use node::{RpcNodeCore, RpcNodeCoreExt}; pub use pubsub::EthPubSubApiServer; pub use types::{EthApiTypes, FullEthApiTypes, RpcBlock, RpcReceipt, RpcTransaction}; diff --git a/crates/rpc/rpc-eth-api/src/types.rs b/crates/rpc/rpc-eth-api/src/types.rs index b75bce026f..12ff090d37 100644 --- a/crates/rpc/rpc-eth-api/src/types.rs +++ b/crates/rpc/rpc-eth-api/src/types.rs @@ -39,15 +39,26 @@ pub type RpcBlock = Block, ::HeaderResponse>; /// Adapter for network specific receipt type. pub type RpcReceipt = ::ReceiptResponse; +/// Adapter for network specific error type. +pub type RpcError = ::Error; + /// Helper trait holds necessary trait bounds on [`EthApiTypes`] to implement `eth` API. pub trait FullEthApiTypes: - EthApiTypes>> + EthApiTypes< + TransactionCompat: TransactionCompat< + Transaction = RpcTransaction, + Error = RpcError, + >, +> { } impl FullEthApiTypes for T where T: EthApiTypes< - TransactionCompat: TransactionCompat>, + TransactionCompat: TransactionCompat< + Transaction = RpcTransaction, + Error = RpcError, + >, > { } diff --git a/crates/rpc/rpc-eth-api/src/helpers/error.rs b/crates/rpc/rpc-eth-types/src/error/api.rs similarity index 87% rename from crates/rpc/rpc-eth-api/src/helpers/error.rs rename to crates/rpc/rpc-eth-types/src/error/api.rs index 1d991b8e65..419f530c4e 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/error.rs +++ b/crates/rpc/rpc-eth-types/src/error/api.rs @@ -1,9 +1,10 @@ //! Helper traits to wrap generic l1 errors, in network specific error type configured in -//! [`EthApiTypes`](crate::EthApiTypes). +//! `reth_rpc_eth_api::EthApiTypes`. -use reth_rpc_eth_types::EthApiError; use revm_primitives::EVMError; +use crate::EthApiError; + /// Helper trait to wrap core [`EthApiError`]. pub trait FromEthApiError: From { /// Converts from error via [`EthApiError`]. @@ -51,7 +52,7 @@ pub trait AsEthApiError { fn as_err(&self) -> Option<&EthApiError>; /// Returns `true` if error is - /// [`RpcInvalidTransactionError::GasTooHigh`](reth_rpc_eth_types::RpcInvalidTransactionError::GasTooHigh). + /// [`RpcInvalidTransactionError::GasTooHigh`](crate::RpcInvalidTransactionError::GasTooHigh). fn is_gas_too_high(&self) -> bool { if let Some(err) = self.as_err() { return err.is_gas_too_high() @@ -61,7 +62,7 @@ pub trait AsEthApiError { } /// Returns `true` if error is - /// [`RpcInvalidTransactionError::GasTooLow`](reth_rpc_eth_types::RpcInvalidTransactionError::GasTooLow). + /// [`RpcInvalidTransactionError::GasTooLow`](crate::RpcInvalidTransactionError::GasTooLow). fn is_gas_too_low(&self) -> bool { if let Some(err) = self.as_err() { return err.is_gas_too_low() diff --git a/crates/rpc/rpc-eth-types/src/error.rs b/crates/rpc/rpc-eth-types/src/error/mod.rs similarity index 99% rename from crates/rpc/rpc-eth-types/src/error.rs rename to crates/rpc/rpc-eth-types/src/error/mod.rs index 641cbc8829..99c41daea3 100644 --- a/crates/rpc/rpc-eth-types/src/error.rs +++ b/crates/rpc/rpc-eth-types/src/error/mod.rs @@ -1,6 +1,9 @@ //! Implementation specific Errors for the `eth_` namespace. -use std::time::Duration; +pub mod api; +pub use api::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError}; + +use core::time::Duration; use alloy_eips::BlockId; use alloy_primitives::{Address, Bytes, U256}; diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index b2a9a5e62e..91aaa25430 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -21,8 +21,9 @@ use revm::{db::CacheDB, Database}; use revm_primitives::{keccak256, Address, BlockEnv, Bytes, ExecutionResult, TxKind, B256, U256}; use crate::{ - cache::db::StateProviderTraitObjWrapper, error::ToRpcError, EthApiError, RevertError, - RpcInvalidTransactionError, + cache::db::StateProviderTraitObjWrapper, + error::{api::FromEthApiError, ToRpcError}, + EthApiError, RevertError, RpcInvalidTransactionError, }; /// Errors which may occur during `eth_simulateV1` execution. @@ -170,7 +171,7 @@ where /// Handles outputs of the calls execution and builds a [`SimulatedBlock`]. #[expect(clippy::complexity)] -pub fn build_block( +pub fn build_block>( results: Vec<(Address, ExecutionResult)>, transactions: Vec, block_env: &BlockEnv, @@ -179,7 +180,7 @@ pub fn build_block( full_transactions: bool, db: &CacheDB>>, tx_resp_builder: &T, -) -> Result>, EthApiError> { +) -> Result>, T::Error> { let mut calls: Vec = Vec::with_capacity(results.len()); let mut senders = Vec::with_capacity(results.len()); let mut receipts = Vec::with_capacity(results.len()); @@ -272,7 +273,7 @@ pub fn build_block( } } - let state_root = db.db.state_root(hashed_state)?; + let state_root = db.db.state_root(hashed_state).map_err(T::Error::from_eth_err)?; let header = reth_primitives::Header { beneficiary: block_env.coinbase, diff --git a/crates/rpc/rpc-eth-types/src/transaction.rs b/crates/rpc/rpc-eth-types/src/transaction.rs index bfff1cafea..a4ede0a1a4 100644 --- a/crates/rpc/rpc-eth-types/src/transaction.rs +++ b/crates/rpc/rpc-eth-types/src/transaction.rs @@ -41,7 +41,10 @@ impl TransactionSource { } /// Conversion into network specific transaction type. - pub fn into_transaction(self, resp_builder: &T) -> T::Transaction { + pub fn into_transaction( + self, + resp_builder: &T, + ) -> Result { match self { Self::Pool(tx) => from_recovered(tx, resp_builder), Self::Block { transaction, index, block_hash, block_number, base_fee } => { diff --git a/crates/rpc/rpc-types-compat/Cargo.toml b/crates/rpc/rpc-types-compat/Cargo.toml index 2e45d210d1..887986ada1 100644 --- a/crates/rpc/rpc-types-compat/Cargo.toml +++ b/crates/rpc/rpc-types-compat/Cargo.toml @@ -27,6 +27,7 @@ alloy-consensus.workspace = true # io serde.workspace = true +jsonrpsee-types.workspace = true [dev-dependencies] serde_json.workspace = true diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index 41bd057dfd..43086b311b 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -1,15 +1,16 @@ //! Compatibility functions for rpc `Block` type. -use crate::{transaction::from_recovered_with_block_context, TransactionCompat}; use alloy_consensus::Sealed; use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{B256, U256}; use alloy_rlp::Encodable; use alloy_rpc_types_eth::{ - Block, BlockError, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo, + Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo, }; use reth_primitives::{Block as PrimitiveBlock, BlockWithSenders}; +use crate::{transaction::from_recovered_with_block_context, TransactionCompat}; + /// Converts the given primitive block into a [`Block`] response with the given /// [`BlockTransactionsKind`] /// @@ -20,7 +21,7 @@ pub fn from_block( kind: BlockTransactionsKind, block_hash: Option, tx_resp_builder: &T, -) -> Result, BlockError> { +) -> Result, T::Error> { match kind { BlockTransactionsKind::Hashes => { Ok(from_block_with_tx_hashes::(block, total_difficulty, block_hash)) @@ -63,7 +64,7 @@ pub fn from_block_full( total_difficulty: U256, block_hash: Option, tx_resp_builder: &T, -) -> Result, BlockError> { +) -> Result, T::Error> { let block_hash = block_hash.unwrap_or_else(|| block.block.header.hash_slow()); let block_number = block.block.number; let base_fee_per_gas = block.block.base_fee_per_gas; @@ -88,7 +89,7 @@ pub fn from_block_full( from_recovered_with_block_context::(signed_tx_ec_recovered, tx_info, tx_resp_builder) }) - .collect::>(); + .collect::, T::Error>>()?; Ok(from_block_with_transactions( block_length, diff --git a/crates/rpc/rpc-types-compat/src/transaction.rs b/crates/rpc/rpc-types-compat/src/transaction.rs index cfbaaa622f..9e8fae6709 100644 --- a/crates/rpc/rpc-types-compat/src/transaction.rs +++ b/crates/rpc/rpc-types-compat/src/transaction.rs @@ -1,5 +1,6 @@ //! Compatibility functions for rpc `Transaction` type. +use core::error; use std::fmt; use alloy_consensus::Transaction as _; @@ -19,7 +20,7 @@ pub fn from_recovered_with_block_context( tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, resp_builder: &T, -) -> T::Transaction { +) -> Result { resp_builder.fill(tx, tx_info) } @@ -28,7 +29,7 @@ pub fn from_recovered_with_block_context( pub fn from_recovered( tx: TransactionSignedEcRecovered, resp_builder: &T, -) -> T::Transaction { +) -> Result { resp_builder.fill(tx, TransactionInfo::default()) } @@ -43,9 +44,16 @@ pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug { + Clone + fmt::Debug; + /// RPC transaction error type. + type Error: error::Error + Into>; + /// Create a new rpc transaction result for a _pending_ signed transaction, setting block /// environment related fields to `None`. - fn fill(&self, tx: TransactionSignedEcRecovered, tx_inf: TransactionInfo) -> Self::Transaction; + fn fill( + &self, + tx: TransactionSignedEcRecovered, + tx_inf: TransactionInfo, + ) -> Result; /// Truncates the input of a transaction to only the first 4 bytes. // todo: remove in favour of using constructor on `TransactionResponse` or similar diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 589cb801e2..3782780f5a 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -34,7 +34,7 @@ use tokio::{ sync::{mpsc::Receiver, Mutex}, time::MissedTickBehavior, }; -use tracing::trace; +use tracing::{error, trace}; /// The maximum number of headers we read at once when handling a range filter. const MAX_HEADERS_RANGE: u64 = 1_000; // with ~530bytes per header this is ~500kb @@ -625,10 +625,15 @@ where let mut prepared_stream = self.txs_stream.lock().await; while let Ok(tx) = prepared_stream.try_recv() { - pending_txs.push(from_recovered( - tx.transaction.to_recovered_transaction(), - &self.tx_resp_builder, - )) + match from_recovered(tx.transaction.to_recovered_transaction(), &self.tx_resp_builder) { + Ok(tx) => pending_txs.push(tx), + Err(err) => { + error!(target: "rpc", + %err, + "Failed to fill txn with block context" + ); + } + } } FilterChanges::Transactions(pending_txs) } diff --git a/crates/rpc/rpc/src/eth/helpers/types.rs b/crates/rpc/rpc/src/eth/helpers/types.rs index 19ffc55b39..d1ce84bc0b 100644 --- a/crates/rpc/rpc/src/eth/helpers/types.rs +++ b/crates/rpc/rpc/src/eth/helpers/types.rs @@ -4,6 +4,7 @@ use alloy_consensus::{Signed, Transaction as _, TxEip4844Variant, TxEnvelope}; use alloy_network::{Ethereum, Network}; use alloy_rpc_types_eth::{Transaction, TransactionInfo}; use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; +use reth_rpc_eth_types::EthApiError; use reth_rpc_types_compat::TransactionCompat; /// Builds RPC transaction response for l1. @@ -16,11 +17,13 @@ where { type Transaction = ::TransactionResponse; + type Error = EthApiError; + fn fill( &self, tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, - ) -> Self::Transaction { + ) -> Result { let from = tx.signer(); let TransactionSigned { transaction, signature, hash } = tx.into_signed(); @@ -54,14 +57,14 @@ where }) .unwrap_or_else(|| inner.max_fee_per_gas()); - Transaction { + Ok(Transaction { inner, block_hash, block_number, transaction_index, from, effective_gas_price: Some(effective_gas_price), - } + }) } fn otterscan_api_truncate_input(tx: &mut Self::Transaction) { diff --git a/crates/rpc/rpc/src/eth/pubsub.rs b/crates/rpc/rpc/src/eth/pubsub.rs index 0702e3147c..8ea6d1f87c 100644 --- a/crates/rpc/rpc/src/eth/pubsub.rs +++ b/crates/rpc/rpc/src/eth/pubsub.rs @@ -27,6 +27,7 @@ use tokio_stream::{ wrappers::{BroadcastStream, ReceiverStream}, Stream, }; +use tracing::error; /// `Eth` pubsub RPC implementation. /// @@ -146,11 +147,23 @@ where match params { Params::Bool(true) => { // full transaction objects requested - let stream = pubsub.full_pending_transaction_stream().map(|tx| { - EthSubscriptionResult::FullTransaction(Box::new(from_recovered( + let stream = pubsub.full_pending_transaction_stream().filter_map(|tx| { + let tx_value = match from_recovered( tx.transaction.to_recovered_transaction(), &tx_resp_builder, - ))) + ) { + Ok(tx) => { + Some(EthSubscriptionResult::FullTransaction(Box::new(tx))) + } + Err(err) => { + error!(target = "rpc", + %err, + "Failed to fill transaction with block context" + ); + None + } + }; + std::future::ready(tx_value) }); return pipe_from_stream(accepted_sink, stream).await } diff --git a/crates/rpc/rpc/src/txpool.rs b/crates/rpc/rpc/src/txpool.rs index d03e10ca75..3e46183b46 100644 --- a/crates/rpc/rpc/src/txpool.rs +++ b/crates/rpc/rpc/src/txpool.rs @@ -1,3 +1,4 @@ +use core::fmt; use std::collections::BTreeMap; use alloy_consensus::Transaction; @@ -6,7 +7,7 @@ use alloy_rpc_types_txpool::{ TxpoolContent, TxpoolContentFrom, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus, }; use async_trait::async_trait; -use jsonrpsee::core::RpcResult as Result; +use jsonrpsee::core::RpcResult; use reth_primitives::TransactionSignedEcRecovered; use reth_rpc_api::TxPoolApiServer; use reth_rpc_types_compat::{transaction::from_recovered, TransactionCompat}; @@ -35,33 +36,36 @@ where Pool: TransactionPool + 'static, Eth: TransactionCompat, { - fn content(&self) -> TxpoolContent { + fn content(&self) -> Result, Eth::Error> { #[inline] fn insert( tx: &Tx, content: &mut BTreeMap>, resp_builder: &RpcTxB, - ) where + ) -> Result<(), RpcTxB::Error> + where Tx: PoolTransaction>, RpcTxB: TransactionCompat, { content.entry(tx.sender()).or_default().insert( tx.nonce().to_string(), - from_recovered(tx.clone().into_consensus().into(), resp_builder), + from_recovered(tx.clone().into_consensus().into(), resp_builder)?, ); + + Ok(()) } let AllPoolTransactions { pending, queued } = self.pool.all_transactions(); let mut content = TxpoolContent { pending: BTreeMap::new(), queued: BTreeMap::new() }; for pending in pending { - insert::<_, Eth>(&pending.transaction, &mut content.pending, &self.tx_resp_builder); + insert::<_, Eth>(&pending.transaction, &mut content.pending, &self.tx_resp_builder)?; } for queued in queued { - insert::<_, Eth>(&queued.transaction, &mut content.queued, &self.tx_resp_builder); + insert::<_, Eth>(&queued.transaction, &mut content.queued, &self.tx_resp_builder)?; } - content + Ok(content) } } @@ -76,7 +80,7 @@ where /// Ref: [Here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status) /// /// Handler for `txpool_status` - async fn txpool_status(&self) -> Result { + async fn txpool_status(&self) -> RpcResult { trace!(target: "rpc::eth", "Serving txpool_status"); let all = self.pool.all_transactions(); Ok(TxpoolStatus { pending: all.pending.len() as u64, queued: all.queued.len() as u64 }) @@ -88,7 +92,7 @@ where /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect) for more details /// /// Handler for `txpool_inspect` - async fn txpool_inspect(&self) -> Result { + async fn txpool_inspect(&self) -> RpcResult { trace!(target: "rpc::eth", "Serving txpool_inspect"); #[inline] @@ -131,9 +135,9 @@ where async fn txpool_content_from( &self, from: Address, - ) -> Result> { + ) -> RpcResult> { trace!(target: "rpc::eth", ?from, "Serving txpool_contentFrom"); - Ok(self.content().remove_from(&from)) + Ok(self.content().map_err(Into::into)?.remove_from(&from)) } /// Returns the details of all transactions currently pending for inclusion in the next @@ -141,14 +145,14 @@ where /// /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content) for more details /// Handler for `txpool_content` - async fn txpool_content(&self) -> Result> { + async fn txpool_content(&self) -> RpcResult> { trace!(target: "rpc::eth", "Serving txpool_content"); - Ok(self.content()) + Ok(self.content().map_err(Into::into)?) } } -impl std::fmt::Debug for TxPoolApi { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Debug for TxPoolApi { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TxpoolApi").finish_non_exhaustive() } }