From 2b6da4b8deb717d23ec0b6aa305a7301931f848d Mon Sep 17 00:00:00 2001 From: Age Manning Date: Tue, 24 Mar 2020 19:10:28 +1100 Subject: [PATCH] Initial fork versioning (#934) * Merge #913 * Correct release tests * Completed release test corrections * Initial work on upgrading discovery * Updates discovery to latest version * Update ENR initialisation logic * Remove debug statements * Shifts timing units to slots * Initial work * Add initial fork versioning and EnrForkId * Correct linking for EnrForkId --- Cargo.lock | 23 ++++++++---- Cargo.toml | 1 + beacon_node/fork/Cargo.toml | 8 ++++ beacon_node/fork/src/forks.rs | 5 +++ beacon_node/fork/src/lib.rs | 71 +++++++++++++++++++++++++++++++++++ eth2/types/src/enr_fork_id.rs | 36 ++++++++++++++++++ eth2/types/src/lib.rs | 4 +- eth2/types/src/slot_epoch.rs | 2 + 8 files changed, 141 insertions(+), 9 deletions(-) create mode 100644 beacon_node/fork/Cargo.toml create mode 100644 beacon_node/fork/src/forks.rs create mode 100644 beacon_node/fork/src/lib.rs create mode 100644 eth2/types/src/enr_fork_id.rs diff --git a/Cargo.lock b/Cargo.lock index 2b6aef52fb..a5cb39f405 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" +checksum = "d663a8e9a99154b5fb793032533f6328da35e23aac63d5c152279aa8ba356825" [[package]] name = "arrayref" @@ -1462,9 +1462,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" +checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" dependencies = [ "cfg-if", "crc32fast", @@ -1496,6 +1496,13 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "fork" +version = "0.2.0" +dependencies = [ + "types", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -2031,9 +2038,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.67" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" +checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" [[package]] name = "libflate" @@ -3209,9 +3216,9 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" +checksum = "f918f2b601f93baa836c1c2945faef682ba5b6d4828ecb45eeb7cc3c71b811b4" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", diff --git a/Cargo.toml b/Cargo.toml index 37f2550269..a0510b4d53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ members = [ "beacon_node/client", "beacon_node/eth1", "beacon_node/eth2-libp2p", + "beacon_node/fork", "beacon_node/network", "beacon_node/rest_api", "beacon_node/store", diff --git a/beacon_node/fork/Cargo.toml b/beacon_node/fork/Cargo.toml new file mode 100644 index 0000000000..dc3d82222c --- /dev/null +++ b/beacon_node/fork/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "fork" +version = "0.2.0" +authors = ["Age Manning "] +edition = "2018" + +[dependencies] +types = { path = "../../eth2/types" } diff --git a/beacon_node/fork/src/forks.rs b/beacon_node/fork/src/forks.rs new file mode 100644 index 0000000000..ce0d65a2f6 --- /dev/null +++ b/beacon_node/fork/src/forks.rs @@ -0,0 +1,5 @@ +///! 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])]; diff --git a/beacon_node/fork/src/lib.rs b/beacon_node/fork/src/lib.rs new file mode 100644 index 0000000000..d4f0c7133a --- /dev/null +++ b/beacon_node/fork/src/lib.rs @@ -0,0 +1,71 @@ +///! Maintains a hard-coded list of known forks and their slots at which they were activated. +use types::{Epoch, EthSpec, Slot, FAR_FUTURE_EPOCH}; + +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: Vec) -> [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: Vec) -> [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(slot: Slot, disabled_forks: Vec) -> 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 { + FAR_FUTURE_EPOCH + } +} diff --git a/eth2/types/src/enr_fork_id.rs b/eth2/types/src/enr_fork_id.rs new file mode 100644 index 0000000000..f1c5ac6bf1 --- /dev/null +++ b/eth2/types/src/enr_fork_id.rs @@ -0,0 +1,36 @@ +use crate::test_utils::TestRandom; +use crate::utils::{fork_from_hex_str, fork_to_hex_str}; +use crate::Epoch; + +use serde_derive::{Deserialize, Serialize}; +use ssz_derive::{Decode, Encode}; +use test_random_derive::TestRandom; +use tree_hash_derive::TreeHash; + +/// Specifies a fork which allows nodes to identify each other on the network. This fork is used in +/// a nodes local ENR. +/// +/// Spec v0.11 +#[derive( + Debug, Clone, PartialEq, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, +)] +pub struct EnrForkId { + #[serde( + serialize_with = "fork_to_hex_str", + deserialize_with = "fork_from_hex_str" + )] + pub fork_digest: [u8; 4], + #[serde( + serialize_with = "fork_to_hex_str", + deserialize_with = "fork_from_hex_str" + )] + pub next_fork_version: [u8; 4], + pub next_fork_epoch: Epoch, +} + +#[cfg(test)] +mod tests { + use super::*; + + ssz_and_tree_hash_tests!(EnrForkId); +} diff --git a/eth2/types/src/lib.rs b/eth2/types/src/lib.rs index bf399b551c..f77aac0d55 100644 --- a/eth2/types/src/lib.rs +++ b/eth2/types/src/lib.rs @@ -21,6 +21,7 @@ pub mod checkpoint; pub mod deposit; pub mod deposit_data; pub mod deposit_message; +pub mod enr_fork_id; pub mod eth1_data; pub mod eth_spec; pub mod fork; @@ -60,6 +61,7 @@ pub use crate::checkpoint::Checkpoint; pub use crate::deposit::{Deposit, DEPOSIT_TREE_DEPTH}; pub use crate::deposit_data::DepositData; pub use crate::deposit_message::DepositMessage; +pub use crate::enr_fork_id::EnrForkId; pub use crate::eth1_data::Eth1Data; pub use crate::fork::Fork; pub use crate::free_attestation::FreeAttestation; @@ -72,7 +74,7 @@ pub use crate::signed_beacon_block::SignedBeaconBlock; pub use crate::signed_beacon_block_header::SignedBeaconBlockHeader; pub use crate::signed_voluntary_exit::SignedVoluntaryExit; pub use crate::signing_root::{SignedRoot, SigningRoot}; -pub use crate::slot_epoch::{Epoch, Slot}; +pub use crate::slot_epoch::{Epoch, Slot, FAR_FUTURE_EPOCH}; pub use crate::subnet_id::SubnetId; pub use crate::validator::Validator; pub use crate::voluntary_exit::VoluntaryExit; diff --git a/eth2/types/src/slot_epoch.rs b/eth2/types/src/slot_epoch.rs index f77ea2d7d8..6261497673 100644 --- a/eth2/types/src/slot_epoch.rs +++ b/eth2/types/src/slot_epoch.rs @@ -22,6 +22,8 @@ use std::hash::{Hash, Hasher}; use std::iter::Iterator; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign}; +pub const FAR_FUTURE_EPOCH: Epoch = Epoch(u64::max_value()); + #[derive(Eq, Debug, Clone, Copy, Default, Serialize, Deserialize)] #[serde(transparent)] pub struct Slot(u64);