@@ -2,7 +2,7 @@ use std::collections::HashSet;
22
33use crate :: {
44 helpers:: { EthHex , from_0x_hex_str} ,
5- operator:: { Operator , OperatorV1X1 , OperatorV1X2OrLater } ,
5+ operator:: { Operator , OperatorSSZ , OperatorV1X1 , OperatorV1X2OrLater } ,
66 version:: { CURRENT_VERSION , DKG_ALGO , versions:: * } ,
77} ;
88use charon_eth2:: enr:: { Record , RecordError } ;
@@ -15,6 +15,7 @@ use serde_with::{
1515 base64:: { Base64 , Standard } ,
1616 serde_as,
1717} ;
18+ use ssz_derive:: { Decode , Encode } ;
1819use uuid:: Uuid ;
1920
2021/// Length of the fork version in bytes.
@@ -463,6 +464,129 @@ impl Definition {
463464 }
464465}
465466
467+ #[ derive( Debug , Clone , PartialEq , Eq , Encode , Decode ) ]
468+ pub ( crate ) struct DefinitionSSZ {
469+ /// Human-readable random unique identifier. Max 64 chars.
470+ pub uuid : Vec < u8 > ,
471+ /// Human-readable cosmetic identifier. Max 256 chars.
472+ pub name : Vec < u8 > ,
473+ /// Schema version of this definition. Max 16 chars.
474+ pub version : Vec < u8 > ,
475+ /// Human-readable timestamp of this definition. Max 32
476+ /// chars. Note that this was added in v1.1.0, so may be empty for older
477+ /// versions.
478+ pub timestamp : Vec < u8 > ,
479+ /// Number of DVs to be created in the cluster lock
480+ /// file.
481+ pub num_validators : u64 ,
482+ /// Threshold required for signature reconstruction. Defaults to safe value
483+ /// for number of nodes/peers.
484+ pub threshold : u64 ,
485+ /// DKG algorithm to use for key generation. Max 32 chars.
486+ pub dkg_algorithm : Vec < u8 > ,
487+ /// Cluster's 4 byte beacon chain fork version
488+ /// (network/chain identifier).
489+ pub fork_version : [ u8 ; 4 ] ,
490+ /// Charon nodes in the cluster and their operators.
491+ /// Max 256 operators.
492+ pub operators : Vec < OperatorSSZ > ,
493+ /// Creator identifies the creator of a cluster definition. They may also be
494+ /// an operator.
495+ pub creator : CreatorSSZ ,
496+ /// Addresses of each validator.
497+ pub validator_addresses : Vec < ValidatorAddressesSSZ > ,
498+ /// Partial deposit amounts that sum up to at least
499+ /// 32ETH.
500+ /// todo: check type
501+ pub deposit_amounts : Vec < u64 > ,
502+ /// Consensus protocol name preferred by the
503+ /// cluster, e.g. "abft".
504+ pub consensus_protocol : Vec < u8 > ,
505+ /// Target block gas limit for the cluster.
506+ pub target_gas_limit : u64 ,
507+ /// Compounding flag enables compounding rewards for validators by using
508+ /// 0x02 withdrawal credentials.
509+ pub compounding : bool ,
510+ /// Config hash uniquely identifies a cluster definition excluding operator
511+ /// ENRs and signatures.
512+ pub config_hash : [ u8 ; 32 ] ,
513+ /// Definition hash uniquely identifies a cluster definition including
514+ /// operator ENRs and signatures.
515+ pub definition_hash : [ u8 ; 32 ] ,
516+ }
517+
518+ impl From < Definition > for DefinitionSSZ {
519+ fn from ( definition : Definition ) -> Self {
520+ Self {
521+ uuid : definition. uuid . to_string ( ) . as_bytes ( ) . to_vec ( ) ,
522+ name : definition. name . as_bytes ( ) . to_vec ( ) ,
523+ version : definition. version . as_bytes ( ) . to_vec ( ) ,
524+ timestamp : definition. timestamp . timestamp ( ) . to_be_bytes ( ) . to_vec ( ) ,
525+ num_validators : definition. num_validators ,
526+ threshold : definition. threshold ,
527+ dkg_algorithm : definition. dkg_algorithm . as_bytes ( ) . to_vec ( ) ,
528+ fork_version : definition. fork_version . try_into ( ) . unwrap ( ) ,
529+ operators : definition
530+ . operators
531+ . into_iter ( )
532+ . map ( OperatorSSZ :: from)
533+ . collect ( ) ,
534+ creator : CreatorSSZ :: from ( definition. creator ) ,
535+ validator_addresses : definition
536+ . validator_addresses
537+ . into_iter ( )
538+ . map ( ValidatorAddressesSSZ :: from)
539+ . collect ( ) ,
540+ deposit_amounts : definition. deposit_amounts ,
541+ consensus_protocol : definition. consensus_protocol . as_bytes ( ) . to_vec ( ) ,
542+ target_gas_limit : definition. target_gas_limit ,
543+ compounding : definition. compounding ,
544+ config_hash : definition. config_hash . try_into ( ) . unwrap ( ) ,
545+ definition_hash : definition. definition_hash . try_into ( ) . unwrap ( ) ,
546+ }
547+ }
548+ }
549+
550+ impl TryFrom < DefinitionSSZ > for Definition {
551+ type Error = DefinitionError ;
552+
553+ fn try_from ( definition : DefinitionSSZ ) -> Result < Self , Self :: Error > {
554+ Ok ( Self {
555+ uuid : Uuid :: from_slice ( & definition. uuid ) . unwrap ( ) ,
556+ name : String :: from_utf8 ( definition. name ) . unwrap ( ) ,
557+ version : String :: from_utf8 ( definition. version ) . unwrap ( ) ,
558+ timestamp : DateTime :: from_timestamp (
559+ i64:: from_be_bytes ( definition. timestamp . try_into ( ) . unwrap ( ) ) ,
560+ 0 ,
561+ )
562+ . unwrap ( ) ,
563+ num_validators : definition. num_validators ,
564+ threshold : definition. threshold ,
565+ dkg_algorithm : String :: from_utf8 ( definition. dkg_algorithm ) . unwrap ( ) ,
566+ fork_version : definition. fork_version . to_vec ( ) ,
567+ operators : definition
568+ . operators
569+ . into_iter ( )
570+ . map ( Operator :: try_from)
571+ . collect :: < Result < Vec < Operator > , DefinitionError > > ( )
572+ . unwrap ( ) ,
573+ creator : Creator :: try_from ( definition. creator ) . unwrap ( ) ,
574+ validator_addresses : definition
575+ . validator_addresses
576+ . into_iter ( )
577+ . map ( ValidatorAddresses :: try_from)
578+ . collect :: < Result < Vec < ValidatorAddresses > , DefinitionError > > ( )
579+ . unwrap ( ) ,
580+ deposit_amounts : definition. deposit_amounts ,
581+ consensus_protocol : String :: from_utf8 ( definition. consensus_protocol ) . unwrap ( ) ,
582+ target_gas_limit : definition. target_gas_limit ,
583+ compounding : definition. compounding ,
584+ config_hash : definition. config_hash . to_vec ( ) ,
585+ definition_hash : definition. definition_hash . to_vec ( ) ,
586+ } )
587+ }
588+ }
589+
466590/// Creator identifies the creator of a cluster definition. They may also be an
467591/// operator.
468592#[ serde_as]
@@ -475,6 +599,34 @@ pub struct Creator {
475599 pub config_signature : Vec < u8 > ,
476600}
477601
602+ #[ derive( Debug , Clone , PartialEq , Eq , Encode , Decode ) ]
603+ pub ( crate ) struct CreatorSSZ {
604+ /// The Ethereum address of the creator
605+ pub address : [ u8 ; 20 ] ,
606+ /// The creator's signature over the config hash
607+ pub config_signature : [ u8 ; 65 ] ,
608+ }
609+
610+ impl From < Creator > for CreatorSSZ {
611+ fn from ( creator : Creator ) -> Self {
612+ Self {
613+ address : creator. address . as_bytes ( ) . to_vec ( ) . try_into ( ) . unwrap ( ) ,
614+ config_signature : creator. config_signature . try_into ( ) . unwrap ( ) ,
615+ }
616+ }
617+ }
618+
619+ impl TryFrom < CreatorSSZ > for Creator {
620+ type Error = DefinitionError ;
621+
622+ fn try_from ( creator : CreatorSSZ ) -> Result < Self , Self :: Error > {
623+ Ok ( Self {
624+ address : String :: from_utf8 ( creator. address . to_vec ( ) ) . unwrap ( ) ,
625+ config_signature : creator. config_signature . to_vec ( ) ,
626+ } )
627+ }
628+ }
629+
478630/// Addresses for a validator
479631#[ derive( Debug , Clone , PartialEq , Eq , Serialize , Deserialize , Default ) ]
480632pub struct ValidatorAddresses {
@@ -484,6 +636,48 @@ pub struct ValidatorAddresses {
484636 pub withdrawal_address : String ,
485637}
486638
639+ #[ derive( Debug , Clone , PartialEq , Eq , Encode , Decode ) ]
640+ pub ( crate ) struct ValidatorAddressesSSZ {
641+ /// The fee recipient address for the validator
642+ pub fee_recipient_address : [ u8 ; 20 ] ,
643+ /// The withdrawal address for the validator
644+ pub withdrawal_address : [ u8 ; 20 ] ,
645+ }
646+
647+ impl From < ValidatorAddresses > for ValidatorAddressesSSZ {
648+ fn from ( validator_addresses : ValidatorAddresses ) -> Self {
649+ Self {
650+ fee_recipient_address : validator_addresses
651+ . fee_recipient_address
652+ . as_bytes ( )
653+ . to_vec ( )
654+ . try_into ( )
655+ . unwrap ( ) ,
656+ withdrawal_address : validator_addresses
657+ . withdrawal_address
658+ . as_bytes ( )
659+ . to_vec ( )
660+ . try_into ( )
661+ . unwrap ( ) ,
662+ }
663+ }
664+ }
665+
666+ impl TryFrom < ValidatorAddressesSSZ > for ValidatorAddresses {
667+ type Error = DefinitionError ;
668+
669+ fn try_from ( validator_addresses : ValidatorAddressesSSZ ) -> Result < Self , Self :: Error > {
670+ Ok ( Self {
671+ fee_recipient_address : String :: from_utf8 (
672+ validator_addresses. fee_recipient_address . to_vec ( ) ,
673+ )
674+ . unwrap ( ) ,
675+ withdrawal_address : String :: from_utf8 ( validator_addresses. withdrawal_address . to_vec ( ) )
676+ . unwrap ( ) ,
677+ } )
678+ }
679+ }
680+
487681/// DefinitionV1x0or1 is a cluster definition for version 1.0.0 or 1.1.0
488682#[ serde_as]
489683#[ derive( Debug , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
0 commit comments