Skip to main content

reth_rpc_convert/
transaction.rs

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