@@ -5,6 +5,7 @@ use ssz::{Decode, DecodeError, Encode};
5
5
use ssz_types:: { typenum:: U128 , VariableList } ;
6
6
7
7
use crate :: {
8
+ consensus:: historical_summaries:: { HistoricalSummaries , HistoricalSummariesWithProofElectra } ,
8
9
light_client:: {
9
10
bootstrap:: { LightClientBootstrapDeneb , LightClientBootstrapElectra } ,
10
11
finality_update:: { LightClientFinalityUpdateDeneb , LightClientFinalityUpdateElectra } ,
@@ -14,7 +15,7 @@ use crate::{
14
15
types:: {
15
16
consensus:: {
16
17
fork:: { ForkDigest , ForkName } ,
17
- historical_summaries:: HistoricalSummariesWithProof ,
18
+ historical_summaries:: HistoricalSummariesWithProofDeneb ,
18
19
light_client:: {
19
20
bootstrap:: {
20
21
LightClientBootstrap , LightClientBootstrapBellatrix ,
@@ -477,57 +478,116 @@ impl Encode for ForkVersionedLightClientFinalityUpdate {
477
478
478
479
/// A wrapper type including a `ForkName` and `HistoricalSummariesWithProof`
479
480
#[ derive( Clone , Debug , PartialEq ) ]
480
- pub struct ForkVersionedHistoricalSummariesWithProof {
481
- pub fork_name : ForkName ,
482
- pub historical_summaries_with_proof : HistoricalSummariesWithProof ,
481
+ pub enum ForkVersionedHistoricalSummariesWithProof {
482
+ Deneb ( HistoricalSummariesWithProofDeneb ) ,
483
+ Electra ( HistoricalSummariesWithProofElectra ) ,
483
484
}
484
485
485
486
impl ForkVersionedHistoricalSummariesWithProof {
486
- pub fn encode ( & self ) -> Vec < u8 > {
487
- let fork_digest = self . fork_name . as_fork_digest ( ) ;
488
-
489
- let mut data = fork_digest. to_vec ( ) ;
490
- data. extend ( self . historical_summaries_with_proof . as_ssz_bytes ( ) ) ;
491
- data
487
+ pub fn epoch ( & self ) -> u64 {
488
+ match self {
489
+ Self :: Deneb ( historical_summaries_with_proof) => historical_summaries_with_proof. epoch ,
490
+ Self :: Electra ( historical_summaries_with_proof) => historical_summaries_with_proof. epoch ,
491
+ }
492
492
}
493
493
494
- pub fn decode ( buf : & [ u8 ] ) -> Result < Self , DecodeError > {
495
- let fork_digest = ForkDigest :: try_from ( & buf[ 0 ..4 ] ) . map_err ( |err| {
496
- DecodeError :: BytesInvalid ( format ! ( "Unable to decode fork digest: {err:?}" ) )
497
- } ) ?;
498
- let fork_name = ForkName :: try_from ( fork_digest) . map_err ( |_| {
499
- DecodeError :: BytesInvalid ( format ! ( "Unable to decode fork name: {fork_digest:?}" ) )
500
- } ) ?;
501
- let summaries_with_proof = HistoricalSummariesWithProof :: from_ssz_bytes ( & buf[ 4 ..] ) ?;
494
+ pub fn fork_name ( & self ) -> ForkName {
495
+ match self {
496
+ Self :: Deneb ( _) => ForkName :: Deneb ,
497
+ Self :: Electra ( _) => ForkName :: Electra ,
498
+ }
499
+ }
500
+ }
502
501
503
- Ok ( Self {
504
- fork_name,
505
- historical_summaries_with_proof : summaries_with_proof,
506
- } )
502
+ impl From < ForkVersionedHistoricalSummariesWithProof > for HistoricalSummaries {
503
+ fn from ( historical_summaries_with_proof : ForkVersionedHistoricalSummariesWithProof ) -> Self {
504
+ match historical_summaries_with_proof {
505
+ ForkVersionedHistoricalSummariesWithProof :: Deneb ( historical_summaries_with_proof) => {
506
+ historical_summaries_with_proof. historical_summaries
507
+ }
508
+ ForkVersionedHistoricalSummariesWithProof :: Electra ( historical_summaries_with_proof) => {
509
+ historical_summaries_with_proof. historical_summaries
510
+ }
511
+ }
507
512
}
508
513
}
509
514
510
- impl Decode for ForkVersionedHistoricalSummariesWithProof {
515
+ impl Encode for ForkVersionedHistoricalSummariesWithProof {
511
516
fn is_ssz_fixed_len ( ) -> bool {
512
517
false
513
518
}
514
519
515
- fn from_ssz_bytes ( bytes : & [ u8 ] ) -> Result < Self , DecodeError > {
516
- Self :: decode ( bytes)
520
+ fn ssz_append ( & self , buf : & mut Vec < u8 > ) {
521
+ self . fork_name ( ) . as_fork_digest ( ) . ssz_append ( buf) ;
522
+ match self {
523
+ Self :: Deneb ( historical_summaries_with_proof) => {
524
+ historical_summaries_with_proof. ssz_append ( buf)
525
+ }
526
+ Self :: Electra ( historical_summaries_with_proof) => {
527
+ historical_summaries_with_proof. ssz_append ( buf)
528
+ }
529
+ }
530
+ }
531
+
532
+ fn ssz_fixed_len ( ) -> usize {
533
+ ssz:: BYTES_PER_LENGTH_OFFSET
534
+ }
535
+
536
+ fn ssz_bytes_len ( & self ) -> usize {
537
+ let fork_digest_len = self . fork_name ( ) . as_fork_digest ( ) . ssz_bytes_len ( ) ;
538
+ let historical_summaries_with_proof_len = match self {
539
+ Self :: Deneb ( historical_summaries_with_proof) => {
540
+ historical_summaries_with_proof. ssz_bytes_len ( )
541
+ }
542
+ Self :: Electra ( historical_summaries_with_proof) => {
543
+ historical_summaries_with_proof. ssz_bytes_len ( )
544
+ }
545
+ } ;
546
+ fork_digest_len + historical_summaries_with_proof_len
517
547
}
518
548
}
519
549
520
- impl Encode for ForkVersionedHistoricalSummariesWithProof {
550
+ impl Decode for ForkVersionedHistoricalSummariesWithProof {
521
551
fn is_ssz_fixed_len ( ) -> bool {
522
552
false
523
553
}
524
554
525
- fn ssz_append ( & self , buf : & mut Vec < u8 > ) {
526
- buf . extend_from_slice ( & self . encode ( ) ) ;
555
+ fn ssz_fixed_len ( ) -> usize {
556
+ ssz :: BYTES_PER_LENGTH_OFFSET
527
557
}
528
558
529
- fn ssz_bytes_len ( & self ) -> usize {
530
- self . encode ( ) . len ( )
559
+ fn from_ssz_bytes ( bytes : & [ u8 ] ) -> Result < Self , DecodeError > {
560
+ let fork_digest_len = <ForkDigest as Decode >:: ssz_fixed_len ( ) ;
561
+ let Some ( ( fork_digest_bytes, historical_summaries_with_proof_bytes) ) =
562
+ bytes. split_at_checked ( fork_digest_len)
563
+ else {
564
+ return Err ( DecodeError :: InvalidByteLength {
565
+ len : bytes. len ( ) ,
566
+ expected : fork_digest_len,
567
+ } ) ;
568
+ } ;
569
+
570
+ let fork_digest = ForkDigest :: from_ssz_bytes ( fork_digest_bytes) ?;
571
+ let fork_name = match ForkName :: try_from ( fork_digest) {
572
+ Ok ( fork_name) => fork_name,
573
+ Err ( err) => return Err ( DecodeError :: BytesInvalid ( err. to_string ( ) ) ) ,
574
+ } ;
575
+
576
+ match fork_name {
577
+ ForkName :: Bellatrix | ForkName :: Capella => Err ( DecodeError :: BytesInvalid ( format ! (
578
+ "HistoricalSummariesWithProof not supported for fork digest: {fork_digest:?}"
579
+ ) ) ) ,
580
+ ForkName :: Deneb => Ok ( Self :: Deneb (
581
+ HistoricalSummariesWithProofDeneb :: from_ssz_bytes (
582
+ historical_summaries_with_proof_bytes,
583
+ ) ?,
584
+ ) ) ,
585
+ ForkName :: Electra => Ok ( Self :: Electra (
586
+ HistoricalSummariesWithProofElectra :: from_ssz_bytes (
587
+ historical_summaries_with_proof_bytes,
588
+ ) ?,
589
+ ) ) ,
590
+ }
531
591
}
532
592
}
533
593
@@ -710,11 +770,15 @@ mod test {
710
770
711
771
match & beacon_content {
712
772
BeaconContentValue :: HistoricalSummariesWithProof ( content) => {
713
- assert_eq ! (
714
- expected_epoch,
715
- content. historical_summaries_with_proof. epoch
716
- ) ;
717
- assert_eq ! ( ForkName :: Deneb , content. fork_name) ;
773
+ assert_eq ! ( ForkName :: Deneb , content. fork_name( ) ) ;
774
+
775
+ let ForkVersionedHistoricalSummariesWithProof :: Deneb (
776
+ historical_summaries_with_proof,
777
+ ) = content
778
+ else {
779
+ panic ! ( "Expected Deneb historical summaries, actual: {content:?}" ) ;
780
+ } ;
781
+ assert_eq ! ( expected_epoch, historical_summaries_with_proof. epoch) ;
718
782
}
719
783
_ => panic ! ( "Invalid beacon content type!" ) ,
720
784
}
0 commit comments