@@ -7,15 +7,15 @@ use graph::{
77 blockchain:: {
88 self , Block as BlockchainBlock , BlockPtr , BlockTime , ChainStoreBlock , ChainStoreData ,
99 } ,
10+ components:: ethereum:: { AnyBlock , AnyHeader , AnyRpcHeader , AnyRpcTransaction , AnyTxEnvelope } ,
1011 prelude:: {
1112 alloy:: {
1213 self ,
13- consensus:: { ReceiptEnvelope , ReceiptWithBloom , TxEnvelope , TxType } ,
14+ consensus:: { ReceiptWithBloom , TxEnvelope , TxType } ,
15+ network:: AnyReceiptEnvelope ,
1416 primitives:: { aliases:: B2048 , Address , Bloom , Bytes , LogData , B256 , U256 } ,
15- rpc:: types:: {
16- AccessList , AccessListItem , Block as AlloyBlock , Transaction ,
17- TransactionReceipt as AlloyTransactionReceipt ,
18- } ,
17+ rpc:: types:: { self as alloy_rpc_types, AccessList , AccessListItem , Transaction } ,
18+ serde:: WithOtherFields ,
1919 } ,
2020 BlockNumber , Error , EthereumBlock , EthereumBlockWithCalls , EthereumCall ,
2121 LightEthereumBlock ,
@@ -142,18 +142,21 @@ impl<'a> TransactionTraceAt<'a> {
142142 }
143143}
144144
145- impl < ' a > TryInto < Transaction > for TransactionTraceAt < ' a > {
145+ impl < ' a > TryInto < Transaction < AnyTxEnvelope > > for TransactionTraceAt < ' a > {
146146 type Error = Error ;
147147
148- fn try_into ( self ) -> Result < Transaction , Self :: Error > {
148+ fn try_into ( self ) -> Result < Transaction < AnyTxEnvelope > , Self :: Error > {
149149 use alloy:: {
150150 consensus:: transaction:: Recovered ,
151151 consensus:: {
152152 Signed , TxEip1559 , TxEip2930 , TxEip4844 , TxEip4844Variant , TxEip7702 , TxLegacy ,
153153 } ,
154+ network:: { AnyTxEnvelope , AnyTxType , UnknownTxEnvelope , UnknownTypedTransaction } ,
154155 primitives:: { Bytes , TxKind , U256 } ,
155156 rpc:: types:: Transaction as AlloyTransaction ,
157+ serde:: OtherFields ,
156158 } ;
159+ use std:: collections:: BTreeMap ;
157160
158161 // Extract data from trace and block
159162 let block_hash = self . block . hash . try_decode_proto ( "transaction block hash" ) ?;
@@ -172,20 +175,77 @@ impl<'a> TryInto<Transaction> for TransactionTraceAt<'a> {
172175 let gas_limit = self . trace . gas_limit ;
173176 let input = Bytes :: from ( self . trace . input . clone ( ) ) ;
174177
175- let tx_type = u64:: try_from ( self . trace . r#type ) . map_err ( |_| {
178+ let tx_type_u64 = u64:: try_from ( self . trace . r#type ) . map_err ( |_| {
176179 format_err ! (
177180 "Invalid transaction type value {} in transaction trace. Transaction type must be a valid u64." ,
178181 self . trace. r#type
179182 )
180183 } ) ?;
181184
182- let tx_type = TxType :: try_from ( tx_type) . map_err ( |_| {
183- format_err ! (
184- "Unsupported transaction type {} in transaction trace. Only standard Ethereum transaction types (Legacy=0, EIP-2930=1, EIP-1559=2, EIP-4844=3, EIP-7702=4) are supported." ,
185- tx_type
186- )
187- } ) ?;
185+ // Try to convert to known Ethereum transaction type
186+ let tx_type_result = TxType :: try_from ( tx_type_u64) ;
187+
188+ // If this is an unknown transaction type, create an UnknownTxEnvelope
189+ if tx_type_result. is_err ( ) {
190+ let mut fields_map = BTreeMap :: new ( ) ;
191+
192+ fields_map. insert (
193+ "nonce" . to_string ( ) ,
194+ jsonrpc_core:: serde_json:: json!( format!( "0x{:x}" , self . trace. nonce) ) ,
195+ ) ;
196+ fields_map. insert (
197+ "from" . to_string ( ) ,
198+ jsonrpc_core:: serde_json:: json!( format!( "{:?}" , from_address) ) ,
199+ ) ;
200+ if let Some ( to_addr) = to {
201+ fields_map. insert (
202+ "to" . to_string ( ) ,
203+ jsonrpc_core:: serde_json:: json!( format!( "{:?}" , to_addr) ) ,
204+ ) ;
205+ }
206+ fields_map. insert (
207+ "value" . to_string ( ) ,
208+ jsonrpc_core:: serde_json:: json!( format!( "0x{:x}" , value) ) ,
209+ ) ;
210+ fields_map. insert (
211+ "gas" . to_string ( ) ,
212+ jsonrpc_core:: serde_json:: json!( format!( "0x{:x}" , gas_limit) ) ,
213+ ) ;
214+ fields_map. insert (
215+ "gasPrice" . to_string ( ) ,
216+ jsonrpc_core:: serde_json:: json!( format!( "0x{:x}" , gas_price) ) ,
217+ ) ;
218+ fields_map. insert (
219+ "input" . to_string ( ) ,
220+ jsonrpc_core:: serde_json:: json!( format!( "0x{}" , hex:: encode( & input) ) ) ,
221+ ) ;
222+
223+ let fields = OtherFields :: new ( fields_map) ;
224+ let unknown_tx = UnknownTypedTransaction {
225+ ty : AnyTxType ( tx_type_u64 as u8 ) ,
226+ fields,
227+ memo : Default :: default ( ) ,
228+ } ;
229+
230+ let tx_hash = self . trace . hash . try_decode_proto ( "transaction hash" ) ?;
231+ let unknown_envelope = UnknownTxEnvelope {
232+ hash : tx_hash,
233+ inner : unknown_tx,
234+ } ;
235+
236+ let any_envelope = AnyTxEnvelope :: Unknown ( unknown_envelope) ;
237+ let recovered = Recovered :: new_unchecked ( any_envelope, from_address) ;
238+
239+ return Ok ( AlloyTransaction {
240+ inner : recovered,
241+ block_hash : Some ( block_hash) ,
242+ block_number : Some ( block_number) ,
243+ transaction_index,
244+ effective_gas_price : if gas_price > 0 { Some ( gas_price) } else { None } ,
245+ } ) ;
246+ }
188247
248+ let tx_type = tx_type_result. unwrap ( ) ;
189249 let nonce = self . trace . nonce ;
190250
191251 // Extract EIP-1559 fee fields from trace
@@ -358,7 +418,8 @@ impl<'a> TryInto<Transaction> for TransactionTraceAt<'a> {
358418 }
359419 } ;
360420
361- let recovered = Recovered :: new_unchecked ( envelope, from_address) ;
421+ let any_envelope = AnyTxEnvelope :: Ethereum ( envelope) ;
422+ let recovered = Recovered :: new_unchecked ( any_envelope, from_address) ;
362423
363424 Ok ( AlloyTransaction {
364425 inner : recovered,
@@ -378,10 +439,10 @@ impl TryInto<BlockFinality> for &Block {
378439 }
379440}
380441
381- impl TryInto < AlloyBlock > for & Block {
442+ impl TryInto < AnyBlock > for & Block {
382443 type Error = Error ;
383444
384- fn try_into ( self ) -> Result < AlloyBlock , Self :: Error > {
445+ fn try_into ( self ) -> Result < AnyBlock , Self :: Error > {
385446 let header = self . header ( ) ;
386447
387448 let block_hash = self . hash . try_decode_proto ( "block hash" ) ?;
@@ -458,27 +519,39 @@ impl TryInto<AlloyBlock> for &Block {
458519 . transaction_traces
459520 . iter ( )
460521 . map ( |t| TransactionTraceAt :: new ( t, self ) . try_into ( ) )
461- . collect :: < Result < Vec < Transaction > , Error > > ( ) ?;
522+ . collect :: < Result < Vec < Transaction < AnyTxEnvelope > > , Error > > ( ) ?;
462523
463524 let uncles = self
464525 . uncles
465526 . iter ( )
466527 . map ( |u| u. hash . try_decode_proto ( "uncle hash" ) )
467528 . collect :: < Result < Vec < B256 > , _ > > ( ) ?;
468529
469- Ok ( AlloyBlock :: new (
470- rpc_header,
471- alloy:: rpc:: types:: BlockTransactions :: Full ( transactions) ,
472- )
473- . with_uncles ( uncles) )
530+ use alloy:: rpc:: types:: Block ;
531+
532+ let any_header: AnyRpcHeader = rpc_header. map ( AnyHeader :: from) ;
533+
534+ let any_transactions: Vec < AnyRpcTransaction > = transactions
535+ . into_iter ( )
536+ . map ( |tx| AnyRpcTransaction :: new ( WithOtherFields :: new ( tx) ) )
537+ . collect ( ) ;
538+
539+ let any_block = Block {
540+ header : any_header,
541+ transactions : alloy:: rpc:: types:: BlockTransactions :: Full ( any_transactions) ,
542+ uncles,
543+ withdrawals : None ,
544+ } ;
545+
546+ Ok ( AnyBlock :: new ( WithOtherFields :: new ( any_block) ) )
474547 }
475548}
476549
477550impl TryInto < EthereumBlockWithCalls > for & Block {
478551 type Error = Error ;
479552
480553 fn try_into ( self ) -> Result < EthereumBlockWithCalls , Self :: Error > {
481- let alloy_block: AlloyBlock = self . try_into ( ) ?;
554+ let alloy_block: AnyBlock = self . try_into ( ) ?;
482555
483556 let transaction_receipts = self
484557 . transaction_traces
@@ -494,7 +567,7 @@ impl TryInto<EthereumBlockWithCalls> for &Block {
494567 #[ allow( unreachable_code) ]
495568 let block = EthereumBlockWithCalls {
496569 ethereum_block : EthereumBlock {
497- block : Arc :: new ( LightEthereumBlock :: new ( alloy_block. into ( ) ) ) ,
570+ block : Arc :: new ( LightEthereumBlock :: new ( alloy_block) ) ,
498571 transaction_receipts,
499572 } ,
500573 // Comment (437a9f17-67cc-478f-80a3-804fe554b227): This Some() will avoid calls in the triggers_in_block
@@ -521,7 +594,7 @@ impl TryInto<EthereumBlockWithCalls> for &Block {
521594fn transaction_trace_to_alloy_txn_reciept (
522595 t : & TransactionTrace ,
523596 block : & Block ,
524- ) -> Result < Option < AlloyTransactionReceipt < ReceiptEnvelope < alloy:: rpc :: types :: Log > > > , Error > {
597+ ) -> Result < Option < alloy:: network :: AnyTransactionReceipt > , Error > {
525598 use alloy:: consensus:: { Eip658Value , Receipt } ;
526599 let r = t. receipt . as_ref ( ) ;
527600
@@ -588,27 +661,19 @@ fn transaction_trace_to_alloy_txn_reciept(
588661
589662 let receipt_with_bloom = ReceiptWithBloom :: new ( core_receipt, logs_bloom) ;
590663
591- let tx_type = TxType :: try_from ( u64:: try_from ( t. r#type ) . map_err ( |_| {
664+ let tx_type_u64 = u64:: try_from ( t. r#type ) . map_err ( |_| {
592665 format_err ! (
593666 "Invalid transaction type value {} in transaction receipt. Transaction type must be a valid u64." ,
594667 t. r#type
595668 )
596- } ) ?) . map_err ( |_| {
597- format_err ! (
598- "Unsupported transaction type {} in transaction receipt. Only standard Ethereum transaction types (Legacy=0, EIP-2930=1, EIP-1559=2, EIP-4844=3, EIP-7702=4) are supported." ,
599- t. r#type
600- )
601669 } ) ?;
602670
603- let envelope = match tx_type {
604- TxType :: Legacy => ReceiptEnvelope :: Legacy ( receipt_with_bloom) ,
605- TxType :: Eip2930 => ReceiptEnvelope :: Eip2930 ( receipt_with_bloom) ,
606- TxType :: Eip1559 => ReceiptEnvelope :: Eip1559 ( receipt_with_bloom) ,
607- TxType :: Eip4844 => ReceiptEnvelope :: Eip4844 ( receipt_with_bloom) ,
608- TxType :: Eip7702 => ReceiptEnvelope :: Eip7702 ( receipt_with_bloom) ,
671+ let any_envelope = AnyReceiptEnvelope {
672+ inner : receipt_with_bloom,
673+ r#type : tx_type_u64 as u8 ,
609674 } ;
610675
611- Ok ( Some ( AlloyTransactionReceipt {
676+ let receipt = alloy_rpc_types :: TransactionReceipt {
612677 transaction_hash : t. hash . try_decode_proto ( "transaction hash" ) ?,
613678 transaction_index : Some ( t. index as u64 ) ,
614679 block_hash : Some ( block. hash . try_decode_proto ( "transaction block hash" ) ?) ,
@@ -626,8 +691,10 @@ fn transaction_trace_to_alloy_txn_reciept(
626691 let val: U256 = x. into ( ) ;
627692 val. to :: < u128 > ( )
628693 } ) ,
629- inner : envelope,
630- } ) )
694+ inner : any_envelope,
695+ } ;
696+
697+ Ok ( Some ( WithOtherFields :: new ( receipt) ) )
631698}
632699
633700impl BlockHeader {
0 commit comments