From a1af65ce1a75c03c6c9fead20be88bd729cb74e1 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Mon, 4 Mar 2019 17:48:19 +1100 Subject: [PATCH] Update ChainSpec to v0.4.0 --- .../src/attestation_data_and_custody_bit.rs | 3 +- eth2/types/src/beacon_block.rs | 2 +- eth2/types/src/beacon_state.rs | 20 +++-- eth2/types/src/chain_spec.rs | 73 ++++++++++--------- eth2/types/src/test_utils/mod.rs | 6 ++ eth2/types/src/validator.rs | 15 ++-- 6 files changed, 62 insertions(+), 57 deletions(-) diff --git a/eth2/types/src/attestation_data_and_custody_bit.rs b/eth2/types/src/attestation_data_and_custody_bit.rs index 2f652609e..83018c194 100644 --- a/eth2/types/src/attestation_data_and_custody_bit.rs +++ b/eth2/types/src/attestation_data_and_custody_bit.rs @@ -17,8 +17,7 @@ impl TestRandom for AttestationDataAndCustodyBit { fn random_for_test(rng: &mut T) -> Self { Self { data: <_>::random_for_test(rng), - // TODO: deal with bools - custody_bit: false, + custody_bit: <_>::random_for_test(rng), } } } diff --git a/eth2/types/src/beacon_block.rs b/eth2/types/src/beacon_block.rs index 53b0dac80..d8e50d9ca 100644 --- a/eth2/types/src/beacon_block.rs +++ b/eth2/types/src/beacon_block.rs @@ -1,5 +1,5 @@ use crate::test_utils::TestRandom; -use crate::{BeaconBlockBody, ChainSpec, Eth1Data, Hash256, ProposalSignedData, Slot}; +use crate::{BeaconBlockBody, ChainSpec, Eth1Data, Hash256, Slot}; use bls::Signature; use rand::RngCore; use serde_derive::Serialize; diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index c96beff52..b420f51d5 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -772,7 +772,7 @@ impl BeaconState { /// Update validator registry, activating/exiting validators if possible. /// - /// Spec v0.2.0 + /// Spec v0.4.0 pub fn update_validator_registry(&mut self, spec: &ChainSpec) { let current_epoch = self.current_epoch(spec); let active_validator_indices = @@ -788,8 +788,8 @@ impl BeaconState { for index in 0..self.validator_registry.len() { let validator = &self.validator_registry[index]; - if (validator.activation_epoch > self.get_entry_exit_effect_epoch(current_epoch, spec)) - && self.validator_balances[index] >= spec.max_deposit_amount + if (validator.activation_epoch == spec.far_future_epoch) + & (self.validator_balances[index] == spec.max_deposit_amount) { balance_churn += self.get_effective_balance(index, spec); if balance_churn > max_balance_churn { @@ -803,9 +803,7 @@ impl BeaconState { for index in 0..self.validator_registry.len() { let validator = &self.validator_registry[index]; - if (validator.exit_epoch > self.get_entry_exit_effect_epoch(current_epoch, spec)) - && validator.status_flags == Some(StatusFlags::InitiatedExit) - { + if (validator.exit_epoch == spec.far_future_epoch) & (validator.initiated_exit) { balance_churn += self.get_effective_balance(index, spec); if balance_churn > max_balance_churn { break; @@ -958,10 +956,9 @@ impl BeaconState { /// Initiate an exit for the validator of the given `index`. /// - /// Spec v0.2.0 + /// Spec v0.4.0 pub fn initiate_validator_exit(&mut self, validator_index: usize) { - // TODO: the spec does an `|=` here, ensure this isn't buggy. - self.validator_registry[validator_index].status_flags = Some(StatusFlags::InitiatedExit); + self.validator_registry[validator_index].initiated_exit = true; } /// Exit the validator of the given `index`. @@ -1019,9 +1016,10 @@ impl BeaconState { /// Initiate an exit for the validator of the given `index`. /// /// Spec v0.2.0 - pub fn prepare_validator_for_withdrawal(&mut self, validator_index: usize) { + pub fn prepare_validator_for_withdrawal(&mut self, validator_index: usize, spec: &ChainSpec) { //TODO: we're not ANDing here, we're setting. Potentially wrong. - self.validator_registry[validator_index].status_flags = Some(StatusFlags::Withdrawable); + self.validator_registry[validator_index].withdrawable_epoch = + self.current_epoch(spec) + spec.min_validator_withdrawability_delay; } /// Iterate through the validator registry and eject active validators with balance below diff --git a/eth2/types/src/chain_spec.rs b/eth2/types/src/chain_spec.rs index 706ad417a..ac5d0a815 100644 --- a/eth2/types/src/chain_spec.rs +++ b/eth2/types/src/chain_spec.rs @@ -5,7 +5,7 @@ const GWEI: u64 = 1_000_000_000; /// Holds all the "constants" for a BeaconChain. /// -/// Spec v0.2.0 +/// Spec v0.4.0 #[derive(PartialEq, Debug, Clone)] pub struct ChainSpec { /* @@ -16,7 +16,7 @@ pub struct ChainSpec { pub max_balance_churn_quotient: u64, pub beacon_chain_shard_number: u64, pub max_indices_per_slashable_vote: u64, - pub max_withdrawals_per_epoch: u64, + pub max_exit_dequeues_per_epoch: u64, pub shuffle_round_count: u8, /* @@ -48,13 +48,13 @@ pub struct ChainSpec { /* * Time parameters */ - pub slot_duration: u64, + pub seconds_per_slot: u64, pub min_attestation_inclusion_delay: u64, - pub epoch_length: u64, - pub seed_lookahead: Epoch, - pub entry_exit_delay: u64, - pub eth1_data_voting_period: u64, - pub min_validator_withdrawal_epochs: Epoch, + pub slots_per_epoch: u64, + pub min_seed_lookahead: Epoch, + pub activation_exit_delay: u64, + pub epochs_per_eth1_voting_period: u64, + pub min_validator_withdrawability_delay: Epoch, /* * State list lengths @@ -62,15 +62,16 @@ pub struct ChainSpec { pub latest_block_roots_length: usize, pub latest_randao_mixes_length: usize, pub latest_index_roots_length: usize, - pub latest_penalized_exit_length: usize, + pub latest_slashed_exit_length: usize, /* * Reward and penalty quotients */ pub base_reward_quotient: u64, pub whistleblower_reward_quotient: u64, - pub includer_reward_quotient: u64, + pub attestation_inclusion_reward_quotient: u64, pub inactivity_penalty_quotient: u64, + pub min_penalty_quotient: u64, /* * Max operations per block @@ -79,7 +80,8 @@ pub struct ChainSpec { pub max_attester_slashings: u64, pub max_attestations: u64, pub max_deposits: u64, - pub max_exits: u64, + pub max_voluntary_exits: u64, + pub max_transfers: u64, /* * Signature domains @@ -89,19 +91,17 @@ pub struct ChainSpec { pub domain_proposal: u64, pub domain_exit: u64, pub domain_randao: u64, + pub domain_transfer: u64, } impl ChainSpec { - /// Returns a `ChainSpec` compatible with the specification from Ethereum Foundation. + /// Returns a `ChainSpec` compatible with the Ethereum Foundation specification. /// - /// Of course, the actual foundation specs are unknown at this point so these are just a rough - /// estimate. - /// - /// Spec v0.2.0 + /// Spec v0.4.0 pub fn foundation() -> Self { - let genesis_slot = Slot::new(2_u64.pow(19)); - let epoch_length = 64; - let genesis_epoch = genesis_slot.epoch(epoch_length); + let genesis_slot = Slot::new(2_u64.pow(32)); + let slots_per_epoch = 64; + let genesis_epoch = genesis_slot.epoch(slots_per_epoch); Self { /* @@ -112,7 +112,7 @@ impl ChainSpec { max_balance_churn_quotient: 32, beacon_chain_shard_number: u64::max_value(), max_indices_per_slashable_vote: 4_096, - max_withdrawals_per_epoch: 4, + max_exit_dequeues_per_epoch: 4, shuffle_round_count: 90, /* @@ -133,7 +133,7 @@ impl ChainSpec { * Initial Values */ genesis_fork_version: 0, - genesis_slot: Slot::new(2_u64.pow(19)), + genesis_slot, genesis_epoch, genesis_start_shard: 0, far_future_epoch: Epoch::new(u64::max_value()), @@ -144,13 +144,13 @@ impl ChainSpec { /* * Time parameters */ - slot_duration: 6, + seconds_per_slot: 6, min_attestation_inclusion_delay: 4, - epoch_length, - seed_lookahead: Epoch::new(1), - entry_exit_delay: 4, - eth1_data_voting_period: 16, - min_validator_withdrawal_epochs: Epoch::new(256), + slots_per_epoch, + min_seed_lookahead: Epoch::new(1), + activation_exit_delay: 4, + epochs_per_eth1_voting_period: 16, + min_validator_withdrawability_delay: Epoch::new(256), /* * State list lengths @@ -158,15 +158,16 @@ impl ChainSpec { latest_block_roots_length: 8_192, latest_randao_mixes_length: 8_192, latest_index_roots_length: 8_192, - latest_penalized_exit_length: 8_192, + latest_slashed_exit_length: 8_192, /* * Reward and penalty quotients */ base_reward_quotient: 32, whistleblower_reward_quotient: 512, - includer_reward_quotient: 8, + attestation_inclusion_reward_quotient: 8, inactivity_penalty_quotient: 16_777_216, + min_penalty_quotient: 32, /* * Max operations per block @@ -175,7 +176,8 @@ impl ChainSpec { max_attester_slashings: 1, max_attestations: 128, max_deposits: 16, - max_exits: 16, + max_voluntary_exits: 16, + max_transfers: 16, /* * Signature domains @@ -185,6 +187,7 @@ impl ChainSpec { domain_proposal: 2, domain_exit: 3, domain_randao: 4, + domain_transfer: 5, } } } @@ -192,18 +195,18 @@ impl ChainSpec { impl ChainSpec { /// Returns a `ChainSpec` compatible with the specification suitable for 8 validators. /// - /// Spec v0.2.0 + /// Spec v0.4.0 pub fn few_validators() -> Self { - let genesis_slot = Slot::new(2_u64.pow(19)); - let epoch_length = 8; - let genesis_epoch = genesis_slot.epoch(epoch_length); + let genesis_slot = Slot::new(2_u64.pow(32)); + let slots_per_epoch = 8; + let genesis_epoch = genesis_slot.epoch(slots_per_epoch); Self { shard_count: 8, target_committee_size: 1, genesis_slot, genesis_epoch, - epoch_length, + slots_per_epoch, ..ChainSpec::foundation() } } diff --git a/eth2/types/src/test_utils/mod.rs b/eth2/types/src/test_utils/mod.rs index eb54f2a53..82e060fca 100644 --- a/eth2/types/src/test_utils/mod.rs +++ b/eth2/types/src/test_utils/mod.rs @@ -17,6 +17,12 @@ where fn random_for_test(rng: &mut T) -> Self; } +impl TestRandom for bool { + fn random_for_test(rng: &mut T) -> Self { + (rng.next_u32() % 2) == 1 + } +} + impl TestRandom for u64 { fn random_for_test(rng: &mut T) -> Self { rng.next_u64() diff --git a/eth2/types/src/validator.rs b/eth2/types/src/validator.rs index 5b5dab6bf..43701ca05 100644 --- a/eth2/types/src/validator.rs +++ b/eth2/types/src/validator.rs @@ -1,20 +1,19 @@ use crate::{test_utils::TestRandom, Epoch, Hash256, PublicKey}; use rand::RngCore; use serde_derive::Serialize; -use ssz::{hash, Decodable, DecodeError, Encodable, SszStream, TreeHash}; use ssz_derive::{Decode, Encode, TreeHash}; use test_random_derive::TestRandom; /// Information about a `BeaconChain` validator. /// /// Spec v0.4.0 -#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode, TestRandom)] +#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode, TestRandom, TreeHash)] pub struct Validator { pub pubkey: PublicKey, pub withdrawal_credentials: Hash256, pub activation_epoch: Epoch, pub exit_epoch: Epoch, - pub withdrawal_epoch: Epoch, + pub withdrawable_epoch: Epoch, pub initiated_exit: bool, pub slashed: bool, } @@ -32,7 +31,7 @@ impl Validator { /// Returns `true` if the validator is able to withdraw at some epoch. pub fn is_withdrawable_at(&self, epoch: Epoch) -> bool { - self.withdrawal_epoch <= epoch + self.withdrawable_epoch <= epoch } } @@ -44,9 +43,9 @@ impl Default for Validator { withdrawal_credentials: Hash256::default(), activation_epoch: Epoch::from(std::u64::MAX), exit_epoch: Epoch::from(std::u64::MAX), - withdrawal_epoch: Epoch::from(std::u64::MAX), - penalized_epoch: Epoch::from(std::u64::MAX), - status_flags: None, + withdrawable_epoch: Epoch::from(std::u64::MAX), + initiated_exit: false, + slashed: false, } } } @@ -55,7 +54,7 @@ impl Default for Validator { mod tests { use super::*; use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng}; - use ssz::ssz_encode; + use ssz::{ssz_encode, Decodable, TreeHash}; #[test] pub fn test_ssz_round_trip() {