diff --git a/Cargo.lock b/Cargo.lock index 59c582fec3f2..c88834a27124 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8899,6 +8899,7 @@ dependencies = [ "alloy-serde", "reth-primitives", "reth-trie-common", + "serde", "serde_json", ] diff --git a/crates/optimism/rpc/Cargo.toml b/crates/optimism/rpc/Cargo.toml index dc0f96c4012d..17ebec7ff741 100644 --- a/crates/optimism/rpc/Cargo.toml +++ b/crates/optimism/rpc/Cargo.toml @@ -56,7 +56,7 @@ serde_json.workspace = true # misc thiserror.workspace = true tracing.workspace = true -derive_more.workspace = true +derive_more = { workspace = true, features = ["constructor", "deref"] } [dev-dependencies] reth-optimism-chainspec.workspace = true diff --git a/crates/optimism/rpc/src/eth/mod.rs b/crates/optimism/rpc/src/eth/mod.rs index d65dd8edd1d5..04774a4651c0 100644 --- a/crates/optimism/rpc/src/eth/mod.rs +++ b/crates/optimism/rpc/src/eth/mod.rs @@ -39,7 +39,7 @@ use reth_tasks::{ }; use reth_transaction_pool::TransactionPool; -use crate::{OpEthApiError, OpTxBuilder, SequencerClient}; +use crate::{OpEthApiError, SequencerClient}; /// Adapter for [`EthApiInner`], which holds all the data required to serve core `eth_` API. pub type EthApiNodeBackend = EthApiInner< @@ -59,7 +59,7 @@ pub type EthApiNodeBackend = EthApiInner< /// /// This type implements the [`FullEthApi`](reth_rpc_eth_api::helpers::FullEthApi) by implemented /// all the `Eth` helper traits and prerequisite traits. -#[derive(Clone, Deref)] +#[derive(Deref)] pub struct OpEthApi { /// Gateway to node's core components. #[deref] @@ -102,7 +102,11 @@ where { type Error = OpEthApiError; type NetworkTypes = Optimism; - type TransactionCompat = OpTxBuilder; + type TransactionCompat = Self; + + fn tx_resp_builder(&self) -> &Self::TransactionCompat { + self + } } impl EthApiSpec for OpEthApi @@ -249,3 +253,12 @@ impl fmt::Debug for OpEthApi { f.debug_struct("OpEthApi").finish_non_exhaustive() } } + +impl Clone for OpEthApi +where + N: FullNodeComponents, +{ + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), sequencer_client: self.sequencer_client.clone() } + } +} diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index b7575c24416a..4ac2d7e6b74f 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -6,7 +6,7 @@ use alloy_rpc_types::TransactionInfo; use op_alloy_rpc_types::Transaction; use reth_node_api::FullNodeComponents; use reth_primitives::TransactionSignedEcRecovered; -use reth_provider::{BlockReaderIdExt, TransactionsProvider}; +use reth_provider::{BlockReaderIdExt, ReceiptProvider, TransactionsProvider}; use reth_rpc::eth::EthTxBuilder; use reth_rpc_eth_api::{ helpers::{EthSigner, EthTransactions, LoadTransaction, SpawnBlocking}, @@ -88,22 +88,34 @@ where } } -/// Builds OP transaction response type. -#[derive(Clone, Debug, Copy)] -pub struct OpTxBuilder; - -impl TransactionCompat for OpTxBuilder { +impl TransactionCompat for OpEthApi +where + N: FullNodeComponents, +{ type Transaction = Transaction; - fn fill(tx: TransactionSignedEcRecovered, tx_info: TransactionInfo) -> Self::Transaction { + fn fill( + &self, + tx: TransactionSignedEcRecovered, + tx_info: TransactionInfo, + ) -> Self::Transaction { let signed_tx = tx.clone().into_signed(); + let hash = tx.hash; - let mut inner = EthTxBuilder::fill(tx, tx_info).inner; + let mut inner = EthTxBuilder.fill(tx, tx_info).inner; if signed_tx.is_deposit() { inner.gas_price = Some(signed_tx.max_fee_per_gas()) } + let deposit_receipt_version = self + .inner + .provider() + .receipt_by_hash(hash) + .ok() // todo: change sig to return result + .flatten() + .and_then(|receipt| receipt.deposit_receipt_version); + Transaction { inner, source_hash: signed_tx.source_hash(), @@ -111,7 +123,7 @@ impl TransactionCompat for OpTxBuilder { // only include is_system_tx if true: is_system_tx: (signed_tx.is_deposit() && signed_tx.is_system_transaction()) .then_some(true), - deposit_receipt_version: None, // todo: how to fill this field? + deposit_receipt_version, } } diff --git a/crates/optimism/rpc/src/lib.rs b/crates/optimism/rpc/src/lib.rs index e3fef7adb5b7..0ff1451d05b7 100644 --- a/crates/optimism/rpc/src/lib.rs +++ b/crates/optimism/rpc/src/lib.rs @@ -15,5 +15,5 @@ pub mod eth; pub mod sequencer; pub use error::{OpEthApiError, OptimismInvalidTransactionError, SequencerClientError}; -pub use eth::{transaction::OpTxBuilder, OpEthApi, OpReceiptBuilder}; +pub use eth::{OpEthApi, OpReceiptBuilder}; pub use sequencer::SequencerClient; diff --git a/crates/rpc/rpc-builder/src/eth.rs b/crates/rpc/rpc-builder/src/eth.rs index 613652678a20..40acecfedf33 100644 --- a/crates/rpc/rpc-builder/src/eth.rs +++ b/crates/rpc/rpc-builder/src/eth.rs @@ -22,7 +22,7 @@ pub struct EthHandlers { /// Polling based filter handler available on all transports pub filter: EthFilter, /// Handler for subscriptions only available for transports that support it (ws, ipc) - pub pubsub: EthPubSub, + pub pubsub: EthPubSub, } impl EthHandlers @@ -94,6 +94,7 @@ where ctx.cache.clone(), ctx.config.filter_config(), Box::new(ctx.executor.clone()), + api.tx_resp_builder().clone(), ); let pubsub = EthPubSub::with_spawner( @@ -102,6 +103,7 @@ where ctx.events.clone(), ctx.network.clone(), Box::new(ctx.executor.clone()), + api.tx_resp_builder().clone(), ); Self { api, cache: ctx.cache, filter, pubsub } diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index cd93aeb620e3..72b53efe674c 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -1199,9 +1199,12 @@ where .into_rpc() .into(), RethRpcModule::Web3 => Web3Api::new(self.network.clone()).into_rpc().into(), - RethRpcModule::Txpool => { - TxPoolApi::<_, EthApi>::new(self.pool.clone()).into_rpc().into() - } + RethRpcModule::Txpool => TxPoolApi::new( + self.pool.clone(), + self.eth.api.tx_resp_builder().clone(), + ) + .into_rpc() + .into(), RethRpcModule::Rpc => RPCApi::new( namespaces .iter() diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index 20edf96d810d..66bc5a44d2db 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -502,7 +502,7 @@ where trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash"); Ok(EthTransactions::transaction_by_hash(self, hash) .await? - .map(|tx| tx.into_transaction::())) + .map(|tx| tx.into_transaction(self.tx_resp_builder()))) } /// 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 9bf35d850af6..da5f275ef0cf 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/block.rs @@ -63,11 +63,12 @@ pub trait EthBlocks: LoadBlock { .map_err(Self::Error::from_eth_err)?; } - let block = from_block::( + let block = from_block( (*block).clone().unseal(), total_difficulty.unwrap_or_default(), 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/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index 0acf6646294f..1510233c5059 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -191,7 +191,7 @@ pub trait EthCall: Call + LoadPendingBlock { results.push((env.tx.caller, res.result)); } - let block = simulate::build_block::( + let block = simulate::build_block( results, transactions, &block_env, @@ -199,6 +199,7 @@ pub trait EthCall: Call + LoadPendingBlock { total_difficulty, return_full_transactions, &db, + this.tx_resp_builder(), )?; parent_hash = block.inner.header.hash; diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index d29787d7a23b..0d16a5c9145b 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -209,9 +209,10 @@ pub trait EthTransactions: LoadTransaction { index: Some(index as u64), }; - return Ok(Some(from_recovered_with_block_context::( + return Ok(Some(from_recovered_with_block_context( tx.clone().with_signer(*signer), tx_info, + self.tx_resp_builder(), ))) } } @@ -237,7 +238,7 @@ pub trait EthTransactions: LoadTransaction { LoadState::pool(self).get_transaction_by_sender_and_nonce(sender, nonce) { let transaction = tx.transaction.clone().into_consensus(); - return Ok(Some(from_recovered::(transaction.into()))); + return Ok(Some(from_recovered(transaction.into(), self.tx_resp_builder()))); } } @@ -288,9 +289,10 @@ pub trait EthTransactions: LoadTransaction { base_fee: base_fee_per_gas.map(u128::from), index: Some(index as u64), }; - from_recovered_with_block_context::( + from_recovered_with_block_context( tx.clone().with_signer(*signer), tx_info, + self.tx_resp_builder(), ) }) }) diff --git a/crates/rpc/rpc-eth-api/src/types.rs b/crates/rpc/rpc-eth-api/src/types.rs index 9ddc23ea32e5..653730ed3c99 100644 --- a/crates/rpc/rpc-eth-api/src/types.rs +++ b/crates/rpc/rpc-eth-api/src/types.rs @@ -23,12 +23,19 @@ pub trait EthApiTypes: Send + Sync + Clone { type NetworkTypes: Network; /// Conversion methods for transaction RPC type. type TransactionCompat: Send + Sync + Clone + fmt::Debug; + + /// Returns reference to transaction response builder. + fn tx_resp_builder(&self) -> &Self::TransactionCompat; } impl EthApiTypes for () { type Error = EthApiError; type NetworkTypes = AnyNetwork; type TransactionCompat = (); + + fn tx_resp_builder(&self) -> &Self::TransactionCompat { + self + } } /// Adapter for network specific transaction type. diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index 77db511e6251..1d443861d4f6 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -172,6 +172,7 @@ where } /// Handles outputs of the calls execution and builds a [`SimulatedBlock`]. +#[expect(clippy::too_many_arguments)] pub fn build_block( results: Vec<(Address, ExecutionResult)>, transactions: Vec, @@ -180,6 +181,7 @@ pub fn build_block( total_difficulty: U256, full_transactions: bool, db: &CacheDB>>, + tx_resp_builder: &T, ) -> Result>, EthApiError> { let mut calls: Vec = Vec::with_capacity(results.len()); let mut senders = Vec::with_capacity(results.len()); @@ -304,6 +306,6 @@ pub fn build_block( let txs_kind = if full_transactions { BlockTransactionsKind::Full } else { BlockTransactionsKind::Hashes }; - let block = from_block::(block, total_difficulty, txs_kind, None)?; + let block = from_block(block, total_difficulty, txs_kind, None, tx_resp_builder)?; Ok(SimulatedBlock { inner: block, calls }) } diff --git a/crates/rpc/rpc-eth-types/src/transaction.rs b/crates/rpc/rpc-eth-types/src/transaction.rs index c3ca1b503aef..7d2237a1b7fb 100644 --- a/crates/rpc/rpc-eth-types/src/transaction.rs +++ b/crates/rpc/rpc-eth-types/src/transaction.rs @@ -41,9 +41,9 @@ impl TransactionSource { } /// Conversion into network specific transaction type. - pub fn into_transaction(self) -> T::Transaction { + pub fn into_transaction(self, resp_builder: &T) -> T::Transaction { match self { - Self::Pool(tx) => from_recovered::(tx), + Self::Pool(tx) => from_recovered(tx, resp_builder), Self::Block { transaction, index, block_hash, block_number, base_fee } => { let tx_info = TransactionInfo { hash: Some(transaction.hash()), @@ -53,7 +53,7 @@ impl TransactionSource { base_fee: base_fee.map(u128::from), }; - from_recovered_with_block_context::(transaction, tx_info) + from_recovered_with_block_context(transaction, tx_info, resp_builder) } } } diff --git a/crates/rpc/rpc-types-compat/Cargo.toml b/crates/rpc/rpc-types-compat/Cargo.toml index 8e436f0d3934..7d5eac9dbb91 100644 --- a/crates/rpc/rpc-types-compat/Cargo.toml +++ b/crates/rpc/rpc-types-compat/Cargo.toml @@ -26,5 +26,8 @@ alloy-serde.workspace = true alloy-rpc-types-engine.workspace = true alloy-consensus.workspace = true +# io +serde.workspace = true + [dev-dependencies] serde_json.workspace = true \ No newline at end of file diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index a650a69c1c1f..8cddc8c44977 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -20,12 +20,15 @@ pub fn from_block( total_difficulty: U256, kind: BlockTransactionsKind, block_hash: Option, + tx_resp_builder: &T, ) -> Result, BlockError> { match kind { BlockTransactionsKind::Hashes => { Ok(from_block_with_tx_hashes::(block, total_difficulty, block_hash)) } - BlockTransactionsKind::Full => from_block_full::(block, total_difficulty, block_hash), + BlockTransactionsKind::Full => { + from_block_full::(block, total_difficulty, block_hash, tx_resp_builder) + } } } @@ -60,6 +63,7 @@ pub fn from_block_full( mut block: BlockWithSenders, total_difficulty: U256, block_hash: Option, + tx_resp_builder: &T, ) -> Result, BlockError> { let block_hash = block_hash.unwrap_or_else(|| block.block.header.hash_slow()); let block_number = block.block.number; @@ -83,7 +87,7 @@ pub fn from_block_full( index: Some(idx as u64), }; - from_recovered_with_block_context::(signed_tx_ec_recovered, tx_info) + from_recovered_with_block_context::(signed_tx_ec_recovered, tx_info, tx_resp_builder) }) .collect::>(); diff --git a/crates/rpc/rpc-types-compat/src/transaction/mod.rs b/crates/rpc/rpc-types-compat/src/transaction/mod.rs index 7ffd48cb1f72..f8b46454dc23 100644 --- a/crates/rpc/rpc-types-compat/src/transaction/mod.rs +++ b/crates/rpc/rpc-types-compat/src/transaction/mod.rs @@ -2,6 +2,7 @@ mod signature; pub use signature::*; + use std::fmt; use alloy_consensus::Transaction as _; @@ -11,6 +12,7 @@ use alloy_rpc_types::{ }; use alloy_serde::WithOtherFields; use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered, TxType}; +use serde::{Deserialize, Serialize}; /// Create a new rpc transaction result for a mined transaction, using the given block hash, /// number, and tx index fields to populate the corresponding fields in the rpc result. @@ -20,21 +22,33 @@ use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered, TxType}; pub fn from_recovered_with_block_context( tx: TransactionSignedEcRecovered, tx_info: TransactionInfo, + resp_builder: &T, ) -> T::Transaction { - T::fill(tx, tx_info) + resp_builder.fill(tx, tx_info) } /// Create a new rpc transaction result for a _pending_ signed transaction, setting block /// environment related fields to `None`. -pub fn from_recovered(tx: TransactionSignedEcRecovered) -> T::Transaction { - T::fill(tx, TransactionInfo::default()) +pub fn from_recovered( + tx: TransactionSignedEcRecovered, + resp_builder: &T, +) -> T::Transaction { + resp_builder.fill(tx, TransactionInfo::default()) } /// Builds RPC transaction w.r.t. network. pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug { /// RPC transaction response type. - type Transaction: Send + Clone + Default + fmt::Debug; - + type Transaction: Serialize + + for<'de> Deserialize<'de> + + Send + + Sync + + Unpin + + Clone + + Default + + fmt::Debug; + + /// /// Formats gas price and max fee per gas for RPC transaction response w.r.t. network specific /// transaction type. fn gas_price(signed_tx: &TransactionSigned, base_fee: Option) -> GasPrice { @@ -63,7 +77,7 @@ pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug { /// Create a new rpc transaction result for a _pending_ signed transaction, setting block /// environment related fields to `None`. - fn fill(tx: TransactionSignedEcRecovered, tx_inf: TransactionInfo) -> Self::Transaction; + fn fill(&self, tx: TransactionSignedEcRecovered, tx_inf: TransactionInfo) -> Self::Transaction; /// Truncates the input of a transaction to only the first 4 bytes. // todo: remove in favour of using constructor on `TransactionResponse` or similar @@ -80,7 +94,11 @@ impl TransactionCompat for () { // `alloy_network::AnyNetwork` type Transaction = WithOtherFields; - fn fill(_tx: TransactionSignedEcRecovered, _tx_info: TransactionInfo) -> Self::Transaction { + fn fill( + &self, + _tx: TransactionSignedEcRecovered, + _tx_info: TransactionInfo, + ) -> Self::Transaction { WithOtherFields::default() } diff --git a/crates/rpc/rpc/src/eth/core.rs b/crates/rpc/rpc/src/eth/core.rs index 5c7fbbd00239..21787873e966 100644 --- a/crates/rpc/rpc/src/eth/core.rs +++ b/crates/rpc/rpc/src/eth/core.rs @@ -36,12 +36,15 @@ use crate::eth::EthTxBuilder; #[derive(Deref)] pub struct EthApi { /// All nested fields bundled together. + #[deref] pub(super) inner: Arc>, + /// Transaction RPC response builder. + pub tx_resp_builder: EthTxBuilder, } impl Clone for EthApi { fn clone(&self) -> Self { - Self { inner: self.inner.clone() } + Self { inner: self.inner.clone(), tx_resp_builder: EthTxBuilder } } } @@ -81,7 +84,7 @@ where proof_permits, ); - Self { inner: Arc::new(inner) } + Self { inner: Arc::new(inner), tx_resp_builder: EthTxBuilder } } } @@ -119,7 +122,7 @@ where ctx.config.proof_permits, ); - Self { inner: Arc::new(inner) } + Self { inner: Arc::new(inner), tx_resp_builder: EthTxBuilder } } } @@ -131,6 +134,10 @@ where // todo: replace with alloy_network::Ethereum type NetworkTypes = AnyNetwork; type TransactionCompat = EthTxBuilder; + + fn tx_resp_builder(&self) -> &Self::TransactionCompat { + &self.tx_resp_builder + } } impl std::fmt::Debug diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index b136861c7961..24058da1734c 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -4,7 +4,6 @@ use std::{ collections::HashMap, fmt, iter::StepBy, - marker::PhantomData, ops::RangeInclusive, sync::Arc, time::{Duration, Instant}, @@ -44,7 +43,7 @@ pub struct EthFilter { /// All nested fields bundled together inner: Arc>>, /// Assembles response data w.r.t. network. - _tx_resp_builder: PhantomData, + tx_resp_builder: Eth::TransactionCompat, } impl Clone for EthFilter @@ -52,7 +51,7 @@ where Eth: EthApiTypes, { fn clone(&self) -> Self { - Self { inner: self.inner.clone(), _tx_resp_builder: PhantomData } + Self { inner: self.inner.clone(), tx_resp_builder: self.tx_resp_builder.clone() } } } @@ -76,6 +75,7 @@ where eth_cache: EthStateCache, config: EthFilterConfig, task_spawner: Box, + tx_resp_builder: Eth::TransactionCompat, ) -> Self { let EthFilterConfig { max_blocks_per_filter, max_logs_per_response, stale_filter_ttl } = config; @@ -93,7 +93,7 @@ where max_logs_per_response: max_logs_per_response.unwrap_or(usize::MAX), }; - let eth_filter = Self { inner: Arc::new(inner), _tx_resp_builder: PhantomData }; + let eth_filter = Self { inner: Arc::new(inner), tx_resp_builder }; let this = eth_filter.clone(); eth_filter.inner.task_spawner.spawn_critical( @@ -278,7 +278,7 @@ where PendingTransactionFilterKind::Full => { let stream = self.inner.pool.new_pending_pool_transactions_listener(); let full_txs_receiver = - FullTransactionsReceiver::<_, Eth::TransactionCompat>::new(stream); + FullTransactionsReceiver::new(stream, self.tx_resp_builder.clone()); FilterKind::PendingTransaction(PendingTransactionKind::FullTransaction(Arc::new( full_txs_receiver, ))) @@ -603,7 +603,7 @@ impl PendingTransactionsReceiver { #[derive(Debug, Clone)] struct FullTransactionsReceiver { txs_stream: Arc>>, - _tx_resp_builder: PhantomData, + tx_resp_builder: TxCompat, } impl FullTransactionsReceiver @@ -612,8 +612,8 @@ where TxCompat: TransactionCompat, { /// Creates a new `FullTransactionsReceiver` encapsulating the provided transaction stream. - fn new(stream: NewSubpoolTransactionStream) -> Self { - Self { txs_stream: Arc::new(Mutex::new(stream)), _tx_resp_builder: PhantomData } + fn new(stream: NewSubpoolTransactionStream, tx_resp_builder: TxCompat) -> Self { + Self { txs_stream: Arc::new(Mutex::new(stream)), tx_resp_builder } } /// Returns all new pending transactions received since the last poll. @@ -625,7 +625,10 @@ 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())) + pending_txs.push(from_recovered( + tx.transaction.to_recovered_transaction(), + &self.tx_resp_builder, + )) } 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 ab7b1a268e06..848bcdc365a5 100644 --- a/crates/rpc/rpc/src/eth/helpers/types.rs +++ b/crates/rpc/rpc/src/eth/helpers/types.rs @@ -21,7 +21,11 @@ where { type Transaction = ::TransactionResponse; - fn fill(tx: TransactionSignedEcRecovered, tx_info: TransactionInfo) -> Self::Transaction { + fn fill( + &self, + tx: TransactionSignedEcRecovered, + tx_info: TransactionInfo, + ) -> Self::Transaction { let signer = tx.signer(); let signed_tx = tx.into_signed(); diff --git a/crates/rpc/rpc/src/eth/pubsub.rs b/crates/rpc/rpc/src/eth/pubsub.rs index 7bd1fd03d3b9..ac962610ef8a 100644 --- a/crates/rpc/rpc/src/eth/pubsub.rs +++ b/crates/rpc/rpc/src/eth/pubsub.rs @@ -1,6 +1,6 @@ //! `eth_` `PubSub` RPC handler implementation -use std::{marker::PhantomData, sync::Arc}; +use std::sync::Arc; use alloy_primitives::TxHash; use alloy_rpc_types::{ @@ -17,7 +17,7 @@ use jsonrpsee::{ }; use reth_network_api::NetworkInfo; use reth_provider::{BlockReader, CanonStateSubscriptions, EvmEnvProvider}; -use reth_rpc_eth_api::{pubsub::EthPubSubApiServer, FullEthApiTypes, RpcTransaction}; +use reth_rpc_eth_api::{pubsub::EthPubSubApiServer, TransactionCompat}; use reth_rpc_eth_types::logs_utils; use reth_rpc_server_types::result::{internal_rpc_err, invalid_params_rpc_err}; use reth_rpc_types_compat::transaction::from_recovered; @@ -38,7 +38,7 @@ pub struct EthPubSub { inner: Arc>, /// The type that's used to spawn subscription tasks. subscription_task_spawner: Box, - _tx_resp_builder: PhantomData, + tx_resp_builder: Eth, } // === impl EthPubSub === @@ -47,13 +47,20 @@ impl EthPubSub Self { + pub fn new( + provider: Provider, + pool: Pool, + chain_events: Events, + network: Network, + tx_resp_builder: Eth, + ) -> Self { Self::with_spawner( provider, pool, chain_events, network, Box::::default(), + tx_resp_builder, ) } @@ -64,21 +71,22 @@ impl EthPubSub, + tx_resp_builder: Eth, ) -> Self { let inner = EthPubSubInner { provider, pool, chain_events, network }; - Self { inner: Arc::new(inner), subscription_task_spawner, _tx_resp_builder: PhantomData } + Self { inner: Arc::new(inner), subscription_task_spawner, tx_resp_builder } } } #[async_trait::async_trait] -impl EthPubSubApiServer> +impl EthPubSubApiServer for EthPubSub where Provider: BlockReader + EvmEnvProvider + Clone + 'static, Pool: TransactionPool + 'static, Events: CanonStateSubscriptions + Clone + 'static, Network: NetworkInfo + Clone + 'static, - Eth: FullEthApiTypes + 'static, + Eth: TransactionCompat + 'static, { /// Handler for `eth_subscribe` async fn subscribe( @@ -89,8 +97,9 @@ where ) -> jsonrpsee::core::SubscriptionResult { let sink = pending.accept().await?; let pubsub = self.inner.clone(); + let resp_builder = self.tx_resp_builder.clone(); self.subscription_task_spawner.spawn(Box::pin(async move { - let _ = handle_accepted::<_, _, _, _, Eth>(pubsub, sink, kind, params).await; + let _ = handle_accepted(pubsub, sink, kind, params, resp_builder).await; })); Ok(()) @@ -103,13 +112,14 @@ async fn handle_accepted( accepted_sink: SubscriptionSink, kind: SubscriptionKind, params: Option, + tx_resp_builder: Eth, ) -> Result<(), ErrorObject<'static>> where Provider: BlockReader + EvmEnvProvider + Clone + 'static, Pool: TransactionPool + 'static, Events: CanonStateSubscriptions + Clone + 'static, Network: NetworkInfo + Clone + 'static, - Eth: FullEthApiTypes, + Eth: TransactionCompat, { match kind { SubscriptionKind::NewHeads => { @@ -140,10 +150,9 @@ where Params::Bool(true) => { // full transaction objects requested let stream = pubsub.full_pending_transaction_stream().map(|tx| { - EthSubscriptionResult::FullTransaction(Box::new(from_recovered::< - Eth::TransactionCompat, - >( + EthSubscriptionResult::FullTransaction(Box::new(from_recovered( tx.transaction.to_recovered_transaction(), + &tx_resp_builder, ))) }); 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 47aaac0bbfd5..d03e10ca75a8 100644 --- a/crates/rpc/rpc/src/txpool.rs +++ b/crates/rpc/rpc/src/txpool.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, marker::PhantomData}; +use std::collections::BTreeMap; use alloy_consensus::Transaction; use alloy_primitives::Address; @@ -9,7 +9,6 @@ use async_trait::async_trait; use jsonrpsee::core::RpcResult as Result; use reth_primitives::TransactionSignedEcRecovered; use reth_rpc_api::TxPoolApiServer; -use reth_rpc_eth_api::{FullEthApiTypes, RpcTransaction}; use reth_rpc_types_compat::{transaction::from_recovered, TransactionCompat}; use reth_transaction_pool::{AllPoolTransactions, PoolTransaction, TransactionPool}; use tracing::trace; @@ -21,33 +20,34 @@ use tracing::trace; pub struct TxPoolApi { /// An interface to interact with the pool pool: Pool, - _tx_resp_builder: PhantomData, + tx_resp_builder: Eth, } impl TxPoolApi { /// Creates a new instance of `TxpoolApi`. - pub const fn new(pool: Pool) -> Self { - Self { pool, _tx_resp_builder: PhantomData } + pub const fn new(pool: Pool, tx_resp_builder: Eth) -> Self { + Self { pool, tx_resp_builder } } } impl TxPoolApi where Pool: TransactionPool + 'static, - Eth: FullEthApiTypes, + Eth: TransactionCompat, { - fn content(&self) -> TxpoolContent> { + fn content(&self) -> TxpoolContent { #[inline] fn insert( tx: &Tx, content: &mut BTreeMap>, + resp_builder: &RpcTxB, ) where Tx: PoolTransaction>, RpcTxB: TransactionCompat, { content.entry(tx.sender()).or_default().insert( tx.nonce().to_string(), - from_recovered::(tx.clone().into_consensus().into()), + from_recovered(tx.clone().into_consensus().into(), resp_builder), ); } @@ -55,10 +55,10 @@ where let mut content = TxpoolContent { pending: BTreeMap::new(), queued: BTreeMap::new() }; for pending in pending { - insert::<_, Eth::TransactionCompat>(&pending.transaction, &mut content.pending); + insert::<_, Eth>(&pending.transaction, &mut content.pending, &self.tx_resp_builder); } for queued in queued { - insert::<_, Eth::TransactionCompat>(&queued.transaction, &mut content.queued); + insert::<_, Eth>(&queued.transaction, &mut content.queued, &self.tx_resp_builder); } content @@ -66,10 +66,10 @@ where } #[async_trait] -impl TxPoolApiServer> for TxPoolApi +impl TxPoolApiServer for TxPoolApi where Pool: TransactionPool + 'static, - Eth: FullEthApiTypes + 'static, + Eth: TransactionCompat + 'static, { /// Returns the number of transactions currently pending for inclusion in the next block(s), as /// well as the ones that are being scheduled for future execution only. @@ -131,7 +131,7 @@ where async fn txpool_content_from( &self, from: Address, - ) -> Result>> { + ) -> Result> { trace!(target: "rpc::eth", ?from, "Serving txpool_contentFrom"); Ok(self.content().remove_from(&from)) } @@ -141,7 +141,7 @@ 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) -> Result> { trace!(target: "rpc::eth", "Serving txpool_content"); Ok(self.content()) }