1use crate::{
3 CallFees, RpcHeader, RpcLog, RpcReceipt, RpcTransaction, RpcTxReq, RpcTypes, SignableTxRequest,
4};
5use alloy_consensus::{
6 error::ValueError,
7 transaction::{Recovered, TxEip4844Variant},
8 TxEip1559, TxEip2930, TxEip4844, TxEip7702, TxLegacy, TxType,
9};
10use alloy_primitives::{Address, TxKind, U256};
11use alloy_rpc_types_eth::{
12 request::TransactionInputError, Log, TransactionInfo, TransactionRequest,
13};
14use core::error;
15use dyn_clone::DynClone;
16use evm2::ethereum::{RecoveredTxEnvelope, TxEnvelope};
17use reth_evm::{ConfigureEvm, EvmEnv, EvmEnvFor, TxEnvFor};
18use reth_primitives_traits::{
19 BlockTy, HeaderTy, NodePrimitives, SealedBlock, SealedHeader, SealedHeaderFor, TransactionMeta,
20 TxTy,
21};
22use reth_rpc_traits::{FromConsensusHeader, FromConsensusTx, TryIntoSimTx, TxInfoMapper};
23use std::{convert::Infallible, error::Error, fmt, fmt::Debug, marker::PhantomData};
24
25#[derive(Debug, Clone)]
27pub struct ConvertReceiptInput<'a, N: NodePrimitives> {
28 pub receipt: N::Receipt,
30 pub tx: Recovered<&'a N::SignedTx>,
32 pub gas_used: u64,
34 pub next_log_index: usize,
36 pub meta: TransactionMeta,
38}
39
40pub trait ReceiptConverter<N: NodePrimitives>: Debug + 'static {
42 type RpcReceipt;
44
45 type RpcLog;
47
48 type Error;
50
51 fn convert_log(
53 &self,
54 log: Log,
55 receipt: &N::Receipt,
56 header: &SealedHeaderFor<N>,
57 ) -> Result<Self::RpcLog, Self::Error>;
58
59 fn convert_receipts(
62 &self,
63 receipts: Vec<ConvertReceiptInput<'_, N>>,
64 ) -> Result<Vec<Self::RpcReceipt>, Self::Error>;
65
66 fn convert_receipts_with_block(
68 &self,
69 receipts: Vec<ConvertReceiptInput<'_, N>>,
70 _block: &SealedBlock<N::Block>,
71 ) -> Result<Vec<Self::RpcReceipt>, Self::Error> {
72 self.convert_receipts(receipts)
73 }
74}
75
76pub trait HeaderConverter<Consensus, Rpc>: Send + Sync + Unpin + Clone + 'static {
78 type Err: error::Error;
80
81 fn convert_header(
83 &self,
84 header: SealedHeader<Consensus>,
85 block_size: Option<usize>,
86 ) -> Result<Rpc, Self::Err>;
87}
88
89impl<Consensus, Rpc> HeaderConverter<Consensus, Rpc> for ()
92where
93 Rpc: FromConsensusHeader<Consensus>,
94{
95 type Err = Infallible;
96
97 fn convert_header(
98 &self,
99 header: SealedHeader<Consensus>,
100 block_size: Option<usize>,
101 ) -> Result<Rpc, Self::Err> {
102 Ok(Rpc::from_consensus_header(header, block_size))
103 }
104}
105
106impl<Consensus, Rpc, F> HeaderConverter<Consensus, Rpc> for F
107where
108 F: Fn(SealedHeader<Consensus>, Option<usize>) -> Rpc + Send + Sync + Unpin + Clone + 'static,
109{
110 type Err = Infallible;
111
112 fn convert_header(
113 &self,
114 header: SealedHeader<Consensus>,
115 block_size: Option<usize>,
116 ) -> Result<Rpc, Self::Err> {
117 Ok(self(header, block_size))
118 }
119}
120
121#[auto_impl::auto_impl(&, Box, Arc)]
130pub trait RpcConvert: Send + Sync + Unpin + Debug + DynClone + 'static {
131 type Primitives: NodePrimitives;
133
134 type Evm: ConfigureEvm<Primitives = Self::Primitives>;
136
137 type Network: RpcTypes<TransactionRequest: SignableTxRequest<TxTy<Self::Primitives>>>;
140
141 type Error: error::Error + Into<jsonrpsee_types::ErrorObject<'static>>;
143
144 fn fill_pending(
148 &self,
149 tx: Recovered<TxTy<Self::Primitives>>,
150 ) -> Result<RpcTransaction<Self::Network>, Self::Error> {
151 self.fill(tx, TransactionInfo::default())
152 }
153
154 fn fill(
160 &self,
161 tx: Recovered<TxTy<Self::Primitives>>,
162 tx_info: TransactionInfo,
163 ) -> Result<RpcTransaction<Self::Network>, Self::Error>;
164
165 fn build_simulate_v1_transaction(
168 &self,
169 request: RpcTxReq<Self::Network>,
170 ) -> Result<TxTy<Self::Primitives>, Self::Error>;
171
172 fn tx_env(
175 &self,
176 request: RpcTxReq<Self::Network>,
177 evm_env: &EvmEnvFor<Self::Evm>,
178 ) -> Result<TxEnvFor<Self::Evm>, Self::Error>;
179
180 fn convert_log(
182 &self,
183 log: Log,
184 receipt: &<Self::Primitives as NodePrimitives>::Receipt,
185 header: &SealedHeaderFor<Self::Primitives>,
186 ) -> Result<RpcLog<Self::Network>, Self::Error>;
187
188 fn convert_receipts(
191 &self,
192 receipts: Vec<ConvertReceiptInput<'_, Self::Primitives>>,
193 ) -> Result<Vec<RpcReceipt<Self::Network>>, Self::Error>;
194
195 fn convert_receipts_with_block(
197 &self,
198 receipts: Vec<ConvertReceiptInput<'_, Self::Primitives>>,
199 block: &SealedBlock<BlockTy<Self::Primitives>>,
200 ) -> Result<Vec<RpcReceipt<Self::Network>>, Self::Error>;
201
202 fn convert_header(
204 &self,
205 header: SealedHeaderFor<Self::Primitives>,
206 block_size: Option<usize>,
207 ) -> Result<RpcHeader<Self::Network>, Self::Error>;
208}
209
210dyn_clone::clone_trait_object!(
211 <Primitives, Network, Error, Evm>
212 RpcConvert<Primitives = Primitives, Network = Network, Error = Error, Evm = Evm>
213);
214
215pub trait RpcTxConverter<Tx, RpcTx, TxInfo>: Clone + Unpin + Send + Sync + 'static {
235 type Err;
237
238 fn convert_rpc_tx(&self, tx: Tx, signer: Address, tx_info: TxInfo) -> Result<RpcTx, Self::Err>;
242}
243
244impl<Tx, RpcTx> RpcTxConverter<Tx, RpcTx, <RpcTx as FromConsensusTx<Tx>>::TxInfo> for ()
245where
246 RpcTx: FromConsensusTx<Tx>,
247{
248 type Err = RpcTx::Err;
249
250 fn convert_rpc_tx(
251 &self,
252 tx: Tx,
253 signer: Address,
254 tx_info: <RpcTx as FromConsensusTx<Tx>>::TxInfo,
255 ) -> Result<RpcTx, Self::Err> {
256 RpcTx::from_consensus_tx(tx, signer, tx_info)
257 }
258}
259
260impl<Tx, RpcTx, F, TxInfo, E> RpcTxConverter<Tx, RpcTx, TxInfo> for F
261where
262 F: Fn(Tx, Address, TxInfo) -> Result<RpcTx, E> + Clone + Unpin + Send + Sync + 'static,
263{
264 type Err = E;
265
266 fn convert_rpc_tx(&self, tx: Tx, signer: Address, tx_info: TxInfo) -> Result<RpcTx, Self::Err> {
267 self(tx, signer, tx_info)
268 }
269}
270
271pub trait SimTxConverter<TxReq, SimTx>: Clone + Unpin + Send + Sync + 'static {
287 type Err: Error;
289
290 fn convert_sim_tx(&self, tx_req: TxReq) -> Result<SimTx, Self::Err>;
294}
295
296impl<TxReq, SimTx> SimTxConverter<TxReq, SimTx> for ()
297where
298 TxReq: TryIntoSimTx<SimTx> + Debug,
299{
300 type Err = ValueError<TxReq>;
301
302 fn convert_sim_tx(&self, tx_req: TxReq) -> Result<SimTx, Self::Err> {
303 tx_req.try_into_sim_tx()
304 }
305}
306
307impl<TxReq, SimTx, F, E> SimTxConverter<TxReq, SimTx> for F
308where
309 TxReq: Debug,
310 E: Error,
311 F: Fn(TxReq) -> Result<SimTx, E> + Clone + Unpin + Send + Sync + 'static,
312{
313 type Err = E;
314
315 fn convert_sim_tx(&self, tx_req: TxReq) -> Result<SimTx, Self::Err> {
316 self(tx_req)
317 }
318}
319
320pub trait TxEnvConverter<TxReq, Evm: ConfigureEvm>:
336 Debug + Send + Sync + Unpin + Clone + 'static
337{
338 type Error;
340
341 fn convert_tx_env(
345 &self,
346 tx_req: TxReq,
347 evm_env: &EvmEnvFor<Evm>,
348 ) -> Result<TxEnvFor<Evm>, Self::Error>;
349}
350
351pub trait TryIntoTxEnv<T, EvmEnv> {
353 type Err;
355
356 fn try_into_tx_env(self, evm_env: &EvmEnv) -> Result<T, Self::Err>;
358}
359
360#[derive(Debug, thiserror::Error)]
362pub enum EthTxEnvError {
363 #[error(transparent)]
365 CallFees(#[from] crate::CallFeesError),
366 #[error(transparent)]
368 Input(#[from] TransactionInputError),
369 #[error("blob transaction is a create transaction")]
371 BlobTransactionIsCreate,
372 #[error("EIP-7702 authorization list has invalid fields")]
374 AuthorizationListInvalidFields,
375}
376
377impl<Env> TryIntoTxEnv<RecoveredTxEnvelope, Env> for TransactionRequest
378where
379 Env: EvmEnv,
380{
381 type Err = EthTxEnvError;
382
383 fn try_into_tx_env(self, evm_env: &Env) -> Result<RecoveredTxEnvelope, Self::Err> {
384 transaction_request_to_evm2(self, evm_env)
385 }
386}
387
388impl<TxReq, Evm> TxEnvConverter<TxReq, Evm> for ()
389where
390 TxReq: TryIntoTxEnv<TxEnvFor<Evm>, EvmEnvFor<Evm>>,
391 Evm: ConfigureEvm,
392{
393 type Error = TxReq::Err;
394
395 fn convert_tx_env(
396 &self,
397 tx_req: TxReq,
398 evm_env: &EvmEnvFor<Evm>,
399 ) -> Result<TxEnvFor<Evm>, Self::Error> {
400 tx_req.try_into_tx_env(evm_env)
401 }
402}
403
404pub fn normalize_transaction_request(
414 request: &mut TransactionRequest,
415 evm_env: &impl EvmEnv,
416) -> Result<CallFees, EthTxEnvError> {
417 if request.blob_versioned_hashes.as_ref().is_some_and(Vec::is_empty) {
418 return Err(crate::CallFeesError::BlobTransactionMissingBlobHashes.into())
419 }
420 let input = request.input.clone().try_into_unique_input()?;
421 let fees = CallFees::ensure_fees(
422 request.gas_price.map(U256::from),
423 request.max_fee_per_gas.map(U256::from),
424 request.max_priority_fee_per_gas.map(U256::from),
425 U256::from(evm_env.block_base_fee()),
426 request.blob_versioned_hashes.as_deref(),
427 request.max_fee_per_blob_gas.map(U256::from),
428 Some(evm_env.block_env().blob_basefee),
429 )?;
430
431 if request.gas_price.is_none() {
432 if matches!(request.minimal_tx_type(), TxType::Legacy | TxType::Eip2930) {
433 request.gas_price = Some(fees.gas_price.saturating_to());
434 } else {
435 request.max_fee_per_gas.get_or_insert_with(|| fees.gas_price.saturating_to());
436 request.max_priority_fee_per_gas.get_or_insert(0);
437 }
438 }
439 if let Some(blob_fee) = fees.max_fee_per_blob_gas {
440 request.max_fee_per_blob_gas.get_or_insert_with(|| blob_fee.saturating_to());
441 }
442 request.from.get_or_insert(Address::ZERO);
443 request.nonce.get_or_insert(0);
444 request.gas.get_or_insert_with(|| evm_env.block_env().gas_limit.saturating_to());
445 request.chain_id.get_or_insert_with(|| evm_env.chain_id());
446 request.value.get_or_insert(U256::ZERO);
447 request.input = alloy_rpc_types_eth::TransactionInput::new(input.unwrap_or_default());
448 Ok(fees)
449}
450
451fn transaction_request_to_evm2(
452 mut request: TransactionRequest,
453 evm_env: &impl EvmEnv,
454) -> Result<RecoveredTxEnvelope, EthTxEnvError> {
455 let tx_type = request.minimal_tx_type();
456 let CallFees { max_priority_fee_per_gas, gas_price, max_fee_per_blob_gas } =
457 normalize_transaction_request(&mut request, evm_env)?;
458 let TransactionRequest {
459 from,
460 to,
461 gas_price: _,
462 max_fee_per_gas: _,
463 max_priority_fee_per_gas: _,
464 gas,
465 value,
466 input,
467 nonce,
468 access_list,
469 chain_id,
470 blob_versioned_hashes,
471 max_fee_per_blob_gas: _,
472 authorization_list,
473 transaction_type: _,
474 sidecar: _,
475 } = request;
476 let input = input.try_into_unique_input()?.unwrap_or_default();
477 let caller = from.unwrap_or_default();
478 let to = to.unwrap_or(TxKind::Create);
479 let gas_limit = gas.expect("gas limit normalized");
480 let nonce = nonce.unwrap_or_default();
481 let chain_id = chain_id.expect("chain ID normalized");
482 let value = value.unwrap_or_default();
483 let access_list = access_list.unwrap_or_default();
484 let gas_price = gas_price.saturating_to();
485 let max_priority_fee_per_gas =
487 max_priority_fee_per_gas.map(|fee| fee.saturating_to()).unwrap_or(gas_price);
488
489 let tx = match tx_type {
490 TxType::Legacy => TxEnvelope::Legacy(TxLegacy {
491 chain_id: Some(chain_id),
492 nonce,
493 gas_price,
494 gas_limit,
495 to,
496 value,
497 input,
498 }),
499 TxType::Eip2930 => TxEnvelope::Eip2930(TxEip2930 {
500 chain_id,
501 nonce,
502 gas_price,
503 gas_limit,
504 to,
505 value,
506 access_list,
507 input,
508 }),
509 TxType::Eip1559 => TxEnvelope::Eip1559(TxEip1559 {
510 chain_id,
511 nonce,
512 gas_limit,
513 max_fee_per_gas: gas_price,
514 max_priority_fee_per_gas,
515 to,
516 value,
517 access_list,
518 input,
519 }),
520 TxType::Eip4844 => TxEnvelope::Eip4844(TxEip4844Variant::TxEip4844(TxEip4844 {
521 chain_id,
522 nonce,
523 gas_limit,
524 max_fee_per_gas: gas_price,
525 max_priority_fee_per_gas,
526 to: to.to().copied().ok_or(EthTxEnvError::BlobTransactionIsCreate)?,
527 value,
528 access_list,
529 blob_versioned_hashes: blob_versioned_hashes.unwrap_or_default(),
530 max_fee_per_blob_gas: max_fee_per_blob_gas.unwrap_or_default().saturating_to(),
531 input,
532 })),
533 TxType::Eip7702 => TxEnvelope::Eip7702(
534 TxEip7702 {
535 chain_id,
536 nonce,
537 gas_limit,
538 max_fee_per_gas: gas_price,
539 max_priority_fee_per_gas,
540 to: to.to().copied().ok_or(EthTxEnvError::AuthorizationListInvalidFields)?,
541 value,
542 access_list,
543 authorization_list: authorization_list.unwrap_or_default(),
544 input,
545 }
546 .into(),
547 ),
548 };
549 Ok(Recovered::new_unchecked(tx, caller))
550}
551
552impl<F, TxReq, E, Evm> TxEnvConverter<TxReq, Evm> for F
554where
555 F: Fn(TxReq, &EvmEnvFor<Evm>) -> Result<TxEnvFor<Evm>, E>
556 + Debug
557 + Send
558 + Sync
559 + Unpin
560 + Clone
561 + 'static,
562 TxReq: Clone,
563 Evm: ConfigureEvm,
564 E: error::Error + Send + Sync + 'static,
565{
566 type Error = E;
567
568 fn convert_tx_env(
569 &self,
570 tx_req: TxReq,
571 evm_env: &EvmEnvFor<Evm>,
572 ) -> Result<TxEnvFor<Evm>, Self::Error> {
573 self(tx_req, evm_env)
574 }
575}
576
577#[derive(Debug, thiserror::Error)]
579pub enum TransactionConversionError {
580 #[error("Failed to convert transaction into RPC response: {0}")]
582 FromTxReq(String),
583
584 #[error("{0}")]
586 Other(String),
587}
588pub struct RpcConverter<
604 Network,
605 Evm,
606 Receipt,
607 Header = (),
608 Map = (),
609 SimTx = (),
610 RpcTx = (),
611 TxEnv = (),
612> {
613 network: PhantomData<Network>,
614 evm: PhantomData<Evm>,
615 receipt_converter: Receipt,
616 header_converter: Header,
617 mapper: Map,
618 tx_env_converter: TxEnv,
619 sim_tx_converter: SimTx,
620 rpc_tx_converter: RpcTx,
621}
622
623impl<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv> fmt::Debug
624 for RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
625{
626 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
627 f.debug_struct("RpcConverter").finish_non_exhaustive()
628 }
629}
630
631impl<Network, Evm, Receipt> RpcConverter<Network, Evm, Receipt> {
632 pub const fn new(receipt_converter: Receipt) -> Self {
634 Self {
635 network: PhantomData,
636 evm: PhantomData,
637 receipt_converter,
638 header_converter: (),
639 mapper: (),
640 tx_env_converter: (),
641 sim_tx_converter: (),
642 rpc_tx_converter: (),
643 }
644 }
645}
646
647impl<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
648 RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
649{
650 pub fn with_network<N>(
652 self,
653 ) -> RpcConverter<N, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv> {
654 let Self {
655 receipt_converter,
656 header_converter,
657 mapper,
658 evm,
659 sim_tx_converter,
660 rpc_tx_converter,
661 tx_env_converter,
662 ..
663 } = self;
664 RpcConverter {
665 receipt_converter,
666 header_converter,
667 mapper,
668 network: Default::default(),
669 evm,
670 sim_tx_converter,
671 rpc_tx_converter,
672 tx_env_converter,
673 }
674 }
675
676 pub fn with_tx_env_converter<TxEnvNew>(
678 self,
679 tx_env_converter: TxEnvNew,
680 ) -> RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnvNew> {
681 let Self {
682 receipt_converter,
683 header_converter,
684 mapper,
685 network,
686 evm,
687 sim_tx_converter,
688 rpc_tx_converter,
689 ..
690 } = self;
691 RpcConverter {
692 receipt_converter,
693 header_converter,
694 mapper,
695 network,
696 evm,
697 sim_tx_converter,
698 rpc_tx_converter,
699 tx_env_converter,
700 }
701 }
702
703 pub fn with_header_converter<HeaderNew>(
705 self,
706 header_converter: HeaderNew,
707 ) -> RpcConverter<Network, Evm, Receipt, HeaderNew, Map, SimTx, RpcTx, TxEnv> {
708 let Self {
709 receipt_converter,
710 header_converter: _,
711 mapper,
712 network,
713 evm,
714 sim_tx_converter,
715 rpc_tx_converter,
716 tx_env_converter,
717 } = self;
718 RpcConverter {
719 receipt_converter,
720 header_converter,
721 mapper,
722 network,
723 evm,
724 sim_tx_converter,
725 rpc_tx_converter,
726 tx_env_converter,
727 }
728 }
729
730 pub fn with_mapper<MapNew>(
732 self,
733 mapper: MapNew,
734 ) -> RpcConverter<Network, Evm, Receipt, Header, MapNew, SimTx, RpcTx, TxEnv> {
735 let Self {
736 receipt_converter,
737 header_converter,
738 mapper: _,
739 network,
740 evm,
741 sim_tx_converter,
742 rpc_tx_converter,
743 tx_env_converter,
744 } = self;
745 RpcConverter {
746 receipt_converter,
747 header_converter,
748 mapper,
749 network,
750 evm,
751 sim_tx_converter,
752 rpc_tx_converter,
753 tx_env_converter,
754 }
755 }
756
757 pub fn with_sim_tx_converter<SimTxNew>(
759 self,
760 sim_tx_converter: SimTxNew,
761 ) -> RpcConverter<Network, Evm, Receipt, Header, Map, SimTxNew, RpcTx, TxEnv> {
762 let Self {
763 receipt_converter,
764 header_converter,
765 mapper,
766 network,
767 evm,
768 rpc_tx_converter,
769 tx_env_converter,
770 ..
771 } = self;
772 RpcConverter {
773 receipt_converter,
774 header_converter,
775 mapper,
776 network,
777 evm,
778 sim_tx_converter,
779 rpc_tx_converter,
780 tx_env_converter,
781 }
782 }
783
784 pub fn with_rpc_tx_converter<RpcTxNew>(
786 self,
787 rpc_tx_converter: RpcTxNew,
788 ) -> RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTxNew, TxEnv> {
789 let Self {
790 receipt_converter,
791 header_converter,
792 mapper,
793 network,
794 evm,
795 sim_tx_converter,
796 tx_env_converter,
797 ..
798 } = self;
799 RpcConverter {
800 receipt_converter,
801 header_converter,
802 mapper,
803 network,
804 evm,
805 sim_tx_converter,
806 rpc_tx_converter,
807 tx_env_converter,
808 }
809 }
810
811 pub fn erased(
813 self,
814 ) -> Box<
815 dyn RpcConvert<
816 Primitives = <Self as RpcConvert>::Primitives,
817 Network = <Self as RpcConvert>::Network,
818 Error = <Self as RpcConvert>::Error,
819 Evm = <Self as RpcConvert>::Evm,
820 >,
821 >
822 where
823 Self: RpcConvert,
824 {
825 Box::new(self)
826 }
827}
828
829impl<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv> Default
830 for RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
831where
832 Receipt: Default,
833 Header: Default,
834 Map: Default,
835 SimTx: Default,
836 RpcTx: Default,
837 TxEnv: Default,
838{
839 fn default() -> Self {
840 Self {
841 network: Default::default(),
842 evm: Default::default(),
843 receipt_converter: Default::default(),
844 header_converter: Default::default(),
845 mapper: Default::default(),
846 sim_tx_converter: Default::default(),
847 rpc_tx_converter: Default::default(),
848 tx_env_converter: Default::default(),
849 }
850 }
851}
852
853impl<
854 Network,
855 Evm,
856 Receipt: Clone,
857 Header: Clone,
858 Map: Clone,
859 SimTx: Clone,
860 RpcTx: Clone,
861 TxEnv: Clone,
862 > Clone for RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
863{
864 fn clone(&self) -> Self {
865 Self {
866 network: Default::default(),
867 evm: Default::default(),
868 receipt_converter: self.receipt_converter.clone(),
869 header_converter: self.header_converter.clone(),
870 mapper: self.mapper.clone(),
871 sim_tx_converter: self.sim_tx_converter.clone(),
872 rpc_tx_converter: self.rpc_tx_converter.clone(),
873 tx_env_converter: self.tx_env_converter.clone(),
874 }
875 }
876}
877
878impl<N, Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv> RpcConvert
879 for RpcConverter<Network, Evm, Receipt, Header, Map, SimTx, RpcTx, TxEnv>
880where
881 N: NodePrimitives,
882 Network: RpcTypes<TransactionRequest: SignableTxRequest<N::SignedTx>>,
883 Evm: ConfigureEvm<Primitives = N> + 'static,
884 Receipt: ReceiptConverter<
885 N,
886 RpcReceipt = RpcReceipt<Network>,
887 RpcLog = RpcLog<Network>,
888 Error: From<TransactionConversionError>
889 + From<TxEnv::Error>
890 + From<<Map as TxInfoMapper<TxTy<N>>>::Err>
891 + From<RpcTx::Err>
892 + From<Header::Err>
893 + Error
894 + Unpin
895 + Sync
896 + Send
897 + Into<jsonrpsee_types::ErrorObject<'static>>,
898 > + Send
899 + Sync
900 + Unpin
901 + Clone,
902 Header: HeaderConverter<HeaderTy<N>, RpcHeader<Network>>,
903 Map: TxInfoMapper<TxTy<N>> + Clone + Debug + Unpin + Send + Sync + 'static,
904 SimTx: SimTxConverter<RpcTxReq<Network>, TxTy<N>>,
905 RpcTx:
906 RpcTxConverter<TxTy<N>, Network::TransactionResponse, <Map as TxInfoMapper<TxTy<N>>>::Out>,
907 TxEnv: TxEnvConverter<RpcTxReq<Network>, Evm>,
908{
909 type Primitives = N;
910 type Evm = Evm;
911 type Network = Network;
912 type Error = Receipt::Error;
913
914 fn fill(
915 &self,
916 tx: Recovered<TxTy<N>>,
917 tx_info: TransactionInfo,
918 ) -> Result<Network::TransactionResponse, Self::Error> {
919 let (tx, signer) = tx.into_parts();
920 let tx_info = self.mapper.try_map(&tx, tx_info)?;
921
922 self.rpc_tx_converter.convert_rpc_tx(tx, signer, tx_info).map_err(Into::into)
923 }
924
925 fn build_simulate_v1_transaction(
926 &self,
927 request: RpcTxReq<Network>,
928 ) -> Result<TxTy<N>, Self::Error> {
929 Ok(self
930 .sim_tx_converter
931 .convert_sim_tx(request)
932 .map_err(|e| TransactionConversionError::FromTxReq(e.to_string()))?)
933 }
934
935 fn tx_env(
936 &self,
937 request: RpcTxReq<Network>,
938 evm_env: &EvmEnvFor<Evm>,
939 ) -> Result<TxEnvFor<Evm>, Self::Error> {
940 self.tx_env_converter.convert_tx_env(request, evm_env).map_err(Into::into)
941 }
942
943 fn convert_log(
944 &self,
945 log: Log,
946 receipt: &<Self::Primitives as NodePrimitives>::Receipt,
947 header: &SealedHeaderFor<Self::Primitives>,
948 ) -> Result<RpcLog<Self::Network>, Self::Error> {
949 self.receipt_converter.convert_log(log, receipt, header)
950 }
951
952 fn convert_receipts(
953 &self,
954 receipts: Vec<ConvertReceiptInput<'_, Self::Primitives>>,
955 ) -> Result<Vec<RpcReceipt<Self::Network>>, Self::Error> {
956 self.receipt_converter.convert_receipts(receipts)
957 }
958
959 fn convert_receipts_with_block(
960 &self,
961 receipts: Vec<ConvertReceiptInput<'_, Self::Primitives>>,
962 block: &SealedBlock<BlockTy<Self::Primitives>>,
963 ) -> Result<Vec<RpcReceipt<Self::Network>>, Self::Error> {
964 self.receipt_converter.convert_receipts_with_block(receipts, block)
965 }
966
967 fn convert_header(
968 &self,
969 header: SealedHeaderFor<Self::Primitives>,
970 block_size: Option<usize>,
971 ) -> Result<RpcHeader<Self::Network>, Self::Error> {
972 Ok(self.header_converter.convert_header(header, block_size)?)
973 }
974}