33pub use discv5:: enr:: CombinedKey ;
44
55use super :: enr_ext:: CombinedKeyExt ;
6+ use super :: enr_ext:: { EnrExt , QUIC6_ENR_KEY , QUIC_ENR_KEY } ;
67use super :: ENR_FILENAME ;
78use crate :: types:: { Enr , EnrAttestationBitfield , EnrSyncCommitteeBitfield } ;
89use crate :: NetworkConfig ;
@@ -18,10 +19,10 @@ use std::str::FromStr;
1819use tracing:: { debug, warn} ;
1920use types:: { ChainSpec , EnrForkId , EthSpec } ;
2021
21- use super :: enr_ext:: { EnrExt , QUIC6_ENR_KEY , QUIC_ENR_KEY } ;
22-
2322/// The ENR field specifying the fork id.
2423pub const ETH2_ENR_KEY : & str = "eth2" ;
24+ /// The ENR field specifying the next fork digest.
25+ pub const NEXT_FORK_DIGEST_ENR_KEY : & str = "nfd" ;
2526/// The ENR field specifying the attestation subnet bitfield.
2627pub const ATTESTATION_BITFIELD_ENR_KEY : & str = "attnets" ;
2728/// The ENR field specifying the sync committee subnet bitfield.
@@ -42,6 +43,9 @@ pub trait Eth2Enr {
4243 /// The peerdas custody group count associated with the ENR.
4344 fn custody_group_count < E : EthSpec > ( & self , spec : & ChainSpec ) -> Result < u64 , & ' static str > ;
4445
46+ /// The next fork digest associated with the ENR.
47+ fn next_fork_digest ( & self ) -> Result < [ u8 ; 4 ] , & ' static str > ;
48+
4549 fn eth2 ( & self ) -> Result < EnrForkId , & ' static str > ;
4650}
4751
@@ -81,6 +85,12 @@ impl Eth2Enr for Enr {
8185 }
8286 }
8387
88+ fn next_fork_digest ( & self ) -> Result < [ u8 ; 4 ] , & ' static str > {
89+ self . get_decodable :: < [ u8 ; 4 ] > ( NEXT_FORK_DIGEST_ENR_KEY )
90+ . ok_or ( "ENR next fork digest non-existent" ) ?
91+ . map_err ( |_| "Could not decode the ENR next fork digest" )
92+ }
93+
8494 fn eth2 ( & self ) -> Result < EnrForkId , & ' static str > {
8595 let eth2_bytes: Bytes = self
8696 . get_decodable ( ETH2_ENR_KEY )
@@ -149,13 +159,14 @@ pub fn build_or_load_enr<E: EthSpec>(
149159 local_key : Keypair ,
150160 config : & NetworkConfig ,
151161 enr_fork_id : & EnrForkId ,
162+ next_fork_digest : [ u8 ; 4 ] ,
152163 spec : & ChainSpec ,
153164) -> Result < Enr , String > {
154165 // Build the local ENR.
155166 // Note: Discovery should update the ENR record's IP to the external IP as seen by the
156167 // majority of our peers, if the CLI doesn't expressly forbid it.
157168 let enr_key = CombinedKey :: from_libp2p ( local_key) ?;
158- let mut local_enr = build_enr :: < E > ( & enr_key, config, enr_fork_id, spec) ?;
169+ let mut local_enr = build_enr :: < E > ( & enr_key, config, enr_fork_id, next_fork_digest , spec) ?;
159170
160171 use_or_load_enr ( & enr_key, & mut local_enr, config) ?;
161172 Ok ( local_enr)
@@ -166,6 +177,7 @@ pub fn build_enr<E: EthSpec>(
166177 enr_key : & CombinedKey ,
167178 config : & NetworkConfig ,
168179 enr_fork_id : & EnrForkId ,
180+ next_fork_digest : [ u8 ; 4 ] ,
169181 spec : & ChainSpec ,
170182) -> Result < Enr , String > {
171183 let mut builder = discv5:: enr:: Enr :: builder ( ) ;
@@ -257,7 +269,7 @@ pub fn build_enr<E: EthSpec>(
257269 & bitfield. as_ssz_bytes ( ) . into ( ) ,
258270 ) ;
259271
260- // only set `cgc` if PeerDAS fork epoch has been scheduled
272+ // only set `cgc` and `nfd` if PeerDAS fork (Fulu) epoch has been scheduled
261273 if spec. is_peer_das_scheduled ( ) {
262274 let custody_group_count =
263275 if let Some ( false_cgc) = config. advertise_false_custody_group_count {
@@ -268,6 +280,7 @@ pub fn build_enr<E: EthSpec>(
268280 spec. custody_requirement
269281 } ;
270282 builder. add_value ( PEERDAS_CUSTODY_GROUP_COUNT_ENR_KEY , & custody_group_count) ;
283+ builder. add_value ( NEXT_FORK_DIGEST_ENR_KEY , & next_fork_digest) ;
271284 }
272285
273286 builder
@@ -340,6 +353,7 @@ mod test {
340353 use types:: { Epoch , MainnetEthSpec } ;
341354
342355 type E = MainnetEthSpec ;
356+ const TEST_NFD : [ u8 ; 4 ] = [ 0x01 , 0x02 , 0x03 , 0x04 ] ;
343357
344358 fn make_fulu_spec ( ) -> ChainSpec {
345359 let mut spec = E :: default_spec ( ) ;
@@ -351,10 +365,17 @@ mod test {
351365 let keypair = libp2p:: identity:: secp256k1:: Keypair :: generate ( ) ;
352366 let enr_key = CombinedKey :: from_secp256k1 ( & keypair) ;
353367 let enr_fork_id = EnrForkId :: default ( ) ;
354- let enr = build_enr :: < E > ( & enr_key, & config, & enr_fork_id, spec) . unwrap ( ) ;
368+ let enr = build_enr :: < E > ( & enr_key, & config, & enr_fork_id, TEST_NFD , spec) . unwrap ( ) ;
355369 ( enr, enr_key)
356370 }
357371
372+ #[ test]
373+ fn test_nfd_enr_encoding ( ) {
374+ let spec = make_fulu_spec ( ) ;
375+ let enr = build_enr_with_config ( NetworkConfig :: default ( ) , & spec) . 0 ;
376+ assert_eq ! ( enr. next_fork_digest( ) . unwrap( ) , TEST_NFD ) ;
377+ }
378+
358379 #[ test]
359380 fn custody_group_count_default ( ) {
360381 let config = NetworkConfig {
0 commit comments