* Start fixing enr-fork-id

* Fix time-until-next-fork logic

* Remove fork crate
This commit is contained in:
Paul Hauner
2020-03-26 17:35:12 +11:00
committed by Age Manning
parent bb065e3d00
commit f26bafe436
14 changed files with 129 additions and 152 deletions

View File

@@ -12,7 +12,6 @@ write_ssz_files = [] # Writes debugging .ssz files to /tmp during block process
eth2_config = { path = "../../eth2/utils/eth2_config" }
merkle_proof = { path = "../../eth2/utils/merkle_proof" }
store = { path = "../store" }
fork = { path = "../fork" }
parking_lot = "0.9.0"
lazy_static = "1.4.0"
lighthouse_metrics = { path = "../../eth2/utils/lighthouse_metrics" }

View File

@@ -15,7 +15,6 @@ use crate::snapshot_cache::SnapshotCache;
use crate::timeout_rw_lock::TimeoutRwLock;
use crate::validator_pubkey_cache::ValidatorPubkeyCache;
use crate::BeaconSnapshot;
use ::fork::{next_fork_epoch, next_fork_version};
use operation_pool::{OperationPool, PersistedOperationPool};
use slog::{crit, debug, error, info, trace, warn, Logger};
use slot_clock::SlotClock;
@@ -2095,51 +2094,18 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}
/// Gets the current EnrForkId.
///
/// v0.11
pub fn enr_fork_id(&self) -> Result<EnrForkId, Error> {
Ok(EnrForkId {
// TODO: To be implemented with v0.11 updates
fork_digest: [0, 0, 0, 0],
next_fork_version: next_fork_version(self.slot()?, &self.disabled_forks),
next_fork_epoch: next_fork_epoch::<T::EthSpec>(
&self.spec,
self.slot()?,
&self.disabled_forks,
),
})
pub fn enr_fork_id(&self) -> EnrForkId {
// 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_else(|_| self.spec.genesis_slot);
self.spec.enr_fork_id(slot)
}
/// Calculates the duration (in millis) to the next fork, if one exists.
///
/// This is required by the network thread to instantiate timeouts to update networking
/// constants
pub fn duration_to_next_fork(&self) -> Result<Option<tokio::timer::Delay>, Error> {
let current_slot = self.slot()?;
let next_fork_epoch =
next_fork_epoch::<T::EthSpec>(&self.spec, current_slot, &self.disabled_forks);
if next_fork_epoch != self.spec.far_future_epoch {
// There is an upcoming fork
let current_epoch = self.slot()?.epoch(T::EthSpec::slots_per_epoch());
let epochs_until_fork = next_fork_epoch
.saturating_sub(current_epoch)
.saturating_sub(1u64);
let millis_until_fork = T::EthSpec::slots_per_epoch()
* self.spec.milliseconds_per_slot
* epochs_until_fork.as_u64();
Ok(Some(tokio::timer::Delay::new(
Instant::now()
+ self
.slot_clock
.duration_to_next_epoch(T::EthSpec::slots_per_epoch())
.unwrap_or_else(|| Duration::from_secs(0))
+ Duration::from_millis(millis_until_fork)
// add a short timeout to start within the new fork period
+ Duration::from_millis(200),
)))
} else {
Ok(None)
}
/// Calculates the `Duration` to the next fork, if one exists.
pub fn duration_to_next_fork(&self) -> Option<Duration> {
let epoch = self.spec.next_fork_epoch()?;
self.slot_clock
.duration_to_slot(epoch.start_slot(T::EthSpec::slots_per_epoch()))
}
}

View File

@@ -1,8 +0,0 @@
[package]
name = "fork"
version = "0.2.0"
authors = ["Age Manning <Age@AgeManning.com>"]
edition = "2018"
[dependencies]
types = { path = "../../eth2/types" }

View File

@@ -1,5 +0,0 @@
///! List of known forks
// Add known forks to this mapping in slot order.
/// List of known forks. The format is (Fork Name, Slot to be activated, Fork Version).
pub const KNOWN_FORKS: [(&'static str, u64, [u8; 4]); 1] = [("genesis", 0, [0, 0, 0, 0])];

View File

@@ -1,75 +0,0 @@
///! Maintains a hard-coded list of known forks and their slots at which they were activated.
use types::{ChainSpec, Epoch, EthSpec, Slot};
mod forks;
/// A state-less function that provides the fork version given a set of active forks and a slot
/// number.
///
/// The disabled_forks parameter select which forks are disabled by their name.
pub fn current_fork_version(slot: Slot, disabled_forks: &[String]) -> [u8; 4] {
let mut version = [0, 0, 0, 0];
for (fork_name, fork_slot_no, fork_version) in forks::KNOWN_FORKS.iter() {
if *fork_slot_no <= slot.as_u64() {
if disabled_forks
.iter()
.find(|fork| **fork == String::from(*fork_name))
.is_none()
{
version = fork_version.clone();
}
} else {
break;
}
}
version
}
pub fn next_fork_version(slot: Slot, disabled_forks: &[String]) -> [u8; 4] {
let mut version = None;
for (fork_name, fork_slot_no, fork_version) in forks::KNOWN_FORKS.iter() {
if *fork_slot_no > slot.as_u64() {
if disabled_forks
.iter()
.find(|fork| **fork == String::from(*fork_name))
.is_none()
{
version = Some(fork_version.clone());
break;
}
}
}
if let Some(result_version) = version {
result_version
} else {
// if there is no next fork, use the current fork version
current_fork_version(slot, disabled_forks)
}
}
pub fn next_fork_epoch<T: EthSpec>(
spec: &ChainSpec,
slot: Slot,
disabled_forks: &[String],
) -> Epoch {
let mut next_fork_slot = None;
for (fork_name, fork_slot_no, _fork_version) in forks::KNOWN_FORKS.iter() {
if *fork_slot_no > slot.as_u64() {
if disabled_forks
.iter()
.find(|fork| **fork == String::from(*fork_name))
.is_none()
{
next_fork_slot = Some(Slot::new(*fork_slot_no));
break;
}
}
}
if let Some(fork_slot) = next_fork_slot {
fork_slot.epoch(T::slots_per_epoch())
} else {
Epoch::from(spec.far_future_epoch)
}
}

View File

@@ -78,14 +78,10 @@ impl<T: BeaconChainTypes> NetworkService<T> {
let propagation_percentage = config.propagation_percentage;
// build the current enr_fork_id for adding to our local ENR
let enr_fork_id = beacon_chain
.enr_fork_id()
.map_err(|e| format!("Could not get the current ENR fork version: {:?}", e))?;
let enr_fork_id = beacon_chain.enr_fork_id();
// keep track of when our fork_id needs to be updated
let next_fork_update = beacon_chain
.duration_to_next_fork()
.map_err(|e| format!("Could not get the next fork update duration: {:?}", e))?;
let next_fork_update = next_fork_delay(&beacon_chain);
// launch libp2p service
let (network_globals, mut libp2p) =
@@ -357,10 +353,8 @@ fn spawn_service<T: BeaconChainTypes>(
if let Some(mut update_fork_delay) = service.next_fork_update.take() {
if !update_fork_delay.is_elapsed() {
if let Ok(Async::Ready(_)) = update_fork_delay.poll() {
if let Ok(enr_fork_id) = service.beacon_chain.enr_fork_id() {
service.libp2p.swarm.update_fork_version(enr_fork_id);
}
service.next_fork_update = service.beacon_chain.duration_to_next_fork().unwrap_or_else(|_| None);
service.libp2p.swarm.update_fork_version(service.beacon_chain.enr_fork_id());
service.next_fork_update = next_fork_delay(&service.beacon_chain);
}
}
}
@@ -373,6 +367,18 @@ fn spawn_service<T: BeaconChainTypes>(
Ok(network_exit)
}
/// Returns a `Delay` that triggers shortly after the next change in the beacon chain fork version.
/// If there is no scheduled fork, `None` is returned.
fn next_fork_delay<T: BeaconChainTypes>(
beacon_chain: &BeaconChain<T>,
) -> Option<tokio::timer::Delay> {
beacon_chain.duration_to_next_fork().map(|until_fork| {
// Add a short time-out to start within the new fork period.
let delay = Duration::from_millis(200);
tokio::timer::Delay::new(Instant::now() + until_fork + delay)
})
}
/// Types of messages that the network service can receive.
#[derive(Debug)]
pub enum NetworkMessage<T: EthSpec> {