@@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
3
3
use stable_hash:: prelude:: * ;
4
4
use stable_hash:: utils:: AsBytes ;
5
5
use std:: cmp:: Ordering ;
6
+ use std:: convert:: TryFrom ;
6
7
use std:: fmt;
7
8
use web3:: types:: * ;
8
9
@@ -56,6 +57,15 @@ impl LightEthereumBlockExt for LightEthereumBlock {
56
57
}
57
58
}
58
59
60
+ impl < ' a > From < & ' a EthereumBlockType > for LightEthereumBlock {
61
+ fn from ( block : & ' a EthereumBlockType ) -> LightEthereumBlock {
62
+ match block {
63
+ EthereumBlockType :: Full ( block) => block. block . clone ( ) ,
64
+ EthereumBlockType :: Light ( block) => block. clone ( ) ,
65
+ }
66
+ }
67
+ }
68
+
59
69
/// This is used in `EthereumAdapter::triggers_in_block`, called when re-processing a block for
60
70
/// newly created data sources. This allows the re-processing to be reorg safe without having to
61
71
/// always fetch the full block data.
@@ -193,9 +203,37 @@ impl PartialEq for EthereumTrigger {
193
203
194
204
impl Eq for EthereumTrigger { }
195
205
206
+ /// This is used in `EthereumAdapter::triggers_in_block`, called when re-processing a block for
207
+ /// newly created data sources. This allows the re-processing to be reorg safe without having to
208
+ /// always fetch the full block data.
209
+ #[ derive( Clone , Debug ) ]
210
+ pub enum EthereumBlockType {
211
+ Light ( LightEthereumBlock ) ,
212
+
213
+ Full ( EthereumBlock ) ,
214
+ }
215
+
216
+ impl Default for EthereumBlockType {
217
+ fn default ( ) -> Self {
218
+ EthereumBlockType :: Light ( LightEthereumBlock :: default ( ) )
219
+ }
220
+ }
221
+
222
+ impl < ' a > From < & ' a LightEthereumBlock > for EthereumBlockType {
223
+ fn from ( block : & ' a LightEthereumBlock ) -> EthereumBlockType {
224
+ EthereumBlockType :: Light ( block. clone ( ) )
225
+ }
226
+ }
227
+
228
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
229
+ pub enum BlockType {
230
+ Light ,
231
+ Full ,
232
+ }
233
+
196
234
#[ derive( Clone , Debug , PartialEq , Eq ) ]
197
235
pub enum EthereumBlockTriggerType {
198
- Every ,
236
+ Every ( BlockType ) ,
199
237
WithCallTo ( Address ) ,
200
238
}
201
239
@@ -263,6 +301,158 @@ impl PartialOrd for EthereumTrigger {
263
301
}
264
302
}
265
303
304
+ pub struct EthereumTransactionReceiptData {
305
+ // from receipts
306
+ pub transaction_hash : H256 ,
307
+ pub transaction_index : Index ,
308
+ pub cumulative_gas_used : U256 ,
309
+ pub gas_used : Option < U256 > ,
310
+ pub contract_address : Option < H160 > ,
311
+ pub status : Option < U64 > ,
312
+ pub root : Option < H256 > ,
313
+
314
+ // from txs
315
+ pub from : H160 ,
316
+ pub to : Option < H160 > ,
317
+ pub value : U256 ,
318
+ pub gas_price : U256 ,
319
+ pub gas : U256 ,
320
+ pub input : Bytes ,
321
+ }
322
+
323
+ pub struct FullEthereumBlockData {
324
+ pub hash : H256 ,
325
+ pub parent_hash : H256 ,
326
+ pub uncles_hash : H256 ,
327
+ pub author : H160 ,
328
+ pub state_root : H256 ,
329
+ pub transactions_root : H256 ,
330
+ pub receipts_root : H256 ,
331
+ pub number : U64 ,
332
+ pub gas_used : U256 ,
333
+ pub gas_limit : U256 ,
334
+ pub timestamp : U256 ,
335
+ pub difficulty : U256 ,
336
+ pub total_difficulty : U256 ,
337
+ pub size : Option < U256 > ,
338
+ pub transaction_receipts : Vec < EthereumTransactionReceiptData > ,
339
+ }
340
+
341
+ impl < ' a > TryFrom < & ' a EthereumBlockType > for FullEthereumBlockData {
342
+ type Error = String ;
343
+
344
+ fn try_from ( block : & ' a EthereumBlockType ) -> Result < FullEthereumBlockData , Self :: Error > {
345
+ let fullblock = match block {
346
+ EthereumBlockType :: Full ( full_block) => full_block,
347
+ EthereumBlockType :: Light ( _) => return Err ( format ! (
348
+ "Failed to convert EthereumBlockType to FUllEthereumBlockData, requires a EthereumBlockType::Full()"
349
+ ) )
350
+ } ;
351
+ let block = & fullblock. block ;
352
+ let transaction_receipts_data = block
353
+ . transactions
354
+ . iter ( )
355
+ . cloned ( )
356
+ . zip ( fullblock. transaction_receipts . iter ( ) . cloned ( ) )
357
+ . map ( |transaction_and_receipt| {
358
+ assert_eq ! (
359
+ transaction_and_receipt. 0 . hash,
360
+ transaction_and_receipt. 1 . transaction_hash
361
+ ) ;
362
+ EthereumTransactionReceiptData {
363
+ transaction_hash : transaction_and_receipt. 0 . hash ,
364
+ transaction_index : transaction_and_receipt. 1 . transaction_index ,
365
+ cumulative_gas_used : transaction_and_receipt. 1 . cumulative_gas_used ,
366
+ gas_used : transaction_and_receipt. 1 . gas_used ,
367
+ contract_address : transaction_and_receipt. 1 . contract_address ,
368
+ status : transaction_and_receipt. 1 . status ,
369
+ root : transaction_and_receipt. 1 . root ,
370
+
371
+ // from txs
372
+ from : transaction_and_receipt. 0 . from ,
373
+ to : transaction_and_receipt. 0 . to ,
374
+ value : transaction_and_receipt. 0 . value ,
375
+ gas_price : transaction_and_receipt. 0 . gas_price ,
376
+ gas : transaction_and_receipt. 0 . gas ,
377
+ input : transaction_and_receipt. 0 . input ,
378
+ }
379
+ } )
380
+ . collect :: < Vec < EthereumTransactionReceiptData > > ( ) ;
381
+
382
+ Ok ( FullEthereumBlockData {
383
+ hash : block. hash . unwrap ( ) ,
384
+ parent_hash : block. parent_hash ,
385
+ uncles_hash : block. uncles_hash ,
386
+ author : block. author ,
387
+ state_root : block. state_root ,
388
+ transactions_root : block. transactions_root ,
389
+ receipts_root : block. receipts_root ,
390
+ number : block. number . unwrap ( ) ,
391
+ gas_used : block. gas_used ,
392
+ gas_limit : block. gas_limit ,
393
+ timestamp : block. timestamp ,
394
+ difficulty : block. difficulty ,
395
+ total_difficulty : block. total_difficulty . unwrap_or_default ( ) ,
396
+ size : block. size ,
397
+ transaction_receipts : transaction_receipts_data,
398
+ } )
399
+ }
400
+ }
401
+
402
+ impl < ' a > From < & ' a EthereumBlock > for FullEthereumBlockData {
403
+ fn from ( block : & ' a EthereumBlock ) -> FullEthereumBlockData {
404
+ let transaction_receipts_data = block
405
+ . block
406
+ . transactions
407
+ . iter ( )
408
+ . cloned ( )
409
+ . zip ( block. transaction_receipts . iter ( ) . cloned ( ) )
410
+ . map ( |transaction_and_receipt| {
411
+ assert_eq ! (
412
+ transaction_and_receipt. 0 . hash,
413
+ transaction_and_receipt. 1 . transaction_hash
414
+ ) ;
415
+ EthereumTransactionReceiptData {
416
+ transaction_hash : transaction_and_receipt. 0 . hash ,
417
+ transaction_index : transaction_and_receipt. 1 . transaction_index ,
418
+ cumulative_gas_used : transaction_and_receipt. 1 . cumulative_gas_used ,
419
+ gas_used : transaction_and_receipt. 1 . gas_used ,
420
+ contract_address : transaction_and_receipt. 1 . contract_address ,
421
+ status : transaction_and_receipt. 1 . status ,
422
+ root : transaction_and_receipt. 1 . root ,
423
+
424
+ // from txs
425
+ from : transaction_and_receipt. 0 . from ,
426
+ to : transaction_and_receipt. 0 . to ,
427
+ value : transaction_and_receipt. 0 . value ,
428
+ gas_price : transaction_and_receipt. 0 . gas_price ,
429
+ gas : transaction_and_receipt. 0 . gas ,
430
+ input : transaction_and_receipt. 0 . input ,
431
+ }
432
+ } )
433
+ . collect :: < Vec < EthereumTransactionReceiptData > > ( ) ;
434
+ let block = & block. block ;
435
+
436
+ FullEthereumBlockData {
437
+ hash : block. hash . unwrap ( ) ,
438
+ parent_hash : block. parent_hash ,
439
+ uncles_hash : block. uncles_hash ,
440
+ author : block. author ,
441
+ state_root : block. state_root ,
442
+ transactions_root : block. transactions_root ,
443
+ receipts_root : block. receipts_root ,
444
+ number : block. number . unwrap ( ) ,
445
+ gas_used : block. gas_used ,
446
+ gas_limit : block. gas_limit ,
447
+ timestamp : block. timestamp ,
448
+ difficulty : block. difficulty ,
449
+ total_difficulty : block. total_difficulty . unwrap_or_default ( ) ,
450
+ size : block. size ,
451
+ transaction_receipts : transaction_receipts_data,
452
+ }
453
+ }
454
+ }
455
+
266
456
/// Ethereum block data.
267
457
#[ derive( Clone , Debug , Default ) ]
268
458
pub struct EthereumBlockData {
@@ -303,6 +493,32 @@ impl<'a, T> From<&'a Block<T>> for EthereumBlockData {
303
493
}
304
494
}
305
495
496
+ impl < ' a > From < & ' a EthereumBlockType > for EthereumBlockData {
497
+ fn from ( block : & ' a EthereumBlockType ) -> EthereumBlockData {
498
+ let block = match block {
499
+ EthereumBlockType :: Full ( full_block) => & full_block. block ,
500
+ EthereumBlockType :: Light ( light_block) => light_block,
501
+ } ;
502
+
503
+ EthereumBlockData {
504
+ hash : block. hash . unwrap ( ) ,
505
+ parent_hash : block. parent_hash ,
506
+ uncles_hash : block. uncles_hash ,
507
+ author : block. author ,
508
+ state_root : block. state_root ,
509
+ transactions_root : block. transactions_root ,
510
+ receipts_root : block. receipts_root ,
511
+ number : block. number . unwrap ( ) ,
512
+ gas_used : block. gas_used ,
513
+ gas_limit : block. gas_limit ,
514
+ timestamp : block. timestamp ,
515
+ difficulty : block. difficulty ,
516
+ total_difficulty : block. total_difficulty . unwrap_or_default ( ) ,
517
+ size : block. size ,
518
+ }
519
+ }
520
+ }
521
+
306
522
/// Ethereum transaction data.
307
523
#[ derive( Clone , Debug ) ]
308
524
pub struct EthereumTransactionData {
@@ -536,7 +752,9 @@ impl ToEntityKey for EthereumBlockPointer {
536
752
537
753
#[ cfg( test) ]
538
754
mod test {
539
- use super :: { EthereumBlockPointer , EthereumBlockTriggerType , EthereumCall , EthereumTrigger } ;
755
+ use super :: {
756
+ BlockType , EthereumBlockPointer , EthereumBlockTriggerType , EthereumCall , EthereumTrigger ,
757
+ } ;
540
758
use web3:: types:: * ;
541
759
542
760
#[ test]
@@ -546,7 +764,7 @@ mod test {
546
764
number : 1 ,
547
765
hash : H256 :: random ( ) ,
548
766
} ,
549
- EthereumBlockTriggerType :: Every ,
767
+ EthereumBlockTriggerType :: Every ( BlockType :: Light ) ,
550
768
) ;
551
769
552
770
let block2 = EthereumTrigger :: Block (
0 commit comments