Update to spec v1.0.0-rc.0 and BLSv4 (#1765)

## Issue Addressed

Closes #1504 
Closes #1505
Replaces #1703
Closes #1707

## Proposed Changes

* Update BLST and Milagro to versions compatible with BLSv4 spec
* Update Lighthouse to spec v1.0.0-rc.0, and update EF test vectors
* Use the v1.0.0 constants for `MainnetEthSpec`.
* Rename `InteropEthSpec` -> `V012LegacyEthSpec`
    * Change all constants to suit the mainnet `v0.12.3` specification (i.e., Medalla).
* Deprecate the `--spec` flag for the `lighthouse` binary
    * This value is now obtained from the `config_name` field of the `YamlConfig`.
        * Built in testnet YAML files have been updated.
    * Ignore the `--spec` value, if supplied, log a warning that it will be deprecated
    * `lcli` still has the spec flag, that's fine because it's dev tooling.
* Remove the `E: EthSpec` from `YamlConfig`
    * This means we need to deser the genesis `BeaconState` on-demand, but this is fine.
* Swap the old "minimal", "mainnet" strings over to the new `EthSpecId` enum.
* Always require a `CONFIG_NAME` field in `YamlConfig` (it used to have a default).

## Additional Info

Lots of breaking changes, do not merge! ~~We will likely need a Lighthouse v0.4.0 branch, and possibly a long-term v0.3.0 branch to keep Medalla alive~~.

Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
Michael Sproul
2020-10-28 22:19:38 +00:00
parent ad846ad280
commit 36bd4d87f0
55 changed files with 596 additions and 661 deletions

View File

@@ -264,7 +264,6 @@ impl ChainSpec {
hysteresis_quotient: 4,
hysteresis_downward_multiplier: 1,
hysteresis_upward_multiplier: 5,
proportional_slashing_multiplier: 3,
/*
* Gwei values
@@ -283,7 +282,7 @@ impl ChainSpec {
/*
* Time parameters
*/
genesis_delay: 172800, // 2 days
genesis_delay: 604800, // 7 days
milliseconds_per_slot: 12_000,
min_attestation_inclusion_delay: 1,
min_seed_lookahead: Epoch::new(1),
@@ -298,8 +297,9 @@ impl ChainSpec {
base_reward_factor: 64,
whistleblower_reward_quotient: 512,
proposer_reward_quotient: 8,
inactivity_penalty_quotient: u64::pow(2, 24),
min_slashing_penalty_quotient: 32,
inactivity_penalty_quotient: u64::pow(2, 26),
min_slashing_penalty_quotient: 128,
proportional_slashing_multiplier: 1,
/*
* Signature domains
@@ -320,7 +320,7 @@ impl ChainSpec {
/*
* Eth1
*/
eth1_follow_distance: 1_024,
eth1_follow_distance: 2048,
seconds_per_eth1_block: 14,
deposit_chain_id: 1,
deposit_network_id: 1,
@@ -359,6 +359,9 @@ impl ChainSpec {
shard_committee_period: 64,
genesis_delay: 300,
milliseconds_per_slot: 6_000,
inactivity_penalty_quotient: u64::pow(2, 25),
min_slashing_penalty_quotient: 64,
proportional_slashing_multiplier: 2,
safe_slots_to_update_justified: 2,
network_id: 2, // lighthouse testnet network id
deposit_chain_id: 5,
@@ -368,17 +371,19 @@ impl ChainSpec {
}
}
/// Interop testing spec
/// Suits the `v0.12.3` version of the eth2 spec:
/// https://github.com/ethereum/eth2.0-specs/blob/v0.12.3/configs/mainnet/phase0.yaml
///
/// This allows us to customize a chain spec for interop testing.
pub fn interop() -> Self {
/// This method only needs to exist whilst we provide support for "legacy" testnets prior to v1.0.0
/// (e.g., Medalla, Zinken, Spadina, Altona, etc.).
pub fn v012_legacy() -> Self {
let boot_nodes = vec![];
Self {
milliseconds_per_slot: 12_000,
target_committee_size: 4,
shuffle_round_count: 10,
network_id: 13,
genesis_delay: 172_800, // 2 days
inactivity_penalty_quotient: u64::pow(2, 24),
min_slashing_penalty_quotient: 32,
eth1_follow_distance: 1024,
boot_nodes,
..ChainSpec::mainnet()
}
@@ -448,8 +453,7 @@ mod tests {
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "UPPERCASE", deny_unknown_fields)]
pub struct YamlConfig {
#[serde(default)]
config_name: String,
pub config_name: String,
// ChainSpec
#[serde(with = "serde_utils::quoted_u64")]
max_committees_per_slot: u64,
@@ -481,10 +485,6 @@ pub struct YamlConfig {
hysteresis_downward_multiplier: u64,
#[serde(with = "serde_utils::quoted_u64")]
hysteresis_upward_multiplier: u64,
// Proportional slashing multiplier defaults to 3 for compatibility with Altona and Medalla.
#[serde(default = "default_proportional_slashing_multiplier")]
#[serde(with = "serde_utils::quoted_u64")]
proportional_slashing_multiplier: u64,
#[serde(with = "serde_utils::bytes_4_hex")]
genesis_fork_version: [u8; 4],
#[serde(with = "serde_utils::u8_hex")]
@@ -514,6 +514,8 @@ pub struct YamlConfig {
#[serde(with = "serde_utils::quoted_u64")]
min_slashing_penalty_quotient: u64,
#[serde(with = "serde_utils::quoted_u64")]
proportional_slashing_multiplier: u64,
#[serde(with = "serde_utils::quoted_u64")]
safe_slots_to_update_justified: u64,
#[serde(with = "serde_utils::u32_hex")]
@@ -575,11 +577,6 @@ pub struct YamlConfig {
deposit_contract_address: Address,
}
// Compatibility shim for proportional slashing multpilier on Altona and Medalla.
fn default_proportional_slashing_multiplier() -> u64 {
3
}
impl Default for YamlConfig {
fn default() -> Self {
let chain_spec = MainnetEthSpec::default_spec();
@@ -594,6 +591,21 @@ fn milliseconds_to_seconds(millis: u64) -> u64 {
/// Spec v0.12.1
impl YamlConfig {
/// Maps `self.config_name` to an identifier for an `EthSpec` instance.
///
/// Returns `None` if there is no match.
pub fn eth_spec_id(&self) -> Option<EthSpecId> {
Some(match self.config_name.as_str() {
"mainnet" => EthSpecId::Mainnet,
"minimal" => EthSpecId::Minimal,
"zinken" => EthSpecId::V012Legacy,
"spadina" => EthSpecId::V012Legacy,
"medalla" => EthSpecId::V012Legacy,
"altona" => EthSpecId::V012Legacy,
_ => return None,
})
}
pub fn from_spec<T: EthSpec>(spec: &ChainSpec) -> Self {
Self {
config_name: T::spec_name().to_string(),

View File

@@ -6,7 +6,45 @@ use ssz_types::typenum::{
Unsigned, U0, U1024, U1099511627776, U128, U16, U16777216, U2, U2048, U32, U4, U4096, U64,
U65536, U8, U8192,
};
use std::fmt::Debug;
use std::fmt::{self, Debug};
use std::str::FromStr;
const MAINNET: &str = "mainnet";
const MINIMAL: &str = "minimal";
const LEGACY: &str = "v0.12-legacy";
/// Used to identify one of the `EthSpec` instances defined here.
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum EthSpecId {
Mainnet,
Minimal,
V012Legacy,
}
impl FromStr for EthSpecId {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
MAINNET => Ok(EthSpecId::Mainnet),
MINIMAL => Ok(EthSpecId::Minimal),
LEGACY => Ok(EthSpecId::V012Legacy),
_ => Err(format!("Unknown eth spec: {}", s)),
}
}
}
impl fmt::Display for EthSpecId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
EthSpecId::Mainnet => MAINNET,
EthSpecId::Minimal => MINIMAL,
EthSpecId::V012Legacy => LEGACY,
};
write!(f, "{}", s)
}
}
pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + Eq {
/*
@@ -56,7 +94,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
fn default_spec() -> ChainSpec;
fn spec_name() -> &'static str;
fn spec_name() -> EthSpecId;
fn genesis_epoch() -> Epoch {
Epoch::new(Self::GenesisEpoch::to_u64())
@@ -144,7 +182,7 @@ impl EthSpec for MainnetEthSpec {
type MaxValidatorsPerCommittee = U2048;
type GenesisEpoch = U0;
type SlotsPerEpoch = U32;
type EpochsPerEth1VotingPeriod = U32;
type EpochsPerEth1VotingPeriod = U64;
type SlotsPerHistoricalRoot = U8192;
type EpochsPerHistoricalVector = U65536;
type EpochsPerSlashingsVector = U8192;
@@ -156,14 +194,14 @@ impl EthSpec for MainnetEthSpec {
type MaxDeposits = U16;
type MaxVoluntaryExits = U16;
type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch
type SlotsPerEth1VotingPeriod = U1024; // 32 epochs * 32 slots per epoch
type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch
fn default_spec() -> ChainSpec {
ChainSpec::mainnet()
}
fn spec_name() -> &'static str {
"mainnet"
fn spec_name() -> EthSpecId {
EthSpecId::Mainnet
}
}
@@ -203,28 +241,32 @@ impl EthSpec for MinimalEthSpec {
ChainSpec::minimal()
}
fn spec_name() -> &'static str {
"minimal"
fn spec_name() -> EthSpecId {
EthSpecId::Minimal
}
}
pub type MinimalBeaconState = BeaconState<MinimalEthSpec>;
/// Interop testnet spec
/// Suits the `v0.12.3` version of the eth2 spec:
/// https://github.com/ethereum/eth2.0-specs/blob/v0.12.3/configs/mainnet/phase0.yaml
///
/// This struct only needs to exist whilst we provide support for "legacy" testnets prior to v1.0.0
/// (e.g., Medalla, Zinken, Spadina, Altona, etc.).
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
pub struct InteropEthSpec;
pub struct V012LegacyEthSpec;
impl EthSpec for InteropEthSpec {
type SlotsPerEpoch = U8;
type EpochsPerEth1VotingPeriod = U2;
type SlotsPerHistoricalRoot = U64;
type EpochsPerHistoricalVector = U64;
type EpochsPerSlashingsVector = U64;
type MaxPendingAttestations = U1024; // 128 max attestations * 8 slots per epoch
type SlotsPerEth1VotingPeriod = U16; // 2 epochs * 8 slots per epoch
impl EthSpec for V012LegacyEthSpec {
type EpochsPerEth1VotingPeriod = U32;
type SlotsPerEth1VotingPeriod = U1024; // 32 epochs * 32 slots per epoch
params_from_eth_spec!(MainnetEthSpec {
SlotsPerEpoch,
SlotsPerHistoricalRoot,
EpochsPerHistoricalVector,
EpochsPerSlashingsVector,
MaxPendingAttestations,
JustificationBitsLength,
SubnetBitfieldLength,
MaxValidatorsPerCommittee,
@@ -239,12 +281,10 @@ impl EthSpec for InteropEthSpec {
});
fn default_spec() -> ChainSpec {
ChainSpec::interop()
ChainSpec::v012_legacy()
}
fn spec_name() -> &'static str {
"interop"
fn spec_name() -> EthSpecId {
EthSpecId::V012Legacy
}
}
pub type InteropBeaconState = BeaconState<InteropEthSpec>;

View File

@@ -73,6 +73,7 @@ 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::eth_spec::EthSpecId;
pub use crate::fork::Fork;
pub use crate::fork_data::ForkData;
pub use crate::free_attestation::FreeAttestation;

View File

@@ -8,6 +8,7 @@ use ssz_derive::{Decode, Encode};
use std::fmt;
use test_random_derive::TestRandom;
use tree_hash::TreeHash;
use tree_hash_derive::TreeHash;
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
@@ -41,7 +42,7 @@ impl From<SignedBeaconBlockHash> for Hash256 {
///
/// Spec v0.12.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TestRandom)]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
#[serde(bound = "E: EthSpec")]
pub struct SignedBeaconBlock<E: EthSpec> {
pub message: BeaconBlock<E>,