Skip to content

Commit 51a01be

Browse files
authored
Merge of #7655
2 parents 77093d9 + 48cb50f commit 51a01be

File tree

26 files changed

+1050
-584
lines changed

26 files changed

+1050
-584
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6812,17 +6812,27 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
68126812
.enr_fork_id::<T::EthSpec>(slot, self.genesis_validators_root)
68136813
}
68146814

6815-
/// Calculates the `Duration` to the next fork if it exists and returns it
6816-
/// with it's corresponding `ForkName`.
6817-
pub fn duration_to_next_fork(&self) -> Option<(ForkName, Duration)> {
6815+
/// Returns the fork_digest corresponding to an epoch.
6816+
/// See [`ChainSpec::compute_fork_digest`]
6817+
pub fn compute_fork_digest(&self, epoch: Epoch) -> [u8; 4] {
6818+
self.spec
6819+
.compute_fork_digest(self.genesis_validators_root, epoch)
6820+
}
6821+
6822+
/// Calculates the `Duration` to the next fork digest (this could be either a regular or BPO
6823+
/// hard fork) if it exists and returns it with its corresponding `Epoch`.
6824+
pub fn duration_to_next_digest(&self) -> Option<(Epoch, Duration)> {
68186825
// If we are unable to read the slot clock we assume that it is prior to genesis and
68196826
// therefore use the genesis slot.
68206827
let slot = self.slot().unwrap_or(self.spec.genesis_slot);
6828+
let epoch = slot.epoch(T::EthSpec::slots_per_epoch());
6829+
6830+
let next_digest_epoch = self.spec.next_digest_epoch(epoch)?;
6831+
let next_digest_slot = next_digest_epoch.start_slot(T::EthSpec::slots_per_epoch());
68216832

6822-
let (fork_name, epoch) = self.spec.next_fork_epoch::<T::EthSpec>(slot)?;
68236833
self.slot_clock
6824-
.duration_to_slot(epoch.start_slot(T::EthSpec::slots_per_epoch()))
6825-
.map(|duration| (fork_name, duration))
6834+
.duration_to_slot(next_digest_slot)
6835+
.map(|duration| (next_digest_epoch, duration))
68266836
}
68276837

68286838
/// This method serves to get a sense of the current chain health. It is used in block proposal

beacon_node/http_api/src/light_client.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ use crate::version::{
44
};
55
use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes};
66
use eth2::types::{
7-
self as api_types, ChainSpec, LightClientUpdate, LightClientUpdateResponseChunk,
7+
self as api_types, LightClientUpdate, LightClientUpdateResponseChunk,
88
LightClientUpdateResponseChunkInner, LightClientUpdatesQuery,
99
};
1010
use ssz::Encode;
1111
use std::sync::Arc;
12-
use types::{BeaconResponse, ForkName, Hash256, LightClientBootstrap};
12+
use types::{BeaconResponse, EthSpec, ForkName, Hash256, LightClientBootstrap};
1313
use warp::{
1414
hyper::{Body, Response},
1515
reply::Reply,
@@ -150,14 +150,10 @@ fn map_light_client_update_to_ssz_chunk<T: BeaconChainTypes>(
150150
chain: &BeaconChain<T>,
151151
light_client_update: &LightClientUpdate<T::EthSpec>,
152152
) -> LightClientUpdateResponseChunk {
153-
let fork_name = chain
154-
.spec
155-
.fork_name_at_slot::<T::EthSpec>(light_client_update.attested_header_slot());
156-
157-
let fork_digest = ChainSpec::compute_fork_digest(
158-
chain.spec.fork_version_for_name(fork_name),
159-
chain.genesis_validators_root,
160-
);
153+
let epoch = light_client_update
154+
.attested_header_slot()
155+
.epoch(T::EthSpec::slots_per_epoch());
156+
let fork_digest = chain.compute_fork_digest(epoch);
161157

162158
let payload = light_client_update.as_ssz_bytes();
163159
let response_chunk_len = fork_digest.len() + payload.len();

beacon_node/lighthouse_network/src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ pub fn gossipsub_config(
457457
) -> Vec<u8> {
458458
let topic_bytes = message.topic.as_str().as_bytes();
459459

460-
if fork_context.current_fork().altair_enabled() {
460+
if fork_context.current_fork_name().altair_enabled() {
461461
let topic_len_bytes = topic_bytes.len().to_le_bytes();
462462
let mut vec = Vec::with_capacity(
463463
prefix.len() + topic_len_bytes.len() + topic_bytes.len() + message.data.len(),

beacon_node/lighthouse_network/src/discovery/enr.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
pub use discv5::enr::CombinedKey;
44

55
use super::enr_ext::CombinedKeyExt;
6+
use super::enr_ext::{EnrExt, QUIC6_ENR_KEY, QUIC_ENR_KEY};
67
use super::ENR_FILENAME;
78
use crate::types::{Enr, EnrAttestationBitfield, EnrSyncCommitteeBitfield};
89
use crate::NetworkConfig;
@@ -18,10 +19,10 @@ use std::str::FromStr;
1819
use tracing::{debug, warn};
1920
use 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.
2423
pub 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.
2627
pub 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 {

beacon_node/lighthouse_network/src/discovery/mod.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use tracing::{debug, error, info, trace, warn};
4949
use types::{ChainSpec, EnrForkId, EthSpec};
5050

5151
mod subnet_predicate;
52-
use crate::discovery::enr::PEERDAS_CUSTODY_GROUP_COUNT_ENR_KEY;
52+
use crate::discovery::enr::{NEXT_FORK_DIGEST_ENR_KEY, PEERDAS_CUSTODY_GROUP_COUNT_ENR_KEY};
5353
pub use subnet_predicate::subnet_predicate;
5454
use types::non_zero_usize::new_non_zero_usize;
5555

@@ -570,6 +570,19 @@ impl<E: EthSpec> Discovery<E> {
570570
Ok(())
571571
}
572572

573+
pub fn update_enr_nfd(&mut self, nfd: [u8; 4]) -> Result<(), String> {
574+
self.discv5
575+
.enr_insert::<Bytes>(NEXT_FORK_DIGEST_ENR_KEY, &nfd.as_ssz_bytes().into())
576+
.map_err(|e| format!("{:?}", e))?;
577+
info!(
578+
next_fork_digest = ?nfd,
579+
"Updating the ENR nfd"
580+
);
581+
enr::save_enr_to_disk(Path::new(&self.enr_dir), &self.local_enr());
582+
*self.network_globals.local_enr.write() = self.discv5.local_enr();
583+
Ok(())
584+
}
585+
573586
/// Updates the `eth2` field of our local ENR.
574587
pub fn update_eth2_enr(&mut self, enr_fork_id: EnrForkId) {
575588
// to avoid having a reference to the spec constant, for the logging we assume
@@ -1217,7 +1230,15 @@ mod tests {
12171230
config.set_listening_addr(crate::ListenAddress::unused_v4_ports());
12181231
let config = Arc::new(config);
12191232
let enr_key: CombinedKey = CombinedKey::from_secp256k1(&keypair);
1220-
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default(), &spec).unwrap();
1233+
let next_fork_digest = [0; 4];
1234+
let enr: Enr = build_enr::<E>(
1235+
&enr_key,
1236+
&config,
1237+
&EnrForkId::default(),
1238+
next_fork_digest,
1239+
&spec,
1240+
)
1241+
.unwrap();
12211242
let globals = NetworkGlobals::new(
12221243
enr,
12231244
MetaData::V2(MetaDataV2 {

0 commit comments

Comments
 (0)