@@ -20,14 +20,15 @@ use crate::{
20
20
oracle:: HeaderOracle ,
21
21
} ;
22
22
23
- #[ derive( Debug , Clone ) ]
23
+ #[ derive( Debug , Default , Clone ) ]
24
24
pub enum HistoricalSummariesProvider {
25
25
/// The historical summaries are provided by the header oracle.
26
26
HeaderOracle ( Arc < RwLock < HeaderOracle > > ) ,
27
27
/// The historical summaries are provided by passed historical summaries.
28
28
HistoricalSummaries ( HistoricalSummaries ) ,
29
29
/// We don't have historical summaries, for example the E2HS bridge doesn't use a provider and
30
30
/// hence can't get HistoricalSummaries. HistoricalSummary proof validation will fail.
31
+ #[ default]
31
32
None ,
32
33
}
33
34
@@ -63,29 +64,33 @@ impl HistoricalSummariesProvider {
63
64
64
65
/// HeaderValidator is responsible for validating pre-merge and post-merge headers with their
65
66
/// respective proofs.
66
- #[ derive( Debug , Clone , PartialEq , Eq , Default ) ]
67
+ ///
68
+ /// Default can only be used for validating pre-capella headers.
69
+ #[ derive( Debug , Clone , Default ) ]
67
70
pub struct HeaderValidator {
68
71
/// Pre-merge accumulator used to validate pre-merge headers.
69
72
pub pre_merge_acc : PreMergeAccumulator ,
70
73
/// Historical roots accumulator used to validate post-merge/pre-Capella headers.
71
74
pub historical_roots_acc : HistoricalRootsAccumulator ,
75
+ /// Historical summaries provider used to validate post-Capella headers.
76
+ pub historical_summaries_provider : HistoricalSummariesProvider ,
72
77
}
73
78
74
79
impl HeaderValidator {
75
- pub fn new ( ) -> Self {
80
+ pub fn new ( historical_summaries_provider : HistoricalSummariesProvider ) -> Self {
76
81
let pre_merge_acc = PreMergeAccumulator :: default ( ) ;
77
82
let historical_roots_acc = HistoricalRootsAccumulator :: default ( ) ;
78
83
79
84
Self {
80
85
pre_merge_acc,
81
86
historical_roots_acc,
87
+ historical_summaries_provider,
82
88
}
83
89
}
84
90
85
91
pub async fn validate_header_with_proof (
86
92
& self ,
87
93
header_with_proof : & HeaderWithProof ,
88
- historical_summaries_provider : HistoricalSummariesProvider ,
89
94
) -> anyhow:: Result < ( ) > {
90
95
match & header_with_proof. proof {
91
96
BlockHeaderProof :: HistoricalHashes ( proof) => {
@@ -123,7 +128,6 @@ impl HeaderValidator {
123
128
header_with_proof. header . number ,
124
129
header_with_proof. header . hash_slow ( ) ,
125
130
proof,
126
- historical_summaries_provider,
127
131
)
128
132
. await
129
133
}
@@ -182,7 +186,6 @@ impl HeaderValidator {
182
186
block_number : u64 ,
183
187
header_hash : B256 ,
184
188
proof : & BlockProofHistoricalSummaries ,
185
- historical_summaries_provider : HistoricalSummariesProvider ,
186
189
) -> anyhow:: Result < ( ) > {
187
190
if block_number < SHANGHAI_BLOCK_NUMBER {
188
191
return Err ( anyhow ! (
@@ -202,7 +205,8 @@ impl HeaderValidator {
202
205
let historical_summary_index =
203
206
( proof. slot - CAPELLA_FORK_EPOCH * SLOTS_PER_EPOCH ) / EPOCH_SIZE ;
204
207
205
- let block_summary_root = historical_summaries_provider
208
+ let block_summary_root = self
209
+ . historical_summaries_provider
206
210
. get_historical_summary (
207
211
proof. slot / SLOTS_PER_EPOCH ,
208
212
historical_summary_index as usize ,
@@ -320,7 +324,6 @@ mod test {
320
324
. unwrap ( ) ;
321
325
let json: Value = serde_json:: from_str ( & file) . unwrap ( ) ;
322
326
let hwps = json. as_object ( ) . unwrap ( ) ;
323
- let header_validator = get_mainnet_header_validator ( ) ;
324
327
let obj = hwps. get ( & block_number. to_string ( ) ) . unwrap ( ) ;
325
328
// Validate content_key decodes
326
329
let raw_ck = obj. get ( "content_key" ) . unwrap ( ) . as_str ( ) . unwrap ( ) ;
@@ -340,17 +343,12 @@ mod test {
340
343
_ => panic ! ( "test reached invalid state" ) ,
341
344
} ;
342
345
assert_eq ! ( trin_proof, fluffy_proof) ;
343
- let hwp = HeaderWithProof {
346
+ let header_with_proof = HeaderWithProof {
344
347
header,
345
348
proof : BlockHeaderProof :: HistoricalHashes ( trin_proof) ,
346
349
} ;
347
- header_validator
348
- . validate_header_with_proof (
349
- & hwp,
350
- HistoricalSummariesProvider :: HeaderOracle ( Arc :: new ( RwLock :: new (
351
- HeaderOracle :: default ( ) ,
352
- ) ) ) ,
353
- )
350
+ HeaderValidator :: default ( )
351
+ . validate_header_with_proof ( & header_with_proof)
354
352
. await
355
353
. unwrap ( ) ;
356
354
}
@@ -374,46 +372,37 @@ mod test {
374
372
header,
375
373
proof : BlockHeaderProof :: HistoricalHashes ( proof) ,
376
374
} ;
377
- HeaderValidator :: new ( )
378
- . validate_header_with_proof (
379
- & header_with_proof,
380
- HistoricalSummariesProvider :: HeaderOracle ( Arc :: new ( RwLock :: new (
381
- HeaderOracle :: default ( ) ,
382
- ) ) ) ,
383
- )
375
+ HeaderValidator :: default ( )
376
+ . validate_header_with_proof ( & header_with_proof)
384
377
. await
385
378
. unwrap ( ) ;
386
- let encoded_hwp = hex_encode ( header_with_proof. as_ssz_bytes ( ) ) ;
379
+ let encoded_header_with_proof = hex_encode ( header_with_proof. as_ssz_bytes ( ) ) ;
387
380
388
- let hwp_test_vector = serde_yaml:: from_str :: < serde_yaml:: Value > (
381
+ let header_with_proof_test_vector = serde_yaml:: from_str :: < serde_yaml:: Value > (
389
382
& read_portal_spec_tests_file ( format ! (
390
383
"tests/mainnet/history/headers_with_proof/{block_number}.yaml" ,
391
384
) )
392
385
. unwrap ( ) ,
393
386
)
394
387
. unwrap ( ) ;
395
- let expected_hwp = hwp_test_vector[ "content_value" ] . as_str ( ) . unwrap ( ) ;
396
- assert_eq ! ( encoded_hwp, expected_hwp) ;
388
+ let expected_header_with_proof = header_with_proof_test_vector[ "content_value" ]
389
+ . as_str ( )
390
+ . unwrap ( ) ;
391
+ assert_eq ! ( encoded_header_with_proof, expected_header_with_proof) ;
397
392
}
398
393
399
394
#[ tokio:: test]
400
395
async fn invalidate_invalid_proofs ( ) {
401
- let header_validator = get_mainnet_header_validator ( ) ;
402
396
let header = get_header ( 1_000_001 ) ;
403
397
let epoch_accumulator = read_epoch_accumulator_122 ( ) ;
404
398
let mut proof = PreMergeAccumulator :: construct_proof ( & header, & epoch_accumulator) . unwrap ( ) ;
405
399
proof. swap ( 0 , 1 ) ;
406
- let hwp = HeaderWithProof {
400
+ let header_with_proof = HeaderWithProof {
407
401
header,
408
402
proof : BlockHeaderProof :: HistoricalHashes ( proof) ,
409
403
} ;
410
- assert ! ( header_validator
411
- . validate_header_with_proof(
412
- & hwp,
413
- HistoricalSummariesProvider :: HeaderOracle ( Arc :: new( RwLock :: new(
414
- HeaderOracle :: default ( ) ,
415
- ) ) ) ,
416
- )
404
+ assert ! ( HeaderValidator :: default ( )
405
+ . validate_header_with_proof( & header_with_proof)
417
406
. await
418
407
. unwrap_err( )
419
408
. to_string( )
@@ -423,27 +412,19 @@ mod test {
423
412
#[ tokio:: test]
424
413
#[ should_panic( expected = "Invalid proof type found for post-merge header." ) ]
425
414
async fn header_validator_invalidates_post_merge_header_with_accumulator_proof ( ) {
426
- let header_validator = get_mainnet_header_validator ( ) ;
427
415
let future_height = MERGE_BLOCK_NUMBER + 1 ;
428
416
let future_header = generate_random_header ( & future_height) ;
429
417
let future_hwp = HeaderWithProof {
430
418
header : future_header,
431
419
proof : BlockHeaderProof :: HistoricalHashes ( Default :: default ( ) ) ,
432
420
} ;
433
- header_validator
434
- . validate_header_with_proof (
435
- & future_hwp,
436
- HistoricalSummariesProvider :: HeaderOracle ( Arc :: new ( RwLock :: new (
437
- HeaderOracle :: default ( ) ,
438
- ) ) ) ,
439
- )
421
+ HeaderValidator :: default ( )
422
+ . validate_header_with_proof ( & future_hwp)
440
423
. await
441
424
. unwrap ( ) ;
442
425
}
443
426
#[ tokio:: test]
444
427
async fn header_validator_validate_post_merge_pre_capella_header ( ) {
445
- let header_validator = get_mainnet_header_validator ( ) ;
446
-
447
428
// Read the historical roots block proof from a test file
448
429
let file = read_portal_spec_tests_file ( PathBuf :: from ( SPEC_TESTS_DIR ) . join (
449
430
"headers_with_proof/block_proofs_bellatrix/beacon_block_proof-15539558-cdf9ed89b0c43cda17398dc4da9cfc505e5ccd19f7c39e3b43474180f1051e01.yaml" ,
@@ -460,6 +441,7 @@ mod test {
460
441
let historical_roots_block_proof: BlockProofHistoricalRoots =
461
442
serde_yaml:: from_value ( value) . unwrap ( ) ;
462
443
444
+ let header_validator = HeaderValidator :: default ( ) ;
463
445
header_validator
464
446
. verify_historical_roots ( block_number, header_hash, & historical_roots_block_proof)
465
447
. unwrap ( ) ;
@@ -486,8 +468,6 @@ mod test {
486
468
#[ case( 17062257 ) ]
487
469
#[ tokio:: test]
488
470
async fn header_validator_validate_post_capella_header ( #[ case] block_number : u64 ) {
489
- let header_validator = get_mainnet_header_validator ( ) ;
490
-
491
471
// Read the historical roots block proof from a test file
492
472
let file = read_portal_spec_tests_file ( PathBuf :: from ( SPEC_TESTS_DIR ) . join ( format ! (
493
473
"headers_with_proof/block_proofs_capella/beacon_block_proof-{block_number}.yaml"
@@ -512,12 +492,15 @@ mod test {
512
492
let historical_summaries = HistoricalSummaries :: from_ssz_bytes ( & historical_summaries_bytes)
513
493
. expect ( "cannot decode HistoricalSummaries bytes" ) ;
514
494
495
+ let header_validator = HeaderValidator :: new (
496
+ HistoricalSummariesProvider :: HistoricalSummaries ( historical_summaries) ,
497
+ ) ;
498
+
515
499
header_validator
516
500
. verify_historical_summaries (
517
501
block_number,
518
502
header_hash,
519
503
& historical_summaries_block_proof,
520
- HistoricalSummariesProvider :: HistoricalSummaries ( historical_summaries. clone ( ) ) ,
521
504
)
522
505
. await
523
506
. unwrap ( ) ;
@@ -528,24 +511,11 @@ mod test {
528
511
SHANGHAI_BLOCK_NUMBER - 1 ,
529
512
header_hash,
530
513
& historical_summaries_block_proof,
531
- HistoricalSummariesProvider :: HistoricalSummaries ( historical_summaries) ,
532
514
)
533
515
. await ;
534
516
assert ! ( validator_result. is_err( ) ) ;
535
517
}
536
518
537
- //
538
- // Testing utils
539
- //
540
- fn get_mainnet_header_validator ( ) -> HeaderValidator {
541
- let header_validator = HeaderValidator :: default ( ) ;
542
- assert_eq ! (
543
- header_validator. pre_merge_acc. tree_hash_root( ) ,
544
- B256 :: from_str( DEFAULT_PRE_MERGE_ACC_HASH ) . unwrap( )
545
- ) ;
546
- header_validator
547
- }
548
-
549
519
pub ( crate ) fn get_header ( number : u64 ) -> Header {
550
520
let file = fs:: read_to_string ( "./src/assets/header_rlps.json" ) . unwrap ( ) ;
551
521
let json: Value = serde_json:: from_str ( & file) . unwrap ( ) ;
@@ -581,9 +551,8 @@ mod test {
581
551
582
552
#[ tokio:: test]
583
553
async fn header_oracle_bootstraps_with_default_pre_merge_acc ( ) {
584
- let header_validator = HeaderValidator :: default ( ) ;
585
554
assert_eq ! (
586
- header_validator . pre_merge_acc. tree_hash_root( ) ,
555
+ HeaderValidator :: default ( ) . pre_merge_acc. tree_hash_root( ) ,
587
556
B256 :: from_str( DEFAULT_PRE_MERGE_ACC_HASH ) . unwrap( ) ,
588
557
) ;
589
558
}
0 commit comments