@@ -7,15 +7,15 @@ use graph::{
7
7
blockchain:: {
8
8
self , Block as BlockchainBlock , BlockPtr , BlockTime , ChainStoreBlock , ChainStoreData ,
9
9
} ,
10
+ components:: ethereum:: { AnyBlock , AnyHeader , AnyRpcHeader , AnyRpcTransaction , AnyTxEnvelope } ,
10
11
prelude:: {
11
12
alloy:: {
12
13
self ,
13
- consensus:: { ReceiptEnvelope , ReceiptWithBloom , TxEnvelope , TxType } ,
14
+ consensus:: { ReceiptWithBloom , TxEnvelope , TxType } ,
15
+ network:: AnyReceiptEnvelope ,
14
16
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 ,
19
19
} ,
20
20
BlockNumber , Error , EthereumBlock , EthereumBlockWithCalls , EthereumCall ,
21
21
LightEthereumBlock ,
@@ -142,18 +142,21 @@ impl<'a> TransactionTraceAt<'a> {
142
142
}
143
143
}
144
144
145
- impl < ' a > TryInto < Transaction > for TransactionTraceAt < ' a > {
145
+ impl < ' a > TryInto < Transaction < AnyTxEnvelope > > for TransactionTraceAt < ' a > {
146
146
type Error = Error ;
147
147
148
- fn try_into ( self ) -> Result < Transaction , Self :: Error > {
148
+ fn try_into ( self ) -> Result < Transaction < AnyTxEnvelope > , Self :: Error > {
149
149
use alloy:: {
150
150
consensus:: transaction:: Recovered ,
151
151
consensus:: {
152
152
Signed , TxEip1559 , TxEip2930 , TxEip4844 , TxEip4844Variant , TxEip7702 , TxLegacy ,
153
153
} ,
154
+ network:: { AnyTxEnvelope , AnyTxType , UnknownTxEnvelope , UnknownTypedTransaction } ,
154
155
primitives:: { Bytes , TxKind , U256 } ,
155
156
rpc:: types:: Transaction as AlloyTransaction ,
157
+ serde:: OtherFields ,
156
158
} ;
159
+ use std:: collections:: BTreeMap ;
157
160
158
161
// Extract data from trace and block
159
162
let block_hash = self . block . hash . try_decode_proto ( "transaction block hash" ) ?;
@@ -172,20 +175,77 @@ impl<'a> TryInto<Transaction> for TransactionTraceAt<'a> {
172
175
let gas_limit = self . trace . gas_limit ;
173
176
let input = Bytes :: from ( self . trace . input . clone ( ) ) ;
174
177
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 ( |_| {
176
179
format_err ! (
177
180
"Invalid transaction type value {} in transaction trace. Transaction type must be a valid u64." ,
178
181
self . trace. r#type
179
182
)
180
183
} ) ?;
181
184
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
+ }
188
247
248
+ let tx_type = tx_type_result. unwrap ( ) ;
189
249
let nonce = self . trace . nonce ;
190
250
191
251
// Extract EIP-1559 fee fields from trace
@@ -358,7 +418,8 @@ impl<'a> TryInto<Transaction> for TransactionTraceAt<'a> {
358
418
}
359
419
} ;
360
420
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) ;
362
423
363
424
Ok ( AlloyTransaction {
364
425
inner : recovered,
@@ -378,10 +439,10 @@ impl TryInto<BlockFinality> for &Block {
378
439
}
379
440
}
380
441
381
- impl TryInto < AlloyBlock > for & Block {
442
+ impl TryInto < AnyBlock > for & Block {
382
443
type Error = Error ;
383
444
384
- fn try_into ( self ) -> Result < AlloyBlock , Self :: Error > {
445
+ fn try_into ( self ) -> Result < AnyBlock , Self :: Error > {
385
446
let header = self . header ( ) ;
386
447
387
448
let block_hash = self . hash . try_decode_proto ( "block hash" ) ?;
@@ -458,27 +519,39 @@ impl TryInto<AlloyBlock> for &Block {
458
519
. transaction_traces
459
520
. iter ( )
460
521
. map ( |t| TransactionTraceAt :: new ( t, self ) . try_into ( ) )
461
- . collect :: < Result < Vec < Transaction > , Error > > ( ) ?;
522
+ . collect :: < Result < Vec < Transaction < AnyTxEnvelope > > , Error > > ( ) ?;
462
523
463
524
let uncles = self
464
525
. uncles
465
526
. iter ( )
466
527
. map ( |u| u. hash . try_decode_proto ( "uncle hash" ) )
467
528
. collect :: < Result < Vec < B256 > , _ > > ( ) ?;
468
529
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) ) )
474
547
}
475
548
}
476
549
477
550
impl TryInto < EthereumBlockWithCalls > for & Block {
478
551
type Error = Error ;
479
552
480
553
fn try_into ( self ) -> Result < EthereumBlockWithCalls , Self :: Error > {
481
- let alloy_block: AlloyBlock = self . try_into ( ) ?;
554
+ let alloy_block: AnyBlock = self . try_into ( ) ?;
482
555
483
556
let transaction_receipts = self
484
557
. transaction_traces
@@ -494,7 +567,7 @@ impl TryInto<EthereumBlockWithCalls> for &Block {
494
567
#[ allow( unreachable_code) ]
495
568
let block = EthereumBlockWithCalls {
496
569
ethereum_block : EthereumBlock {
497
- block : Arc :: new ( LightEthereumBlock :: new ( alloy_block. into ( ) ) ) ,
570
+ block : Arc :: new ( LightEthereumBlock :: new ( alloy_block) ) ,
498
571
transaction_receipts,
499
572
} ,
500
573
// 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 {
521
594
fn transaction_trace_to_alloy_txn_reciept (
522
595
t : & TransactionTrace ,
523
596
block : & Block ,
524
- ) -> Result < Option < AlloyTransactionReceipt < ReceiptEnvelope < alloy:: rpc :: types :: Log > > > , Error > {
597
+ ) -> Result < Option < alloy:: network :: AnyTransactionReceipt > , Error > {
525
598
use alloy:: consensus:: { Eip658Value , Receipt } ;
526
599
let r = t. receipt . as_ref ( ) ;
527
600
@@ -588,27 +661,19 @@ fn transaction_trace_to_alloy_txn_reciept(
588
661
589
662
let receipt_with_bloom = ReceiptWithBloom :: new ( core_receipt, logs_bloom) ;
590
663
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 ( |_| {
592
665
format_err ! (
593
666
"Invalid transaction type value {} in transaction receipt. Transaction type must be a valid u64." ,
594
667
t. r#type
595
668
)
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
- )
601
669
} ) ?;
602
670
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 ,
609
674
} ;
610
675
611
- Ok ( Some ( AlloyTransactionReceipt {
676
+ let receipt = alloy_rpc_types :: TransactionReceipt {
612
677
transaction_hash : t. hash . try_decode_proto ( "transaction hash" ) ?,
613
678
transaction_index : Some ( t. index as u64 ) ,
614
679
block_hash : Some ( block. hash . try_decode_proto ( "transaction block hash" ) ?) ,
@@ -626,8 +691,10 @@ fn transaction_trace_to_alloy_txn_reciept(
626
691
let val: U256 = x. into ( ) ;
627
692
val. to :: < u128 > ( )
628
693
} ) ,
629
- inner : envelope,
630
- } ) )
694
+ inner : any_envelope,
695
+ } ;
696
+
697
+ Ok ( Some ( WithOtherFields :: new ( receipt) ) )
631
698
}
632
699
633
700
impl BlockHeader {
0 commit comments