Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6812,17 +6812,27 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.enr_fork_id::<T::EthSpec>(slot, self.genesis_validators_root)
}

/// Calculates the `Duration` to the next fork if it exists and returns it
/// with it's corresponding `ForkName`.
pub fn duration_to_next_fork(&self) -> Option<(ForkName, Duration)> {
/// Returns the fork_digest corresponding to an epoch.
/// See [`ChainSpec::compute_fork_digest`]
pub fn compute_fork_digest(&self, epoch: Epoch) -> [u8; 4] {
self.spec
.compute_fork_digest(self.genesis_validators_root, epoch)
}

/// Calculates the `Duration` to the next fork digest (this could be either a regular or BPO
/// hard fork) if it exists and returns it with its corresponding `Epoch`.
pub fn duration_to_next_digest(&self) -> Option<(Epoch, Duration)> {
// If we are unable to read the slot clock we assume that it is prior to genesis and
// therefore use the genesis slot.
let slot = self.slot().unwrap_or(self.spec.genesis_slot);
let epoch = slot.epoch(T::EthSpec::slots_per_epoch());

let next_digest_epoch = self.spec.next_digest_epoch(epoch)?;
let next_digest_slot = next_digest_epoch.start_slot(T::EthSpec::slots_per_epoch());

let (fork_name, epoch) = self.spec.next_fork_epoch::<T::EthSpec>(slot)?;
self.slot_clock
.duration_to_slot(epoch.start_slot(T::EthSpec::slots_per_epoch()))
.map(|duration| (fork_name, duration))
.duration_to_slot(next_digest_slot)
.map(|duration| (next_digest_epoch, duration))
}

/// This method serves to get a sense of the current chain health. It is used in block proposal
Expand Down
16 changes: 6 additions & 10 deletions beacon_node/http_api/src/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use crate::version::{
};
use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes};
use eth2::types::{
self as api_types, ChainSpec, LightClientUpdate, LightClientUpdateResponseChunk,
self as api_types, LightClientUpdate, LightClientUpdateResponseChunk,
LightClientUpdateResponseChunkInner, LightClientUpdatesQuery,
};
use ssz::Encode;
use std::sync::Arc;
use types::{BeaconResponse, ForkName, Hash256, LightClientBootstrap};
use types::{BeaconResponse, EthSpec, ForkName, Hash256, LightClientBootstrap};
use warp::{
hyper::{Body, Response},
reply::Reply,
Expand Down Expand Up @@ -150,14 +150,10 @@ fn map_light_client_update_to_ssz_chunk<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
light_client_update: &LightClientUpdate<T::EthSpec>,
) -> LightClientUpdateResponseChunk {
let fork_name = chain
.spec
.fork_name_at_slot::<T::EthSpec>(light_client_update.attested_header_slot());

let fork_digest = ChainSpec::compute_fork_digest(
chain.spec.fork_version_for_name(fork_name),
chain.genesis_validators_root,
);
let epoch = light_client_update
.attested_header_slot()
.epoch(T::EthSpec::slots_per_epoch());
let fork_digest = chain.compute_fork_digest(epoch);

let payload = light_client_update.as_ssz_bytes();
let response_chunk_len = fork_digest.len() + payload.len();
Expand Down
2 changes: 1 addition & 1 deletion beacon_node/lighthouse_network/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ pub fn gossipsub_config(
) -> Vec<u8> {
let topic_bytes = message.topic.as_str().as_bytes();

if fork_context.current_fork().altair_enabled() {
if fork_context.current_fork_name().altair_enabled() {
let topic_len_bytes = topic_bytes.len().to_le_bytes();
let mut vec = Vec::with_capacity(
prefix.len() + topic_len_bytes.len() + topic_bytes.len() + message.data.len(),
Expand Down
31 changes: 26 additions & 5 deletions beacon_node/lighthouse_network/src/discovery/enr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub use discv5::enr::CombinedKey;

use super::enr_ext::CombinedKeyExt;
use super::enr_ext::{EnrExt, QUIC6_ENR_KEY, QUIC_ENR_KEY};
use super::ENR_FILENAME;
use crate::types::{Enr, EnrAttestationBitfield, EnrSyncCommitteeBitfield};
use crate::NetworkConfig;
Expand All @@ -18,10 +19,10 @@ use std::str::FromStr;
use tracing::{debug, warn};
use types::{ChainSpec, EnrForkId, EthSpec};

use super::enr_ext::{EnrExt, QUIC6_ENR_KEY, QUIC_ENR_KEY};

/// The ENR field specifying the fork id.
pub const ETH2_ENR_KEY: &str = "eth2";
/// The ENR field specifying the next fork digest.
pub const NEXT_FORK_DIGEST_ENR_KEY: &str = "nfd";
/// The ENR field specifying the attestation subnet bitfield.
pub const ATTESTATION_BITFIELD_ENR_KEY: &str = "attnets";
/// The ENR field specifying the sync committee subnet bitfield.
Expand All @@ -42,6 +43,9 @@ pub trait Eth2Enr {
/// The peerdas custody group count associated with the ENR.
fn custody_group_count<E: EthSpec>(&self, spec: &ChainSpec) -> Result<u64, &'static str>;

/// The next fork digest associated with the ENR.
fn next_fork_digest(&self) -> Result<[u8; 4], &'static str>;

fn eth2(&self) -> Result<EnrForkId, &'static str>;
}

Expand Down Expand Up @@ -81,6 +85,12 @@ impl Eth2Enr for Enr {
}
}

fn next_fork_digest(&self) -> Result<[u8; 4], &'static str> {
self.get_decodable::<[u8; 4]>(NEXT_FORK_DIGEST_ENR_KEY)
.ok_or("ENR next fork digest non-existent")?
.map_err(|_| "Could not decode the ENR next fork digest")
}

fn eth2(&self) -> Result<EnrForkId, &'static str> {
let eth2_bytes: Bytes = self
.get_decodable(ETH2_ENR_KEY)
Expand Down Expand Up @@ -149,13 +159,14 @@ pub fn build_or_load_enr<E: EthSpec>(
local_key: Keypair,
config: &NetworkConfig,
enr_fork_id: &EnrForkId,
next_fork_digest: [u8; 4],
spec: &ChainSpec,
) -> Result<Enr, String> {
// Build the local ENR.
// Note: Discovery should update the ENR record's IP to the external IP as seen by the
// majority of our peers, if the CLI doesn't expressly forbid it.
let enr_key = CombinedKey::from_libp2p(local_key)?;
let mut local_enr = build_enr::<E>(&enr_key, config, enr_fork_id, spec)?;
let mut local_enr = build_enr::<E>(&enr_key, config, enr_fork_id, next_fork_digest, spec)?;

use_or_load_enr(&enr_key, &mut local_enr, config)?;
Ok(local_enr)
Expand All @@ -166,6 +177,7 @@ pub fn build_enr<E: EthSpec>(
enr_key: &CombinedKey,
config: &NetworkConfig,
enr_fork_id: &EnrForkId,
next_fork_digest: [u8; 4],
spec: &ChainSpec,
) -> Result<Enr, String> {
let mut builder = discv5::enr::Enr::builder();
Expand Down Expand Up @@ -257,7 +269,7 @@ pub fn build_enr<E: EthSpec>(
&bitfield.as_ssz_bytes().into(),
);

// only set `cgc` if PeerDAS fork epoch has been scheduled
// only set `cgc` and `nfd` if PeerDAS fork (Fulu) epoch has been scheduled
if spec.is_peer_das_scheduled() {
let custody_group_count =
if let Some(false_cgc) = config.advertise_false_custody_group_count {
Expand All @@ -268,6 +280,7 @@ pub fn build_enr<E: EthSpec>(
spec.custody_requirement
};
builder.add_value(PEERDAS_CUSTODY_GROUP_COUNT_ENR_KEY, &custody_group_count);
builder.add_value(NEXT_FORK_DIGEST_ENR_KEY, &next_fork_digest);
}

builder
Expand Down Expand Up @@ -340,6 +353,7 @@ mod test {
use types::{Epoch, MainnetEthSpec};

type E = MainnetEthSpec;
const TEST_NFD: [u8; 4] = [0x01, 0x02, 0x03, 0x04];

fn make_fulu_spec() -> ChainSpec {
let mut spec = E::default_spec();
Expand All @@ -351,10 +365,17 @@ mod test {
let keypair = libp2p::identity::secp256k1::Keypair::generate();
let enr_key = CombinedKey::from_secp256k1(&keypair);
let enr_fork_id = EnrForkId::default();
let enr = build_enr::<E>(&enr_key, &config, &enr_fork_id, spec).unwrap();
let enr = build_enr::<E>(&enr_key, &config, &enr_fork_id, TEST_NFD, spec).unwrap();
(enr, enr_key)
}

#[test]
fn test_nfd_enr_encoding() {
let spec = make_fulu_spec();
let enr = build_enr_with_config(NetworkConfig::default(), &spec).0;
assert_eq!(enr.next_fork_digest().unwrap(), TEST_NFD);
}

#[test]
fn custody_group_count_default() {
let config = NetworkConfig {
Expand Down
25 changes: 23 additions & 2 deletions beacon_node/lighthouse_network/src/discovery/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use tracing::{debug, error, info, trace, warn};
use types::{ChainSpec, EnrForkId, EthSpec};

mod subnet_predicate;
use crate::discovery::enr::PEERDAS_CUSTODY_GROUP_COUNT_ENR_KEY;
use crate::discovery::enr::{NEXT_FORK_DIGEST_ENR_KEY, PEERDAS_CUSTODY_GROUP_COUNT_ENR_KEY};
pub use subnet_predicate::subnet_predicate;
use types::non_zero_usize::new_non_zero_usize;

Expand Down Expand Up @@ -570,6 +570,19 @@ impl<E: EthSpec> Discovery<E> {
Ok(())
}

pub fn update_enr_nfd(&mut self, nfd: [u8; 4]) -> Result<(), String> {
self.discv5
.enr_insert::<Bytes>(NEXT_FORK_DIGEST_ENR_KEY, &nfd.as_ssz_bytes().into())
.map_err(|e| format!("{:?}", e))?;
info!(
next_fork_digest = ?nfd,
"Updating the ENR nfd"
);
enr::save_enr_to_disk(Path::new(&self.enr_dir), &self.local_enr());
*self.network_globals.local_enr.write() = self.discv5.local_enr();
Ok(())
}

/// Updates the `eth2` field of our local ENR.
pub fn update_eth2_enr(&mut self, enr_fork_id: EnrForkId) {
// to avoid having a reference to the spec constant, for the logging we assume
Expand Down Expand Up @@ -1217,7 +1230,15 @@ mod tests {
config.set_listening_addr(crate::ListenAddress::unused_v4_ports());
let config = Arc::new(config);
let enr_key: CombinedKey = CombinedKey::from_secp256k1(&keypair);
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default(), &spec).unwrap();
let next_fork_digest = [0; 4];
let enr: Enr = build_enr::<E>(
&enr_key,
&config,
&EnrForkId::default(),
next_fork_digest,
&spec,
)
.unwrap();
let globals = NetworkGlobals::new(
enr,
MetaData::V2(MetaDataV2 {
Expand Down
Loading
Loading