Skip to main content

reth_rpc_convert/
transaction.rs

1//! Compatibility functions for rpc `Transaction` type.
2use crate::{
3    RpcHeader, RpcLog, RpcReceipt, RpcTransaction, RpcTxReq, RpcTypes, SignableTxRequest,
4    TryIntoTxEnv,
5};
6use alloy_consensus::{error::ValueError, transaction::Recovered};
7use alloy_primitives::Address;
8use alloy_rpc_types_eth::{Log, TransactionInfo};
9use core::error;
10use dyn_clone::DynClone;
11use reth_evm::{BlockEnvFor, ConfigureEvm, EvmEnvFor, SpecFor, TxEnvFor};
12use reth_primitives_traits::{
13    BlockTy, HeaderTy, NodePrimitives, SealedBlock, SealedHeader, SealedHeaderFor, TransactionMeta,
14    TxTy,
15};
16use reth_rpc_traits::{FromConsensusHeader, FromConsensusTx, TryIntoSimTx, TxInfoMapper};
17use std::{convert::Infallible, error::Error, fmt, fmt::Debug, marker::PhantomData};
18
19/// Input for [`RpcConvert::convert_receipts`].
20#[derive(Debug, Clone)]
21pub struct ConvertReceiptInput<'a, N: NodePrimitives> {
22    /// Primitive receipt.
23    pub receipt: N::Receipt,
24    /// Transaction the receipt corresponds to.
25    pub tx: Recovered<&'a N::SignedTx>,
26    /// Gas used by the transaction.
27    pub gas_used: u64,
28    /// Number of logs emitted before this transaction.
29    pub next_log_index: usize,
30    /// Metadata for the transaction.
31    pub meta: TransactionMeta,
32}
33
34/// A type that knows how to convert primitive receipts to RPC representations.
35pub trait ReceiptConverter<N: NodePrimitives>: Debug + 'static {
36    /// RPC receipt representation.
37    type RpcReceipt;
38
39    /// RPC log representation.
40    type RpcLog;
41
42    /// Error that may occur during conversion.
43    type Error;
44
45    /// Converts an RPC log using its primitive receipt and block header.
46    fn convert_log(
47        &self,
48        log: Log,
49        receipt: &N::Receipt,
50        header: &SealedHeaderFor<N>,
51    ) -> Result<Self::RpcLog, Self::Error>;
52
53    /// Converts a set of primitive receipts to RPC representations. It is guaranteed that all
54    /// receipts are from the same block.
55    fn convert_receipts(
56        &self,
57        receipts: Vec<ConvertReceiptInput<'_, N>>,
58    ) -> Result<Vec<Self::RpcReceipt>, Self::Error>;
59
60    /// Converts primitive receipts from `block` to RPC representations.
61    fn convert_receipts_with_block(
62        &self,
63        receipts: Vec<ConvertReceiptInput<'_, N>>,
64        _block: &SealedBlock<N::Block>,
65    ) -> Result<Vec<Self::RpcReceipt>, Self::Error> {
66        self.convert_receipts(receipts)
67    }
68}
69
70/// A type that knows how to convert a consensus header into an RPC header.
71pub trait HeaderConverter<Consensus, Rpc>: Send + Sync + Unpin + Clone + 'static {
72    /// An associated RPC conversion error.
73    type Err: error::Error;
74
75    /// Converts a consensus header into an RPC header.
76    fn convert_header(
77        &self,
78        header: SealedHeader<Consensus>,
79        block_size: usize,
80    ) -> Result<Rpc, Self::Err>;
81}
82
83/// Default implementation of [`HeaderConverter`] that uses [`FromConsensusHeader`] to convert
84/// headers.
85impl<Consensus, Rpc> HeaderConverter<Consensus, Rpc> for ()
86where
87    Rpc: FromConsensusHeader<Consensus>,
88{
89    type Err = Infallible;
90
91    fn convert_header(
92        &self,
93        header: SealedHeader<Consensus>,
94        block_size: usize,
95    ) -> Result<Rpc, Self::Err> {
96        Ok(Rpc::from_consensus_header(header, block_size))
97    }
98}
99
100impl<Consensus, Rpc, F> HeaderConverter<Consensus, Rpc> for F
101where
102    F: Fn(SealedHeader<Consensus>, usize) -> Rpc + Send + Sync + Unpin + Clone + 'static,
103{
104    type Err = Infallible;
105
106    fn convert_header(
107        &self,
108        header: SealedHeader<Consensus>,
109        block_size: usize,
110    ) -> Result<Rpc, Self::Err> {
111        Ok(self(header, block_size))
112    }
113}
114
115/// Responsible for the conversions from and into RPC requests and responses.
116///
117/// The JSON-RPC schema and the Node primitives are configurable using the [`RpcConvert::Network`]
118/// and [`RpcConvert::Primitives`] associated types respectively.
119///
120/// A generic implementation [`RpcConverter`] should be preferred over a manual implementation. As
121/// long as its trait bound requirements are met, the implementation is created automatically and
122/// can be used in RPC method handlers for all the conversions.
123#[auto_impl::auto_impl(&, Box, Arc)]
124pub trait RpcConvert: Send + Sync + Unpin + Debug + DynClone + 'static {
125    /// Associated lower layer consensus types to convert from and into types of [`Self::Network`].
126    type Primitives: NodePrimitives;
127
128    /// The EVM configuration.
129    type Evm: ConfigureEvm<Primitives = Self::Primitives>;
130
131    /// Associated upper layer JSON-RPC API network requests and responses to convert from and into
132    /// types of [`Self::Primitives`].
133    type Network: RpcTypes<TransactionRequest: SignableTxRequest<TxTy<Self::Primitives>>>;
134
135    /// An associated RPC conversion error.
136    type Error: error::Error + Into<jsonrpsee_types::ErrorObject<'static>>;
137
138    /// Wrapper for `fill()` with default `TransactionInfo`
139    /// Create a new rpc transaction result for a _pending_ signed transaction, setting block
140    /// environment related fields to `None`.
141    fn fill_pending(
142        &self,
143        tx: Recovered<TxTy<Self::Primitives>>,
144    ) -> Result<RpcTransaction<Self::Network>, Self::Error> {
145        self.fill(tx, TransactionInfo::default())
146    }
147
148    /// Create a new rpc transaction result for a mined transaction, using the given block hash,
149    /// number, and tx index fields to populate the corresponding fields in the rpc result.
150    ///
151    /// The block hash, number, and tx index fields should be from the original block where the
152    /// transaction was mined.
153    fn fill(
154        &self,
155        tx: Recovered<TxTy<Self::Primitives>>,
156        tx_info: TransactionInfo,
157    ) -> Result<RpcTransaction<Self::Network>, Self::Error>;
158
159    /// Builds a fake transaction from a transaction request for inclusion into block built in
160    /// `eth_simulateV1`.
161    fn build_simulate_v1_transaction(
162        &self,
163        request: RpcTxReq<Self::Network>,
164    ) -> Result<TxTy<Self::Primitives>, Self::Error>;
165
166    /// Creates a transaction environment for execution based on `request` with corresponding
167    /// `cfg_env` and `block_env`.
168    fn tx_env(
169        &self,
170        request: RpcTxReq<Self::Network>,
171        evm_env: &EvmEnvFor<Self::Evm>,
172    ) -> Result<TxEnvFor<Self::Evm>, Self::Error>;
173
174    /// Converts an RPC log using its primitive receipt and block header.
175    fn convert_log(
176        &self,
177        log: Log,
178        receipt: &<Self::Primitives as NodePrimitives>::Receipt,
179        header: &SealedHeaderFor<Self::Primitives>,
180    ) -> Result<RpcLog<Self::Network>, Self::Error>;
181
182    /// Converts a set of primitive receipts to RPC representations. It is guaranteed that all
183    /// receipts are from the same block.
184    fn convert_receipts(
185        &self,
186        receipts: Vec<ConvertReceiptInput<'_, Self::Primitives>>,
187    ) -> Result<Vec<RpcReceipt<Self::Network>>, Self::Error>;
188
189    /// Converts primitive receipts from `block` to RPC representations.
190    fn convert_receipts_with_block(
191        &self,
192        receipts: Vec<ConvertReceiptInput<'_, Self::Primitives>>,
193        block: &SealedBlock<BlockTy<Self::Primitives>>,
194    ) -> Result<Vec<RpcReceipt<Self::Network>>, Self::Error>;
195
196    /// Converts a primitive header to an RPC header.
197    fn convert_header(
198        &self,
199        header: SealedHeaderFor<Self::Primitives>,
200        block_size: usize,
201    ) -> Result<RpcHeader<Self::Network>, Self::Error>;
202}
203
204dyn_clone::clone_trait_object!(
205    <Primitives, Network, Error, Evm>
206    RpcConvert<Primitives = Primitives, Network = Network, Error = Error, Evm = Evm>
207);
208
209/// Converts `Tx` into `RpcTx`
210///
211/// Where:
212/// * `Tx` is a transaction from the consensus layer.
213/// * `RpcTx` is a transaction response object of the RPC API
214///
215/// The conversion function is accompanied by `signer`'s address and `tx_info` providing extra
216/// context about a transaction in a block.
217///
218/// The `RpcTxConverter` has two blanket implementations:
219/// * `()` assuming `RpcTx` implements [`FromConsensusTx`] and is used as default for
220///   [`RpcConverter`].
221/// * `Fn(Tx, Address, TxInfo) -> RpcTx` and can be applied using
222///   [`RpcConverter::with_rpc_tx_converter`].
223///
224/// One should prefer to implement [`FromConsensusTx`] for `RpcTx` to get the `RpcTxConverter`
225/// implementation for free, thanks to the blanket implementation, unless the conversion requires
226/// more context. For example, some configuration parameters or access handles to database, network,
227/// etc.
228pub trait RpcTxConverter<Tx, RpcTx, TxInfo>: Clone + Unpin + Send + Sync + 'static {
229    /// An associated error that can happen during the conversion.
230    type Err;
231
232    /// Performs the conversion of `tx` from `Tx` into `RpcTx`.
233    ///
234    /// See [`RpcTxConverter`] for more information.
235    fn convert_rpc_tx(&self, tx: Tx, signer: Address, tx_info: TxInfo) -> Result<RpcTx, Self::Err>;
236}
237
238impl<Tx, RpcTx> RpcTxConverter<Tx, RpcTx, <RpcTx as FromConsensusTx<Tx>>::TxInfo> for ()
239where
240    RpcTx: FromConsensusTx<Tx>,
241{
242    type Err = RpcTx::Err;
243
244    fn convert_rpc_tx(
245        &self,
246        tx: Tx,
247        signer: Address,
248        tx_info: <RpcTx as FromConsensusTx<Tx>>::TxInfo,
249    ) -> Result<RpcTx, Self::Err> {
250        RpcTx::from_consensus_tx(tx, signer, tx_info)
251    }
252}
253
254impl<Tx, RpcTx, F, TxInfo, E> RpcTxConverter<Tx, RpcTx, TxInfo> for F
255where
256    F: Fn(Tx, Address, TxInfo) -> Result<RpcTx, E> + Clone + Unpin + Send + Sync + 'static,
257{
258    type Err = E;
259
260    fn convert_rpc_tx(&self, tx: Tx, signer: Address, tx_info: TxInfo) -> Result<RpcTx, Self::Err> {
261        self(tx, signer, tx_info)
262    }
263}
264
265/// Converts `TxReq` into `SimTx`.
266///
267/// Where:
268/// * `TxReq` is a transaction request received from an RPC API
269/// * `SimTx` is the corresponding consensus layer transaction for execution simulation
270///
271/// The `SimTxConverter` has two blanket implementations:
272/// * `()` assuming `TxReq` implements [`TryIntoSimTx`] and is used as default for [`RpcConverter`].
273/// * `Fn(TxReq) -> Result<SimTx, ValueError<TxReq>>` and can be applied using
274///   [`RpcConverter::with_sim_tx_converter`].
275///
276/// One should prefer to implement [`TryIntoSimTx`] for `TxReq` to get the `SimTxConverter`
277/// implementation for free, thanks to the blanket implementation, unless the conversion requires
278/// more context. For example, some configuration parameters or access handles to database, network,
279/// etc.
280pub trait SimTxConverter<TxReq, SimTx>: Clone + Unpin + Send + Sync + 'static {
281    /// An associated error that can occur during the conversion.
282    type Err: Error;
283
284    /// Performs the conversion from `tx_req` into `SimTx`.
285    ///
286    /// See [`SimTxConverter`] for more information.
287    fn convert_sim_tx(&self, tx_req: TxReq) -> Result<SimTx, Self::Err>;
288}
289
290impl<TxReq, SimTx> SimTxConverter<TxReq, SimTx> for ()
291where
292    TxReq: TryIntoSimTx<SimTx> + Debug,
293{
294    type Err = ValueError<TxReq>;
295
296    fn convert_sim_tx(&self, tx_req: TxReq) -> Result<SimTx, Self::Err> {
297        tx_req.try_into_sim_tx()
298    }
299}
300
301impl<TxReq, SimTx, F, E> SimTxConverter<TxReq, SimTx> for F
302where
303    TxReq: Debug,
304    E: Error,
305    F: Fn(TxReq) -> Result<SimTx, E> + Clone + Unpin + Send + Sync + 'static,
306{
307    type Err = E;
308
309    fn convert_sim_tx(&self, tx_req: TxReq) -> Result<SimTx, Self::Err> {
310        self(tx_req)
311    }
312}
313
314/// Converts `TxReq` into `TxEnv`.
315///
316/// Where:
317/// * `TxReq` is a transaction request received from an RPC API
318/// * `TxEnv` is the corresponding transaction environment for execution
319///
320/// The `TxEnvConverter` has two blanket implementations:
321/// * `()` assuming `TxReq` implements [`TryIntoTxEnv`] and is used as default for [`RpcConverter`].
322/// * `Fn(TxReq, &CfgEnv<Spec>, &BlockEnv) -> Result<TxEnv, E>` and can be applied using
323///   [`RpcConverter::with_tx_env_converter`].
324///
325/// One should prefer to implement [`TryIntoTxEnv`] for `TxReq` to get the `TxEnvConverter`
326/// implementation for free, thanks to the blanket implementation, unless the conversion requires
327/// more context. For example, some configuration parameters or access handles to database, network,
328/// etc.
329pub trait TxEnvConverter<TxReq, Evm: ConfigureEvm>:
330    Debug + Send + Sync + Unpin + Clone + 'static
331{
332    /// An associated error that can occur during conversion.
333    type Error;
334
335    /// Converts a rpc transaction request into a transaction environment.
336    ///
337    /// See [`TxEnvConverter`] for more information.
338    fn convert_tx_env(
339        &self,
340        tx_req: TxReq,
341        evm_env: &EvmEnvFor<Evm>,
342    ) -> Result<TxEnvFor<Evm>, Self::Error>;
343}
344
345impl<TxReq, Evm> TxEnvConverter<TxReq, Evm> for ()
346where
347    TxReq: TryIntoTxEnv<TxEnvFor<Evm>, SpecFor<Evm>, BlockEnvFor<Evm>>,
348    Evm: ConfigureEvm,
349{
350    type Error = TxReq::Err;
351
352    fn convert_tx_env(
353        &self,
354        tx_req: TxReq,
355        evm_env: &EvmEnvFor<Evm>,
356    ) -> Result<TxEnvFor<Evm>, Self::Error> {
357        tx_req.try_into_tx_env(evm_env)
358    }
359}
360
361/// Converts rpc transaction requests into transaction environment using a closure.
362impl<F, TxReq, E, Evm> TxEnvConverter<TxReq, Evm> for F
363where
364    F: Fn(TxReq, &EvmEnvFor<Evm>) -> Result<TxEnvFor<Evm>, E>
365        + Debug
366        + Send
367        + Sync
368        + Unpin
369        + Clone
370        + 'static,
371    TxReq: Clone,
372    Evm: ConfigureEvm,
373    E: error::Error + Send + Sync + 'static,
374{
375    type Error = E;
376
377    fn convert_tx_env(
378        &self,
379        tx_req: TxReq,
380        evm_env: &EvmEnvFor<Evm>,
381    ) -> Result<TxEnvFor<Evm>, Self::Error> {
382        self(tx_req, evm_env)
383    }
384}
385
386/// Conversion into transaction RPC response failed.
387#[derive(Debug, thiserror::Error)]
388pub enum TransactionConversionError {
389    /// Required fields are missing from the transaction request.
390    #[error("Failed to convert transaction into RPC response: {0}")]
391    FromTxReq(String),
392
393    /// Other conversion errors.
394    #[error("{0}")]
395    Other(String),
396}
397/// Generic RPC response object converter for `Evm` and network `Network`.
398///
399/// The main purpose of this struct is to provide an implementation of [`RpcConvert`] for generic
400/// associated types. This struct can then be used for conversions in RPC method handlers.
401///
402/// An [`RpcConvert`] implementation is generated if the following traits are implemented for the
403/// network and EVM associated primitives:
404/// * [`FromConsensusTx`]: from signed transaction into RPC response object.
405/// * [`TryIntoSimTx`]: from RPC transaction request into a simulated transaction.
406/// * [`TryIntoTxEnv`] or [`TxEnvConverter`]: from RPC transaction request into an executable
407///   transaction.
408/// * [`TxInfoMapper`]: from [`TransactionInfo`] into [`FromConsensusTx::TxInfo`]. Should be
409///   implemented for a dedicated struct that is assigned to `Map`. If [`FromConsensusTx::TxInfo`]
410///   is [`TransactionInfo`] then `()` can be used as `Map` which trivially passes over the input
411///   object.
412pub struct RpcConverter<
413    Network,
414    Evm,
415    Receipt,
416    Header = (),
417    Map = (),
418    SimTx = (),
419    RpcTx = (),
420    TxEnv = (),
421> {
422    network: PhantomData<Network>,
423    evm: PhantomData<Evm>,
424    receipt_converter: Receipt,
425    header_converter: Header,
426    mapper: Map,
427    tx_env_converter: TxEnv,
428    sim_tx_converter: SimTx,
429    rpc_tx_converter: RpcTx,
430}
431
432impl<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv> fmt::Debug
433    for RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
434{
435    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
436        f.debug_struct("RpcConverter").finish_non_exhaustive()
437    }
438}
439
440impl<Network, Evm, Receipt> RpcConverter<Network, Evm, Receipt> {
441    /// Creates a new [`RpcConverter`] with `receipt_converter` and `mapper`.
442    pub const fn new(receipt_converter: Receipt) -> Self {
443        Self {
444            network: PhantomData,
445            evm: PhantomData,
446            receipt_converter,
447            header_converter: (),
448            mapper: (),
449            tx_env_converter: (),
450            sim_tx_converter: (),
451            rpc_tx_converter: (),
452        }
453    }
454}
455
456impl<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
457    RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
458{
459    /// Converts the network type
460    pub fn with_network<N>(
461        self,
462    ) -> RpcConverter<N, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv> {
463        let Self {
464            receipt_converter,
465            header_converter,
466            mapper,
467            evm,
468            sim_tx_converter,
469            rpc_tx_converter,
470            tx_env_converter,
471            ..
472        } = self;
473        RpcConverter {
474            receipt_converter,
475            header_converter,
476            mapper,
477            network: Default::default(),
478            evm,
479            sim_tx_converter,
480            rpc_tx_converter,
481            tx_env_converter,
482        }
483    }
484
485    /// Converts the transaction environment type.
486    pub fn with_tx_env_converter<TxEnvNew>(
487        self,
488        tx_env_converter: TxEnvNew,
489    ) -> RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnvNew> {
490        let Self {
491            receipt_converter,
492            header_converter,
493            mapper,
494            network,
495            evm,
496            sim_tx_converter,
497            rpc_tx_converter,
498            ..
499        } = self;
500        RpcConverter {
501            receipt_converter,
502            header_converter,
503            mapper,
504            network,
505            evm,
506            sim_tx_converter,
507            rpc_tx_converter,
508            tx_env_converter,
509        }
510    }
511
512    /// Configures the header converter.
513    pub fn with_header_converter<HeaderNew>(
514        self,
515        header_converter: HeaderNew,
516    ) -> RpcConverter<Network, Evm, Receipt, HeaderNew, Map, SimTx, RpcTx, TxEnv> {
517        let Self {
518            receipt_converter,
519            header_converter: _,
520            mapper,
521            network,
522            evm,
523            sim_tx_converter,
524            rpc_tx_converter,
525            tx_env_converter,
526        } = self;
527        RpcConverter {
528            receipt_converter,
529            header_converter,
530            mapper,
531            network,
532            evm,
533            sim_tx_converter,
534            rpc_tx_converter,
535            tx_env_converter,
536        }
537    }
538
539    /// Configures the mapper.
540    pub fn with_mapper<MapNew>(
541        self,
542        mapper: MapNew,
543    ) -> RpcConverter<Network, Evm, Receipt, Header, MapNew, SimTx, RpcTx, TxEnv> {
544        let Self {
545            receipt_converter,
546            header_converter,
547            mapper: _,
548            network,
549            evm,
550            sim_tx_converter,
551            rpc_tx_converter,
552            tx_env_converter,
553        } = self;
554        RpcConverter {
555            receipt_converter,
556            header_converter,
557            mapper,
558            network,
559            evm,
560            sim_tx_converter,
561            rpc_tx_converter,
562            tx_env_converter,
563        }
564    }
565
566    /// Swaps the simulate transaction converter with `sim_tx_converter`.
567    pub fn with_sim_tx_converter<SimTxNew>(
568        self,
569        sim_tx_converter: SimTxNew,
570    ) -> RpcConverter<Network, Evm, Receipt, Header, Map, SimTxNew, RpcTx, TxEnv> {
571        let Self {
572            receipt_converter,
573            header_converter,
574            mapper,
575            network,
576            evm,
577            rpc_tx_converter,
578            tx_env_converter,
579            ..
580        } = self;
581        RpcConverter {
582            receipt_converter,
583            header_converter,
584            mapper,
585            network,
586            evm,
587            sim_tx_converter,
588            rpc_tx_converter,
589            tx_env_converter,
590        }
591    }
592
593    /// Swaps the RPC transaction converter with `rpc_tx_converter`.
594    pub fn with_rpc_tx_converter<RpcTxNew>(
595        self,
596        rpc_tx_converter: RpcTxNew,
597    ) -> RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTxNew, TxEnv> {
598        let Self {
599            receipt_converter,
600            header_converter,
601            mapper,
602            network,
603            evm,
604            sim_tx_converter,
605            tx_env_converter,
606            ..
607        } = self;
608        RpcConverter {
609            receipt_converter,
610            header_converter,
611            mapper,
612            network,
613            evm,
614            sim_tx_converter,
615            rpc_tx_converter,
616            tx_env_converter,
617        }
618    }
619
620    /// Converts `self` into a boxed converter.
621    pub fn erased(
622        self,
623    ) -> Box<
624        dyn RpcConvert<
625            Primitives = <Self as RpcConvert>::Primitives,
626            Network = <Self as RpcConvert>::Network,
627            Error = <Self as RpcConvert>::Error,
628            Evm = <Self as RpcConvert>::Evm,
629        >,
630    >
631    where
632        Self: RpcConvert,
633    {
634        Box::new(self)
635    }
636}
637
638impl<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv> Default
639    for RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
640where
641    Receipt: Default,
642    Header: Default,
643    Map: Default,
644    SimTx: Default,
645    RpcTx: Default,
646    TxEnv: Default,
647{
648    fn default() -> Self {
649        Self {
650            network: Default::default(),
651            evm: Default::default(),
652            receipt_converter: Default::default(),
653            header_converter: Default::default(),
654            mapper: Default::default(),
655            sim_tx_converter: Default::default(),
656            rpc_tx_converter: Default::default(),
657            tx_env_converter: Default::default(),
658        }
659    }
660}
661
662impl<
663        Network,
664        Evm,
665        Receipt: Clone,
666        Header: Clone,
667        Map: Clone,
668        SimTx: Clone,
669        RpcTx: Clone,
670        TxEnv: Clone,
671    > Clone for RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
672{
673    fn clone(&self) -> Self {
674        Self {
675            network: Default::default(),
676            evm: Default::default(),
677            receipt_converter: self.receipt_converter.clone(),
678            header_converter: self.header_converter.clone(),
679            mapper: self.mapper.clone(),
680            sim_tx_converter: self.sim_tx_converter.clone(),
681            rpc_tx_converter: self.rpc_tx_converter.clone(),
682            tx_env_converter: self.tx_env_converter.clone(),
683        }
684    }
685}
686
687impl<N, Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv> RpcConvert
688    for RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
689where
690    N: NodePrimitives,
691    Network: RpcTypes<TransactionRequest: SignableTxRequest<N::SignedTx>>,
692    Evm: ConfigureEvm<Primitives = N> + 'static,
693    Receipt: ReceiptConverter<
694            N,
695            RpcReceipt = RpcReceipt<Network>,
696            RpcLog = RpcLog<Network>,
697            Error: From<TransactionConversionError>
698                       + From<TxEnv::Error>
699                       + From<<Map as TxInfoMapper<TxTy<N>>>::Err>
700                       + From<RpcTx::Err>
701                       + From<Header::Err>
702                       + Error
703                       + Unpin
704                       + Sync
705                       + Send
706                       + Into<jsonrpsee_types::ErrorObject<'static>>,
707        > + Send
708        + Sync
709        + Unpin
710        + Clone
711        + Debug,
712    Header: HeaderConverter<HeaderTy<N>, RpcHeader<Network>>,
713    Map: TxInfoMapper<TxTy<N>> + Clone + Debug + Unpin + Send + Sync + 'static,
714    SimTx: SimTxConverter<RpcTxReq<Network>, TxTy<N>>,
715    RpcTx:
716        RpcTxConverter<TxTy<N>, Network::TransactionResponse, <Map as TxInfoMapper<TxTy<N>>>::Out>,
717    TxEnv: TxEnvConverter<RpcTxReq<Network>, Evm>,
718{
719    type Primitives = N;
720    type Evm = Evm;
721    type Network = Network;
722    type Error = Receipt::Error;
723
724    fn fill(
725        &self,
726        tx: Recovered<TxTy<N>>,
727        tx_info: TransactionInfo,
728    ) -> Result<Network::TransactionResponse, Self::Error> {
729        let (tx, signer) = tx.into_parts();
730        let tx_info = self.mapper.try_map(&tx, tx_info)?;
731
732        self.rpc_tx_converter.convert_rpc_tx(tx, signer, tx_info).map_err(Into::into)
733    }
734
735    fn build_simulate_v1_transaction(
736        &self,
737        request: RpcTxReq<Network>,
738    ) -> Result<TxTy<N>, Self::Error> {
739        Ok(self
740            .sim_tx_converter
741            .convert_sim_tx(request)
742            .map_err(|e| TransactionConversionError::FromTxReq(e.to_string()))?)
743    }
744
745    fn tx_env(
746        &self,
747        request: RpcTxReq<Network>,
748        evm_env: &EvmEnvFor<Evm>,
749    ) -> Result<TxEnvFor<Evm>, Self::Error> {
750        self.tx_env_converter.convert_tx_env(request, evm_env).map_err(Into::into)
751    }
752
753    fn convert_log(
754        &self,
755        log: Log,
756        receipt: &<Self::Primitives as NodePrimitives>::Receipt,
757        header: &SealedHeaderFor<Self::Primitives>,
758    ) -> Result<RpcLog<Self::Network>, Self::Error> {
759        self.receipt_converter.convert_log(log, receipt, header)
760    }
761
762    fn convert_receipts(
763        &self,
764        receipts: Vec<ConvertReceiptInput<'_, Self::Primitives>>,
765    ) -> Result<Vec<RpcReceipt<Self::Network>>, Self::Error> {
766        self.receipt_converter.convert_receipts(receipts)
767    }
768
769    fn convert_receipts_with_block(
770        &self,
771        receipts: Vec<ConvertReceiptInput<'_, Self::Primitives>>,
772        block: &SealedBlock<BlockTy<Self::Primitives>>,
773    ) -> Result<Vec<RpcReceipt<Self::Network>>, Self::Error> {
774        self.receipt_converter.convert_receipts_with_block(receipts, block)
775    }
776
777    fn convert_header(
778        &self,
779        header: SealedHeaderFor<Self::Primitives>,
780        block_size: usize,
781    ) -> Result<RpcHeader<Self::Network>, Self::Error> {
782        Ok(self.header_converter.convert_header(header, block_size)?)
783    }
784}