Update consensus code and tests to v0.12.3 (#1655)
## Proposed Changes Update test vectors for v0.12.3, and introduced configurable `proportional_slashing_multiplier`. Also makes `YamlConfig` a bit safer by making every field access in `apply_to_chain_spec` explicit, and removing the `#[serde(default)]` attribute, which would instantiate missing fields to type defaults! Risky!
This commit is contained in:
parent
3412a3ec54
commit
258b28469e
@ -34,7 +34,7 @@ Like all Ethereum 2.0 clients, Lighthouse is a work-in-progress.
|
|||||||
|
|
||||||
Current development overview:
|
Current development overview:
|
||||||
|
|
||||||
- Specification `v0.12.1` implemented, optimized and passing test vectors.
|
- Specification `v0.12.3` implemented, optimized and passing test vectors.
|
||||||
- Rust-native libp2p with Gossipsub and Discv5.
|
- Rust-native libp2p with Gossipsub and Discv5.
|
||||||
- RESTful JSON API via HTTP server.
|
- RESTful JSON API via HTTP server.
|
||||||
- Events via WebSocket.
|
- Events via WebSocket.
|
||||||
|
@ -11,6 +11,10 @@ pub fn process_slashings<T: EthSpec>(
|
|||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let epoch = state.current_epoch();
|
let epoch = state.current_epoch();
|
||||||
let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()?;
|
let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()?;
|
||||||
|
let adjusted_total_slashing_balance = std::cmp::min(
|
||||||
|
sum_slashings.safe_mul(spec.proportional_slashing_multiplier)?,
|
||||||
|
total_balance,
|
||||||
|
);
|
||||||
|
|
||||||
for (index, validator) in state.validators.iter().enumerate() {
|
for (index, validator) in state.validators.iter().enumerate() {
|
||||||
if validator.slashed
|
if validator.slashed
|
||||||
@ -21,7 +25,7 @@ pub fn process_slashings<T: EthSpec>(
|
|||||||
let penalty_numerator = validator
|
let penalty_numerator = validator
|
||||||
.effective_balance
|
.effective_balance
|
||||||
.safe_div(increment)?
|
.safe_div(increment)?
|
||||||
.safe_mul(std::cmp::min(sum_slashings.safe_mul(3)?, total_balance))?;
|
.safe_mul(adjusted_total_slashing_balance)?;
|
||||||
let penalty = penalty_numerator
|
let penalty = penalty_numerator
|
||||||
.safe_div(total_balance)?
|
.safe_div(total_balance)?
|
||||||
.safe_mul(increment)?;
|
.safe_mul(increment)?;
|
||||||
|
@ -52,6 +52,7 @@ pub struct ChainSpec {
|
|||||||
pub hysteresis_quotient: u64,
|
pub hysteresis_quotient: u64,
|
||||||
pub hysteresis_downward_multiplier: u64,
|
pub hysteresis_downward_multiplier: u64,
|
||||||
pub hysteresis_upward_multiplier: u64,
|
pub hysteresis_upward_multiplier: u64,
|
||||||
|
pub proportional_slashing_multiplier: u64,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gwei values
|
* Gwei values
|
||||||
@ -243,7 +244,7 @@ impl ChainSpec {
|
|||||||
|
|
||||||
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
|
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
|
||||||
///
|
///
|
||||||
/// Spec v0.12.1
|
/// Spec v0.12.3
|
||||||
pub fn mainnet() -> Self {
|
pub fn mainnet() -> Self {
|
||||||
Self {
|
Self {
|
||||||
/*
|
/*
|
||||||
@ -267,6 +268,7 @@ impl ChainSpec {
|
|||||||
hysteresis_quotient: 4,
|
hysteresis_quotient: 4,
|
||||||
hysteresis_downward_multiplier: 1,
|
hysteresis_downward_multiplier: 1,
|
||||||
hysteresis_upward_multiplier: 5,
|
hysteresis_upward_multiplier: 5,
|
||||||
|
proportional_slashing_multiplier: 3,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gwei values
|
* Gwei values
|
||||||
@ -437,21 +439,15 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Union of a ChainSpec struct and an EthSpec struct that holds constants used for the configs
|
/// YAML config file as defined by the spec.
|
||||||
/// from the Ethereum 2 specs repo (https://github.com/ethereum/eth2.0-specs/tree/dev/configs)
|
|
||||||
///
|
///
|
||||||
/// Doesn't include fields of the YAML that we don't need yet (e.g. Phase 1 stuff).
|
/// Spec v0.12.3
|
||||||
///
|
|
||||||
/// Spec v0.12.1
|
|
||||||
// Yaml Config is declared here in order to access domain fields of ChainSpec which are private.
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
||||||
#[serde(rename_all = "UPPERCASE")]
|
#[serde(rename_all = "UPPERCASE")]
|
||||||
#[serde(default)]
|
|
||||||
pub struct YamlConfig {
|
pub struct YamlConfig {
|
||||||
|
#[serde(default)]
|
||||||
|
config_name: String,
|
||||||
// ChainSpec
|
// ChainSpec
|
||||||
far_future_epoch: u64,
|
|
||||||
base_rewards_per_epoch: u64,
|
|
||||||
deposit_contract_tree_depth: u64,
|
|
||||||
max_committees_per_slot: usize,
|
max_committees_per_slot: usize,
|
||||||
target_committee_size: usize,
|
target_committee_size: usize,
|
||||||
min_per_epoch_churn_limit: u64,
|
min_per_epoch_churn_limit: u64,
|
||||||
@ -467,7 +463,9 @@ pub struct YamlConfig {
|
|||||||
hysteresis_quotient: u64,
|
hysteresis_quotient: u64,
|
||||||
hysteresis_downward_multiplier: u64,
|
hysteresis_downward_multiplier: u64,
|
||||||
hysteresis_upward_multiplier: u64,
|
hysteresis_upward_multiplier: u64,
|
||||||
genesis_slot: u64,
|
// Proportional slashing multiplier defaults to 3 for compatibility with Altona and Medalla.
|
||||||
|
#[serde(default = "default_proportional_slashing_multiplier")]
|
||||||
|
proportional_slashing_multiplier: u64,
|
||||||
#[serde(
|
#[serde(
|
||||||
serialize_with = "fork_to_hex_str",
|
serialize_with = "fork_to_hex_str",
|
||||||
deserialize_with = "fork_from_hex_str"
|
deserialize_with = "fork_from_hex_str"
|
||||||
@ -524,14 +522,8 @@ pub struct YamlConfig {
|
|||||||
serialize_with = "u32_to_hex_str"
|
serialize_with = "u32_to_hex_str"
|
||||||
)]
|
)]
|
||||||
domain_aggregate_and_proof: u32,
|
domain_aggregate_and_proof: u32,
|
||||||
#[serde(
|
|
||||||
deserialize_with = "u32_from_hex_str",
|
|
||||||
serialize_with = "u32_to_hex_str"
|
|
||||||
)]
|
|
||||||
// EthSpec
|
// EthSpec
|
||||||
justification_bits_length: u32,
|
|
||||||
max_validators_per_committee: u32,
|
max_validators_per_committee: u32,
|
||||||
genesis_epoch: Epoch,
|
|
||||||
slots_per_epoch: u64,
|
slots_per_epoch: u64,
|
||||||
epochs_per_eth1_voting_period: u64,
|
epochs_per_eth1_voting_period: u64,
|
||||||
slots_per_historical_root: usize,
|
slots_per_historical_root: usize,
|
||||||
@ -544,13 +536,22 @@ pub struct YamlConfig {
|
|||||||
max_attestations: u32,
|
max_attestations: u32,
|
||||||
max_deposits: u32,
|
max_deposits: u32,
|
||||||
max_voluntary_exits: u32,
|
max_voluntary_exits: u32,
|
||||||
|
|
||||||
// Validator
|
// Validator
|
||||||
eth1_follow_distance: u64,
|
eth1_follow_distance: u64,
|
||||||
target_aggregators_per_committee: u64,
|
target_aggregators_per_committee: u64,
|
||||||
random_subnets_per_validator: u64,
|
random_subnets_per_validator: u64,
|
||||||
epochs_per_random_subnet_subscription: u64,
|
epochs_per_random_subnet_subscription: u64,
|
||||||
seconds_per_eth1_block: u64,
|
seconds_per_eth1_block: u64,
|
||||||
|
/* TODO: incorporate these into ChainSpec and turn on `serde(deny_unknown_fields)`
|
||||||
|
deposit_chain_id: u64,
|
||||||
|
deposit_network_id: u64,
|
||||||
|
deposit_contract_address: String,
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compatibility shim for proportional slashing multpilier on Altona and Medalla.
|
||||||
|
fn default_proportional_slashing_multiplier() -> u64 {
|
||||||
|
3
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for YamlConfig {
|
impl Default for YamlConfig {
|
||||||
@ -565,10 +566,8 @@ impl YamlConfig {
|
|||||||
#[allow(clippy::integer_arithmetic)]
|
#[allow(clippy::integer_arithmetic)]
|
||||||
pub fn from_spec<T: EthSpec>(spec: &ChainSpec) -> Self {
|
pub fn from_spec<T: EthSpec>(spec: &ChainSpec) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
config_name: T::spec_name().to_string(),
|
||||||
// ChainSpec
|
// ChainSpec
|
||||||
far_future_epoch: spec.far_future_epoch.into(),
|
|
||||||
base_rewards_per_epoch: spec.base_rewards_per_epoch,
|
|
||||||
deposit_contract_tree_depth: spec.deposit_contract_tree_depth,
|
|
||||||
max_committees_per_slot: spec.max_committees_per_slot,
|
max_committees_per_slot: spec.max_committees_per_slot,
|
||||||
target_committee_size: spec.target_committee_size,
|
target_committee_size: spec.target_committee_size,
|
||||||
min_per_epoch_churn_limit: spec.min_per_epoch_churn_limit,
|
min_per_epoch_churn_limit: spec.min_per_epoch_churn_limit,
|
||||||
@ -584,7 +583,7 @@ impl YamlConfig {
|
|||||||
hysteresis_quotient: spec.hysteresis_quotient,
|
hysteresis_quotient: spec.hysteresis_quotient,
|
||||||
hysteresis_downward_multiplier: spec.hysteresis_downward_multiplier,
|
hysteresis_downward_multiplier: spec.hysteresis_downward_multiplier,
|
||||||
hysteresis_upward_multiplier: spec.hysteresis_upward_multiplier,
|
hysteresis_upward_multiplier: spec.hysteresis_upward_multiplier,
|
||||||
genesis_slot: spec.genesis_slot.into(),
|
proportional_slashing_multiplier: spec.proportional_slashing_multiplier,
|
||||||
bls_withdrawal_prefix: spec.bls_withdrawal_prefix_byte,
|
bls_withdrawal_prefix: spec.bls_withdrawal_prefix_byte,
|
||||||
seconds_per_slot: spec.milliseconds_per_slot / 1000,
|
seconds_per_slot: spec.milliseconds_per_slot / 1000,
|
||||||
min_attestation_inclusion_delay: spec.min_attestation_inclusion_delay,
|
min_attestation_inclusion_delay: spec.min_attestation_inclusion_delay,
|
||||||
@ -609,9 +608,7 @@ impl YamlConfig {
|
|||||||
domain_aggregate_and_proof: spec.domain_aggregate_and_proof,
|
domain_aggregate_and_proof: spec.domain_aggregate_and_proof,
|
||||||
|
|
||||||
// EthSpec
|
// EthSpec
|
||||||
justification_bits_length: T::JustificationBitsLength::to_u32(),
|
|
||||||
max_validators_per_committee: T::MaxValidatorsPerCommittee::to_u32(),
|
max_validators_per_committee: T::MaxValidatorsPerCommittee::to_u32(),
|
||||||
genesis_epoch: T::genesis_epoch(),
|
|
||||||
slots_per_epoch: T::slots_per_epoch(),
|
slots_per_epoch: T::slots_per_epoch(),
|
||||||
epochs_per_eth1_voting_period: T::EpochsPerEth1VotingPeriod::to_u64(),
|
epochs_per_eth1_voting_period: T::EpochsPerEth1VotingPeriod::to_u64(),
|
||||||
slots_per_historical_root: T::slots_per_historical_root(),
|
slots_per_historical_root: T::slots_per_historical_root(),
|
||||||
@ -642,10 +639,8 @@ impl YamlConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_to_chain_spec<T: EthSpec>(&self, chain_spec: &ChainSpec) -> Option<ChainSpec> {
|
pub fn apply_to_chain_spec<T: EthSpec>(&self, chain_spec: &ChainSpec) -> Option<ChainSpec> {
|
||||||
// Checking for EthSpec constants
|
// Check that YAML values match type-level EthSpec constants
|
||||||
if self.justification_bits_length != T::JustificationBitsLength::to_u32()
|
if self.max_validators_per_committee != T::MaxValidatorsPerCommittee::to_u32()
|
||||||
|| self.max_validators_per_committee != T::MaxValidatorsPerCommittee::to_u32()
|
|
||||||
|| self.genesis_epoch != T::genesis_epoch()
|
|
||||||
|| self.slots_per_epoch != T::slots_per_epoch()
|
|| self.slots_per_epoch != T::slots_per_epoch()
|
||||||
|| self.epochs_per_eth1_voting_period != T::EpochsPerEth1VotingPeriod::to_u64()
|
|| self.epochs_per_eth1_voting_period != T::EpochsPerEth1VotingPeriod::to_u64()
|
||||||
|| self.slots_per_historical_root != T::slots_per_historical_root()
|
|| self.slots_per_historical_root != T::slots_per_historical_root()
|
||||||
@ -664,25 +659,48 @@ impl YamlConfig {
|
|||||||
|
|
||||||
// Create a ChainSpec from the yaml config
|
// Create a ChainSpec from the yaml config
|
||||||
Some(ChainSpec {
|
Some(ChainSpec {
|
||||||
far_future_epoch: Epoch::from(self.far_future_epoch),
|
/*
|
||||||
base_rewards_per_epoch: self.base_rewards_per_epoch,
|
* Misc
|
||||||
deposit_contract_tree_depth: self.deposit_contract_tree_depth,
|
*/
|
||||||
|
max_committees_per_slot: self.max_committees_per_slot,
|
||||||
target_committee_size: self.target_committee_size,
|
target_committee_size: self.target_committee_size,
|
||||||
min_per_epoch_churn_limit: self.min_per_epoch_churn_limit,
|
min_per_epoch_churn_limit: self.min_per_epoch_churn_limit,
|
||||||
churn_limit_quotient: self.churn_limit_quotient,
|
churn_limit_quotient: self.churn_limit_quotient,
|
||||||
shuffle_round_count: self.shuffle_round_count,
|
shuffle_round_count: self.shuffle_round_count,
|
||||||
min_genesis_active_validator_count: self.min_genesis_active_validator_count,
|
min_genesis_active_validator_count: self.min_genesis_active_validator_count,
|
||||||
min_genesis_time: self.min_genesis_time,
|
min_genesis_time: self.min_genesis_time,
|
||||||
min_deposit_amount: self.min_deposit_amount,
|
|
||||||
genesis_delay: self.genesis_delay,
|
|
||||||
max_effective_balance: self.max_effective_balance,
|
|
||||||
hysteresis_quotient: self.hysteresis_quotient,
|
hysteresis_quotient: self.hysteresis_quotient,
|
||||||
hysteresis_downward_multiplier: self.hysteresis_downward_multiplier,
|
hysteresis_downward_multiplier: self.hysteresis_downward_multiplier,
|
||||||
hysteresis_upward_multiplier: self.hysteresis_upward_multiplier,
|
hysteresis_upward_multiplier: self.hysteresis_upward_multiplier,
|
||||||
|
proportional_slashing_multiplier: self.proportional_slashing_multiplier,
|
||||||
|
/*
|
||||||
|
* Fork Choice
|
||||||
|
*/
|
||||||
|
safe_slots_to_update_justified: self.safe_slots_to_update_justified,
|
||||||
|
/*
|
||||||
|
* Validator
|
||||||
|
*/
|
||||||
|
eth1_follow_distance: self.eth1_follow_distance,
|
||||||
|
target_aggregators_per_committee: self.target_aggregators_per_committee,
|
||||||
|
random_subnets_per_validator: self.random_subnets_per_validator,
|
||||||
|
epochs_per_random_subnet_subscription: self.epochs_per_random_subnet_subscription,
|
||||||
|
seconds_per_eth1_block: self.seconds_per_eth1_block,
|
||||||
|
/*
|
||||||
|
* Gwei values
|
||||||
|
*/
|
||||||
|
min_deposit_amount: self.min_deposit_amount,
|
||||||
|
max_effective_balance: self.max_effective_balance,
|
||||||
ejection_balance: self.ejection_balance,
|
ejection_balance: self.ejection_balance,
|
||||||
effective_balance_increment: self.effective_balance_increment,
|
effective_balance_increment: self.effective_balance_increment,
|
||||||
genesis_slot: Slot::from(self.genesis_slot),
|
/*
|
||||||
|
* Initial values
|
||||||
|
*/
|
||||||
|
genesis_fork_version: self.genesis_fork_version,
|
||||||
bls_withdrawal_prefix_byte: self.bls_withdrawal_prefix,
|
bls_withdrawal_prefix_byte: self.bls_withdrawal_prefix,
|
||||||
|
/*
|
||||||
|
* Time parameters
|
||||||
|
*/
|
||||||
|
genesis_delay: self.genesis_delay,
|
||||||
milliseconds_per_slot: self.seconds_per_slot.saturating_mul(1000),
|
milliseconds_per_slot: self.seconds_per_slot.saturating_mul(1000),
|
||||||
min_attestation_inclusion_delay: self.min_attestation_inclusion_delay,
|
min_attestation_inclusion_delay: self.min_attestation_inclusion_delay,
|
||||||
min_seed_lookahead: Epoch::from(self.min_seed_lookahead),
|
min_seed_lookahead: Epoch::from(self.min_seed_lookahead),
|
||||||
@ -692,20 +710,43 @@ impl YamlConfig {
|
|||||||
),
|
),
|
||||||
shard_committee_period: self.shard_committee_period,
|
shard_committee_period: self.shard_committee_period,
|
||||||
min_epochs_to_inactivity_penalty: self.min_epochs_to_inactivity_penalty,
|
min_epochs_to_inactivity_penalty: self.min_epochs_to_inactivity_penalty,
|
||||||
|
/*
|
||||||
|
* Reward and penalty quotients
|
||||||
|
*/
|
||||||
base_reward_factor: self.base_reward_factor,
|
base_reward_factor: self.base_reward_factor,
|
||||||
whistleblower_reward_quotient: self.whistleblower_reward_quotient,
|
whistleblower_reward_quotient: self.whistleblower_reward_quotient,
|
||||||
proposer_reward_quotient: self.proposer_reward_quotient,
|
proposer_reward_quotient: self.proposer_reward_quotient,
|
||||||
inactivity_penalty_quotient: self.inactivity_penalty_quotient,
|
inactivity_penalty_quotient: self.inactivity_penalty_quotient,
|
||||||
min_slashing_penalty_quotient: self.min_slashing_penalty_quotient,
|
min_slashing_penalty_quotient: self.min_slashing_penalty_quotient,
|
||||||
|
/*
|
||||||
|
* Signature domains
|
||||||
|
*/
|
||||||
domain_beacon_proposer: self.domain_beacon_proposer,
|
domain_beacon_proposer: self.domain_beacon_proposer,
|
||||||
domain_beacon_attester: self.domain_beacon_attester,
|
domain_beacon_attester: self.domain_beacon_attester,
|
||||||
domain_randao: self.domain_randao,
|
domain_randao: self.domain_randao,
|
||||||
domain_deposit: self.domain_deposit,
|
domain_deposit: self.domain_deposit,
|
||||||
domain_voluntary_exit: self.domain_voluntary_exit,
|
domain_voluntary_exit: self.domain_voluntary_exit,
|
||||||
|
domain_selection_proof: self.domain_selection_proof,
|
||||||
|
domain_aggregate_and_proof: self.domain_aggregate_and_proof,
|
||||||
|
/*
|
||||||
|
* Lighthouse-specific parameters
|
||||||
|
*
|
||||||
|
* These are paramaters that are present in the chain spec but aren't part of the YAML
|
||||||
|
* config. We avoid using `..chain_spec` so that changes to the set of fields don't
|
||||||
|
* accidentally get forgotten (explicit better than implicit, yada yada).
|
||||||
|
*/
|
||||||
boot_nodes: chain_spec.boot_nodes.clone(),
|
boot_nodes: chain_spec.boot_nodes.clone(),
|
||||||
genesis_fork_version: self.genesis_fork_version,
|
network_id: chain_spec.network_id,
|
||||||
eth1_follow_distance: self.eth1_follow_distance,
|
attestation_propagation_slot_range: chain_spec.attestation_propagation_slot_range,
|
||||||
..*chain_spec
|
maximum_gossip_clock_disparity_millis: chain_spec.maximum_gossip_clock_disparity_millis,
|
||||||
|
attestation_subnet_count: chain_spec.attestation_subnet_count,
|
||||||
|
/*
|
||||||
|
* Constants, not configurable.
|
||||||
|
*/
|
||||||
|
genesis_slot: chain_spec.genesis_slot,
|
||||||
|
far_future_epoch: chain_spec.far_future_epoch,
|
||||||
|
base_rewards_per_epoch: chain_spec.base_rewards_per_epoch,
|
||||||
|
deposit_contract_tree_depth: chain_spec.deposit_contract_tree_depth,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -768,7 +809,7 @@ mod yaml_tests {
|
|||||||
let yamlconfig = YamlConfig::from_spec::<MinimalEthSpec>(&spec);
|
let yamlconfig = YamlConfig::from_spec::<MinimalEthSpec>(&spec);
|
||||||
|
|
||||||
// modifying the original spec
|
// modifying the original spec
|
||||||
spec.deposit_contract_tree_depth += 1;
|
spec.max_committees_per_slot += 1;
|
||||||
// Applying a yaml config with incorrect EthSpec should fail
|
// Applying a yaml config with incorrect EthSpec should fail
|
||||||
let res = yamlconfig.apply_to_chain_spec::<MainnetEthSpec>(&spec);
|
let res = yamlconfig.apply_to_chain_spec::<MainnetEthSpec>(&spec);
|
||||||
assert_eq!(res, None);
|
assert_eq!(res, None);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use environment::EnvironmentBuilder;
|
use environment::EnvironmentBuilder;
|
||||||
use eth2_testnet_config::Eth2TestnetConfig;
|
use eth2_testnet_config::Eth2TestnetConfig;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use types::{Epoch, MainnetEthSpec, YamlConfig};
|
use types::{MainnetEthSpec, YamlConfig};
|
||||||
|
|
||||||
fn builder() -> EnvironmentBuilder<MainnetEthSpec> {
|
fn builder() -> EnvironmentBuilder<MainnetEthSpec> {
|
||||||
EnvironmentBuilder::mainnet()
|
EnvironmentBuilder::mainnet()
|
||||||
@ -36,8 +36,8 @@ mod setup_eth2_config {
|
|||||||
.expect("should build environment");
|
.expect("should build environment");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
environment.eth2_config.spec.far_future_epoch,
|
environment.eth2_config.spec.max_committees_per_slot,
|
||||||
Epoch::new(999) // see testnet_dir/config.yaml
|
128 // see testnet_dir/config.yaml
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,56 +1,156 @@
|
|||||||
FAR_FUTURE_EPOCH: 999 # for testing
|
# Mainnet preset
|
||||||
BASE_REWARDS_PER_EPOCH: 4
|
# Note: the intention of this file (for now) is to illustrate what a mainnet configuration could look like.
|
||||||
DEPOSIT_CONTRACT_TREE_DEPTH: 32
|
# Some of these constants may still change before the launch of Phase 0.
|
||||||
MAX_COMMITTEES_PER_SLOT: 64
|
|
||||||
|
CONFIG_NAME: "mainnet"
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
MAX_COMMITTEES_PER_SLOT: 128 # MODIFIED FOR TESTING
|
||||||
|
# 2**7 (= 128)
|
||||||
TARGET_COMMITTEE_SIZE: 128
|
TARGET_COMMITTEE_SIZE: 128
|
||||||
|
# 2**11 (= 2,048)
|
||||||
|
MAX_VALIDATORS_PER_COMMITTEE: 2048
|
||||||
|
# 2**2 (= 4)
|
||||||
MIN_PER_EPOCH_CHURN_LIMIT: 4
|
MIN_PER_EPOCH_CHURN_LIMIT: 4
|
||||||
|
# 2**16 (= 65,536)
|
||||||
CHURN_LIMIT_QUOTIENT: 65536
|
CHURN_LIMIT_QUOTIENT: 65536
|
||||||
|
# See issue 563
|
||||||
SHUFFLE_ROUND_COUNT: 90
|
SHUFFLE_ROUND_COUNT: 90
|
||||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 4096
|
# `2**14` (= 16,384)
|
||||||
MIN_GENESIS_TIME: 0
|
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384
|
||||||
GENESIS_DELAY: 3600
|
# Jan 3, 2020
|
||||||
MIN_DEPOSIT_AMOUNT: 10000000
|
MIN_GENESIS_TIME: 1578009600
|
||||||
MAX_EFFECTIVE_BALANCE: 3200000000
|
# 4
|
||||||
EJECTION_BALANCE: 1600000000
|
HYSTERESIS_QUOTIENT: 4
|
||||||
EFFECTIVE_BALANCE_INCREMENT: 100000000
|
# 1 (minus 0.25)
|
||||||
GENESIS_SLOT: 0
|
HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
||||||
GENESIS_FORK_VERSION: 0x01030307
|
# 5 (plus 1.25)
|
||||||
BLS_WITHDRAWAL_PREFIX: 0x00
|
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
||||||
SECONDS_PER_SLOT: 12
|
# 3
|
||||||
MIN_ATTESTATION_INCLUSION_DELAY: 1
|
PROPORTIONAL_SLASHING_MULTIPLIER: 3
|
||||||
MIN_SEED_LOOKAHEAD: 1
|
|
||||||
MAX_SEED_LOOKAHEAD: 4
|
|
||||||
MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4
|
# Fork Choice
|
||||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
|
# ---------------------------------------------------------------
|
||||||
PERSISTENT_COMMITTEE_PERIOD: 2048
|
# 2**3 (= 8)
|
||||||
BASE_REWARD_FACTOR: 64
|
|
||||||
WHISTLEBLOWER_REWARD_QUOTIENT: 512
|
|
||||||
PROPOSER_REWARD_QUOTIENT: 8
|
|
||||||
INACTIVITY_PENALTY_QUOTIENT: 33554432
|
|
||||||
MIN_SLASHING_PENALTY_QUOTIENT: 32
|
|
||||||
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 8
|
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 8
|
||||||
|
|
||||||
|
|
||||||
|
# Validator
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 2**10 (= 1,024)
|
||||||
|
ETH1_FOLLOW_DISTANCE: 1024
|
||||||
|
# 2**4 (= 16)
|
||||||
|
TARGET_AGGREGATORS_PER_COMMITTEE: 16
|
||||||
|
# 2**0 (= 1)
|
||||||
|
RANDOM_SUBNETS_PER_VALIDATOR: 1
|
||||||
|
# 2**8 (= 256)
|
||||||
|
EPOCHS_PER_RANDOM_SUBNET_SUBSCRIPTION: 256
|
||||||
|
# 14 (estimate from Eth1 mainnet)
|
||||||
|
SECONDS_PER_ETH1_BLOCK: 14
|
||||||
|
|
||||||
|
|
||||||
|
# Deposit contract
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Ethereum PoW Mainnet
|
||||||
|
DEPOSIT_CHAIN_ID: 1
|
||||||
|
DEPOSIT_NETWORK_ID: 1
|
||||||
|
# **TBD**
|
||||||
|
DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890
|
||||||
|
|
||||||
|
|
||||||
|
# Gwei values
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
||||||
|
MIN_DEPOSIT_AMOUNT: 1000000000
|
||||||
|
# 2**5 * 10**9 (= 32,000,000,000) Gwei
|
||||||
|
MAX_EFFECTIVE_BALANCE: 32000000000
|
||||||
|
# 2**4 * 10**9 (= 16,000,000,000) Gwei
|
||||||
|
EJECTION_BALANCE: 16000000000
|
||||||
|
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
||||||
|
EFFECTIVE_BALANCE_INCREMENT: 1000000000
|
||||||
|
|
||||||
|
|
||||||
|
# Initial values
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Mainnet initial fork version, recommend altering for testnets
|
||||||
|
GENESIS_FORK_VERSION: 0x00000000
|
||||||
|
BLS_WITHDRAWAL_PREFIX: 0x00
|
||||||
|
|
||||||
|
|
||||||
|
# Time parameters
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 172800 seconds (2 days)
|
||||||
|
GENESIS_DELAY: 172800
|
||||||
|
# 12 seconds
|
||||||
|
SECONDS_PER_SLOT: 12
|
||||||
|
# 2**0 (= 1) slots 12 seconds
|
||||||
|
MIN_ATTESTATION_INCLUSION_DELAY: 1
|
||||||
|
# 2**5 (= 32) slots 6.4 minutes
|
||||||
|
SLOTS_PER_EPOCH: 32
|
||||||
|
# 2**0 (= 1) epochs 6.4 minutes
|
||||||
|
MIN_SEED_LOOKAHEAD: 1
|
||||||
|
# 2**2 (= 4) epochs 25.6 minutes
|
||||||
|
MAX_SEED_LOOKAHEAD: 4
|
||||||
|
# 2**5 (= 32) epochs ~3.4 hours
|
||||||
|
EPOCHS_PER_ETH1_VOTING_PERIOD: 32
|
||||||
|
# 2**13 (= 8,192) slots ~13 hours
|
||||||
|
SLOTS_PER_HISTORICAL_ROOT: 8192
|
||||||
|
# 2**8 (= 256) epochs ~27 hours
|
||||||
|
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
|
||||||
|
# 2**8 (= 256) epochs ~27 hours
|
||||||
|
SHARD_COMMITTEE_PERIOD: 256
|
||||||
|
# 2**2 (= 4) epochs 25.6 minutes
|
||||||
|
MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4
|
||||||
|
|
||||||
|
|
||||||
|
# State vector lengths
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 2**16 (= 65,536) epochs ~0.8 years
|
||||||
|
EPOCHS_PER_HISTORICAL_VECTOR: 65536
|
||||||
|
# 2**13 (= 8,192) epochs ~36 days
|
||||||
|
EPOCHS_PER_SLASHINGS_VECTOR: 8192
|
||||||
|
# 2**24 (= 16,777,216) historical roots, ~26,131 years
|
||||||
|
HISTORICAL_ROOTS_LIMIT: 16777216
|
||||||
|
# 2**40 (= 1,099,511,627,776) validator spots
|
||||||
|
VALIDATOR_REGISTRY_LIMIT: 1099511627776
|
||||||
|
|
||||||
|
|
||||||
|
# Reward and penalty quotients
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 2**6 (= 64)
|
||||||
|
BASE_REWARD_FACTOR: 64
|
||||||
|
# 2**9 (= 512)
|
||||||
|
WHISTLEBLOWER_REWARD_QUOTIENT: 512
|
||||||
|
# 2**3 (= 8)
|
||||||
|
PROPOSER_REWARD_QUOTIENT: 8
|
||||||
|
# 2**24 (= 16,777,216)
|
||||||
|
INACTIVITY_PENALTY_QUOTIENT: 16777216
|
||||||
|
# 2**5 (= 32)
|
||||||
|
MIN_SLASHING_PENALTY_QUOTIENT: 32
|
||||||
|
|
||||||
|
|
||||||
|
# Max operations per block
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# 2**4 (= 16)
|
||||||
|
MAX_PROPOSER_SLASHINGS: 16
|
||||||
|
# 2**1 (= 2)
|
||||||
|
MAX_ATTESTER_SLASHINGS: 2
|
||||||
|
# 2**7 (= 128)
|
||||||
|
MAX_ATTESTATIONS: 128
|
||||||
|
# 2**4 (= 16)
|
||||||
|
MAX_DEPOSITS: 16
|
||||||
|
# 2**4 (= 16)
|
||||||
|
MAX_VOLUNTARY_EXITS: 16
|
||||||
|
|
||||||
|
|
||||||
|
# Signature domains
|
||||||
|
# ---------------------------------------------------------------
|
||||||
DOMAIN_BEACON_PROPOSER: 0x00000000
|
DOMAIN_BEACON_PROPOSER: 0x00000000
|
||||||
DOMAIN_BEACON_ATTESTER: 0x01000000
|
DOMAIN_BEACON_ATTESTER: 0x01000000
|
||||||
DOMAIN_RANDAO: 0x02000000
|
DOMAIN_RANDAO: 0x02000000
|
||||||
DOMAIN_DEPOSIT: 0x03000000
|
DOMAIN_DEPOSIT: 0x03000000
|
||||||
DOMAIN_VOLUNTARY_EXIT: 0x04000000
|
DOMAIN_VOLUNTARY_EXIT: 0x04000000
|
||||||
JUSTIFICATION_BITS_LENGTH: 0x04000000
|
DOMAIN_SELECTION_PROOF: 0x05000000
|
||||||
MAX_VALIDATORS_PER_COMMITTEE: 2048
|
DOMAIN_AGGREGATE_AND_PROOF: 0x06000000
|
||||||
GENESIS_EPOCH: 0
|
|
||||||
SLOTS_PER_EPOCH: 32
|
|
||||||
SLOTS_PER_ETH1_VOTING_PERIOD: 1024
|
|
||||||
SLOTS_PER_HISTORICAL_ROOT: 8192
|
|
||||||
EPOCHS_PER_HISTORICAL_VECTOR: 65536
|
|
||||||
EPOCHS_PER_SLASHINGS_VECTOR: 8192
|
|
||||||
HISTORICAL_ROOTS_LIMIT: 16777216
|
|
||||||
VALIDATOR_REGISTRY_LIMIT: 1099511627776
|
|
||||||
MAX_PROPOSER_SLASHINGS: 16
|
|
||||||
MAX_ATTESTER_SLASHINGS: 2
|
|
||||||
MAX_ATTESTATIONS: 128
|
|
||||||
MAX_DEPOSITS: 16
|
|
||||||
MAX_VOLUNTARY_EXITS: 16
|
|
||||||
ETH1_FOLLOW_DISTANCE: 16
|
|
||||||
TARGET_AGGREGATORS_PER_COMMITTEE: 0
|
|
||||||
RANDOM_SUBNETS_PER_VALIDATOR: 0
|
|
||||||
EPOCHS_PER_RANDOM_SUBNET_SUBSCRIPTION: 0
|
|
||||||
SECONDS_PER_ETH1_BLOCK: 14
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
TESTS_TAG := v0.12.2
|
TESTS_TAG := v0.12.3
|
||||||
TESTS = general minimal mainnet
|
TESTS = general minimal mainnet
|
||||||
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))
|
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))
|
||||||
|
|
||||||
|
@ -140,13 +140,20 @@ impl<E: EthSpec, O: Operation<E>> LoadCase for Operations<E, O> {
|
|||||||
|
|
||||||
// Check BLS setting here before SSZ deserialization, as most types require signatures
|
// Check BLS setting here before SSZ deserialization, as most types require signatures
|
||||||
// to be valid.
|
// to be valid.
|
||||||
let operation = if metadata.bls_setting.unwrap_or_default().check().is_ok() {
|
let (operation, bls_error) = if metadata.bls_setting.unwrap_or_default().check().is_ok() {
|
||||||
Some(ssz_decode_file(&path.join(O::filename()))?)
|
match ssz_decode_file(&path.join(O::filename())) {
|
||||||
|
Ok(op) => (Some(op), None),
|
||||||
|
Err(Error::InvalidBLSInput(error)) => (None, Some(error)),
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
(None, None)
|
||||||
};
|
};
|
||||||
let post_filename = path.join("post.ssz");
|
let post_filename = path.join("post.ssz");
|
||||||
let post = if post_filename.is_file() {
|
let post = if post_filename.is_file() {
|
||||||
|
if let Some(bls_error) = bls_error {
|
||||||
|
panic!("input is unexpectedly invalid: {}", bls_error);
|
||||||
|
}
|
||||||
Some(ssz_decode_file(&post_filename)?)
|
Some(ssz_decode_file(&post_filename)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -21,11 +21,19 @@ pub fn ssz_decode_file<T: ssz::Decode>(path: &Path) -> Result<T, Error> {
|
|||||||
})
|
})
|
||||||
.and_then(|s| {
|
.and_then(|s| {
|
||||||
T::from_ssz_bytes(&s).map_err(|e| {
|
T::from_ssz_bytes(&s).map_err(|e| {
|
||||||
Error::FailedToParseTest(format!(
|
match e {
|
||||||
"Unable to parse SSZ at {}: {:?}",
|
// NOTE: this is a bit hacky, but seemingly better than the alternatives
|
||||||
path.display(),
|
ssz::DecodeError::BytesInvalid(message)
|
||||||
e
|
if message.contains("Blst") || message.contains("Milagro") =>
|
||||||
))
|
{
|
||||||
|
Error::InvalidBLSInput(message)
|
||||||
|
}
|
||||||
|
e => Error::FailedToParseTest(format!(
|
||||||
|
"Unable to parse SSZ at {}: {:?}",
|
||||||
|
path.display(),
|
||||||
|
e
|
||||||
|
)),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ pub enum Error {
|
|||||||
DidntFail(String),
|
DidntFail(String),
|
||||||
/// Failed to parse the test (internal error).
|
/// Failed to parse the test (internal error).
|
||||||
FailedToParseTest(String),
|
FailedToParseTest(String),
|
||||||
|
/// Test case contained invalid BLS data.
|
||||||
|
InvalidBLSInput(String),
|
||||||
/// Skipped the test because the BLS setting was mismatched.
|
/// Skipped the test because the BLS setting was mismatched.
|
||||||
SkippedBls,
|
SkippedBls,
|
||||||
/// Skipped the test because it's known to fail.
|
/// Skipped the test because it's known to fail.
|
||||||
@ -18,6 +20,7 @@ impl Error {
|
|||||||
Error::NotEqual(_) => "NotEqual",
|
Error::NotEqual(_) => "NotEqual",
|
||||||
Error::DidntFail(_) => "DidntFail",
|
Error::DidntFail(_) => "DidntFail",
|
||||||
Error::FailedToParseTest(_) => "FailedToParseTest",
|
Error::FailedToParseTest(_) => "FailedToParseTest",
|
||||||
|
Error::InvalidBLSInput(_) => "InvalidBLSInput",
|
||||||
Error::SkippedBls => "SkippedBls",
|
Error::SkippedBls => "SkippedBls",
|
||||||
Error::SkippedKnownFailure => "SkippedKnownFailure",
|
Error::SkippedKnownFailure => "SkippedKnownFailure",
|
||||||
}
|
}
|
||||||
@ -28,6 +31,7 @@ impl Error {
|
|||||||
Error::NotEqual(m) => m.as_str(),
|
Error::NotEqual(m) => m.as_str(),
|
||||||
Error::DidntFail(m) => m.as_str(),
|
Error::DidntFail(m) => m.as_str(),
|
||||||
Error::FailedToParseTest(m) => m.as_str(),
|
Error::FailedToParseTest(m) => m.as_str(),
|
||||||
|
Error::InvalidBLSInput(m) => m.as_str(),
|
||||||
_ => self.name(),
|
_ => self.name(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user