From 009d05cafd12575d7112c39938ff9b46df729f34 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 7 May 2019 18:42:41 +1000 Subject: [PATCH 01/22] Implement basic FixedLenVec --- eth2/types/Cargo.toml | 1 + eth2/types/src/beacon_state.rs | 1 + eth2/types/src/beacon_state/fixed_params.rs | 72 +++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 eth2/types/src/beacon_state/fixed_params.rs diff --git a/eth2/types/Cargo.toml b/eth2/types/Cargo.toml index 36e251d7e..a2bd08d61 100644 --- a/eth2/types/Cargo.toml +++ b/eth2/types/Cargo.toml @@ -29,6 +29,7 @@ swap_or_not_shuffle = { path = "../utils/swap_or_not_shuffle" } test_random_derive = { path = "../utils/test_random_derive" } tree_hash = { path = "../utils/tree_hash" } tree_hash_derive = { path = "../utils/tree_hash_derive" } +typenum = "1.10" libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "b3c32d9a821ae6cc89079499cc6e8a6bab0bffc3" } [dev-dependencies] diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index e9b052f99..29c9d9b31 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -13,6 +13,7 @@ use tree_hash::TreeHash; use tree_hash_derive::{CachedTreeHash, TreeHash}; mod epoch_cache; +mod fixed_params; mod pubkey_cache; mod tests; diff --git a/eth2/types/src/beacon_state/fixed_params.rs b/eth2/types/src/beacon_state/fixed_params.rs new file mode 100644 index 000000000..08aa675cf --- /dev/null +++ b/eth2/types/src/beacon_state/fixed_params.rs @@ -0,0 +1,72 @@ +use std::borrow::{Borrow, BorrowMut}; +use std::marker::PhantomData; +use std::ops::{Deref, Index, IndexMut}; +use std::slice::SliceIndex; +use typenum::Unsigned; + +pub struct FixedLenVec +where + N: Unsigned, +{ + vec: Vec, + _phantom: PhantomData, +} + +impl From> for FixedLenVec { + fn from(mut vec: Vec) -> Self { + vec.resize_with(Self::capacity(), Default::default); + + Self { + vec, + _phantom: PhantomData, + } + } +} + +impl FixedLenVec { + pub fn capacity() -> usize { + N::to_usize() + } +} + +impl> Index for FixedLenVec { + type Output = I::Output; + + #[inline] + fn index(&self, index: I) -> &Self::Output { + Index::index(&self.vec, index) + } +} + +impl> IndexMut for FixedLenVec { + #[inline] + fn index_mut(&mut self, index: I) -> &mut Self::Output { + IndexMut::index_mut(&mut self.vec, index) + } +} + +#[cfg(test)] +mod test { + use super::*; + use typenum::U8192; + + #[test] + fn slice_ops() { + let vec = vec![1, 2]; + + let mut fixed: FixedLenVec = vec.clone().into(); + + assert_eq!(fixed[0], 1); + assert_eq!(&fixed[0..1], &vec[0..1]); + assert_eq!(&fixed[..], &vec[..]); + + fixed[1] = 3; + assert_eq!(fixed[1], 3); + } +} + +/* +pub trait FixedParams { + type LatestCrosslinks: +} +*/ From 5ba069c7748c696712841bad30724cfa224dbda3 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 13:08:37 +1000 Subject: [PATCH 02/22] Implement new `BeaconStateTypes` trait in `types` --- Cargo.toml | 1 + eth2/types/Cargo.toml | 2 +- eth2/types/src/attestation.rs | 2 +- eth2/types/src/attestation_data.rs | 2 +- .../src/attestation_data_and_custody_bit.rs | 5 +- eth2/types/src/attester_slashing.rs | 2 +- eth2/types/src/beacon_block.rs | 2 +- eth2/types/src/beacon_block_body.rs | 2 +- eth2/types/src/beacon_block_header.rs | 2 +- eth2/types/src/beacon_state.rs | 25 +++++-- .../src/beacon_state/beacon_state_types.rs | 15 ++++ eth2/types/src/beacon_state/epoch_cache.rs | 16 ++--- .../src/beacon_state/epoch_cache/tests.rs | 15 ++-- eth2/types/src/beacon_state/tests.rs | 12 ++-- eth2/types/src/crosslink.rs | 2 +- eth2/types/src/deposit.rs | 2 +- eth2/types/src/deposit_data.rs | 2 +- eth2/types/src/deposit_input.rs | 2 +- eth2/types/src/eth1_data.rs | 2 +- eth2/types/src/eth1_data_vote.rs | 2 +- eth2/types/src/fork.rs | 2 +- eth2/types/src/historical_batch.rs | 2 +- eth2/types/src/lib.rs | 4 +- eth2/types/src/pending_attestation.rs | 2 +- eth2/types/src/proposer_slashing.rs | 2 +- eth2/types/src/slashable_attestation.rs | 2 +- eth2/types/src/slot_epoch.rs | 23 +++--- eth2/types/src/slot_epoch_macros.rs | 4 +- eth2/types/src/slot_height.rs | 1 + eth2/types/src/test_utils/test_random.rs | 50 ++++++++----- .../src/test_utils/test_random/address.rs | 7 +- .../test_random/aggregate_signature.rs | 7 +- .../src/test_utils/test_random/bitfield.rs | 7 +- .../src/test_utils/test_random/hash256.rs | 7 +- .../src/test_utils/test_random/public_key.rs | 7 +- .../src/test_utils/test_random/secret_key.rs | 7 +- .../src/test_utils/test_random/signature.rs | 7 +- .../test_utils/testing_attestation_builder.rs | 4 +- .../testing_attestation_data_builder.rs | 7 +- .../testing_beacon_block_builder.rs | 16 ++--- .../testing_beacon_state_builder.rs | 8 +-- .../testing_pending_attestation_builder.rs | 7 +- eth2/types/src/transfer.rs | 2 +- eth2/types/src/tree_hash_vector.rs | 6 +- eth2/types/src/validator.rs | 2 +- eth2/types/src/voluntary_exit.rs | 2 +- eth2/utils/fixed_len_vec/Cargo.toml | 13 ++++ eth2/utils/fixed_len_vec/src/impls.rs | 70 +++++++++++++++++++ .../fixed_len_vec/src/lib.rs} | 57 ++++++++++++--- eth2/utils/ssz_derive/src/lib.rs | 6 +- eth2/utils/test_random_derive/src/lib.rs | 5 +- eth2/utils/tree_hash_derive/src/lib.rs | 6 +- 52 files changed, 323 insertions(+), 144 deletions(-) create mode 100644 eth2/types/src/beacon_state/beacon_state_types.rs create mode 100644 eth2/utils/fixed_len_vec/Cargo.toml create mode 100644 eth2/utils/fixed_len_vec/src/impls.rs rename eth2/{types/src/beacon_state/fixed_params.rs => utils/fixed_len_vec/src/lib.rs} (51%) diff --git a/Cargo.toml b/Cargo.toml index c05e22286..37ec4ad0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "eth2/utils/bls", "eth2/utils/boolean-bitfield", "eth2/utils/cached_tree_hash", + "eth2/utils/fixed_len_vec", "eth2/utils/hashing", "eth2/utils/honey-badger-split", "eth2/utils/merkle_proof", diff --git a/eth2/types/Cargo.toml b/eth2/types/Cargo.toml index a2bd08d61..160697edd 100644 --- a/eth2/types/Cargo.toml +++ b/eth2/types/Cargo.toml @@ -11,6 +11,7 @@ cached_tree_hash = { path = "../utils/cached_tree_hash" } dirs = "1.0" derivative = "1.0" ethereum-types = "0.5" +fixed_len_vec = { path = "../utils/fixed_len_vec" } hashing = { path = "../utils/hashing" } hex = "0.3" honey-badger-split = { path = "../utils/honey-badger-split" } @@ -29,7 +30,6 @@ swap_or_not_shuffle = { path = "../utils/swap_or_not_shuffle" } test_random_derive = { path = "../utils/test_random_derive" } tree_hash = { path = "../utils/tree_hash" } tree_hash_derive = { path = "../utils/tree_hash_derive" } -typenum = "1.10" libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "b3c32d9a821ae6cc89079499cc6e8a6bab0bffc3" } [dev-dependencies] diff --git a/eth2/types/src/attestation.rs b/eth2/types/src/attestation.rs index d1511763d..d6d5d3a22 100644 --- a/eth2/types/src/attestation.rs +++ b/eth2/types/src/attestation.rs @@ -1,6 +1,6 @@ use super::{AggregateSignature, AttestationData, Bitfield}; use crate::test_utils::TestRandom; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/attestation_data.rs b/eth2/types/src/attestation_data.rs index c963d6001..60e539ab8 100644 --- a/eth2/types/src/attestation_data.rs +++ b/eth2/types/src/attestation_data.rs @@ -1,6 +1,6 @@ use crate::test_utils::TestRandom; use crate::{Crosslink, Epoch, Hash256, Slot}; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/attestation_data_and_custody_bit.rs b/eth2/types/src/attestation_data_and_custody_bit.rs index 85a5875ab..f1437cb54 100644 --- a/eth2/types/src/attestation_data_and_custody_bit.rs +++ b/eth2/types/src/attestation_data_and_custody_bit.rs @@ -1,5 +1,6 @@ use super::AttestationData; use crate::test_utils::TestRandom; + use rand::RngCore; use serde_derive::Serialize; use ssz_derive::{Decode, Encode}; @@ -14,8 +15,8 @@ pub struct AttestationDataAndCustodyBit { pub custody_bit: bool, } -impl TestRandom for AttestationDataAndCustodyBit { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for AttestationDataAndCustodyBit { + fn random_for_test(rng: &mut impl RngCore) -> Self { Self { data: <_>::random_for_test(rng), custody_bit: <_>::random_for_test(rng), diff --git a/eth2/types/src/attester_slashing.rs b/eth2/types/src/attester_slashing.rs index d4848b01c..d7b5d5942 100644 --- a/eth2/types/src/attester_slashing.rs +++ b/eth2/types/src/attester_slashing.rs @@ -1,5 +1,5 @@ use crate::{test_utils::TestRandom, SlashableAttestation}; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/beacon_block.rs b/eth2/types/src/beacon_block.rs index d198d16fc..33d73db16 100644 --- a/eth2/types/src/beacon_block.rs +++ b/eth2/types/src/beacon_block.rs @@ -1,7 +1,7 @@ use crate::test_utils::TestRandom; use crate::*; use bls::Signature; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/beacon_block_body.rs b/eth2/types/src/beacon_block_body.rs index 15ba00d6b..867db78c4 100644 --- a/eth2/types/src/beacon_block_body.rs +++ b/eth2/types/src/beacon_block_body.rs @@ -1,6 +1,6 @@ use crate::test_utils::TestRandom; use crate::*; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/beacon_block_header.rs b/eth2/types/src/beacon_block_header.rs index 5b35da1b6..601346db5 100644 --- a/eth2/types/src/beacon_block_header.rs +++ b/eth2/types/src/beacon_block_header.rs @@ -1,7 +1,7 @@ use crate::test_utils::TestRandom; use crate::*; use bls::Signature; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index 29c9d9b31..46c4ae87d 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -4,7 +4,8 @@ use crate::*; use cached_tree_hash::{Error as TreeHashCacheError, TreeHashCache}; use int_to_bytes::int_to_bytes32; use pubkey_cache::PubkeyCache; -use rand::RngCore; + +use fixed_len_vec::FixedLenVec; use serde_derive::{Deserialize, Serialize}; use ssz::{hash, ssz_encode}; use ssz_derive::{Decode, Encode}; @@ -12,8 +13,10 @@ use test_random_derive::TestRandom; use tree_hash::TreeHash; use tree_hash_derive::{CachedTreeHash, TreeHash}; +pub use beacon_state_types::{BeaconStateTypes, FoundationBeaconState}; + +mod beacon_state_types; mod epoch_cache; -mod fixed_params; mod pubkey_cache; mod tests; @@ -62,7 +65,10 @@ pub enum Error { TreeHash, CachedTreeHash, )] -pub struct BeaconState { +pub struct BeaconState +where + T: BeaconStateTypes, +{ // Misc pub slot: Slot, pub genesis_time: u64, @@ -74,7 +80,7 @@ pub struct BeaconState { pub validator_registry_update_epoch: Epoch, // Randomness and committees - pub latest_randao_mixes: TreeHashVector, + pub latest_randao_mixes: FixedLenVec, pub previous_shuffling_start_shard: u64, pub current_shuffling_start_shard: u64, pub previous_shuffling_epoch: Epoch, @@ -134,14 +140,18 @@ pub struct BeaconState { pub tree_hash_cache: TreeHashCache, } -impl BeaconState { +impl BeaconState { /// Produce the first state of the Beacon Chain. /// /// This does not fully build a genesis beacon state, it omits processing of initial validator /// deposits. To obtain a full genesis beacon state, use the `BeaconStateBuilder`. /// /// Spec v0.5.1 - pub fn genesis(genesis_time: u64, latest_eth1_data: Eth1Data, spec: &ChainSpec) -> BeaconState { + pub fn genesis( + genesis_time: u64, + latest_eth1_data: Eth1Data, + spec: &ChainSpec, + ) -> BeaconState { let initial_crosslink = Crosslink { epoch: spec.genesis_epoch, crosslink_data_root: spec.zero_hash, @@ -425,7 +435,8 @@ impl BeaconState { & (epoch <= current_epoch) { let i = epoch.as_usize() % spec.latest_randao_mixes_length; - if i < self.latest_randao_mixes.len() { + + if i < (&self.latest_randao_mixes[..]).len() { Ok(i) } else { Err(Error::InsufficientRandaoMixes) diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs new file mode 100644 index 000000000..63c038575 --- /dev/null +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -0,0 +1,15 @@ +use crate::*; +use fixed_len_vec::typenum::{Unsigned, U8192}; + +pub trait BeaconStateTypes { + type NumLatestRandaoMixes: Unsigned + Clone + Sync + Send; +} + +#[derive(Clone, PartialEq, Debug)] +pub struct FoundationStateParams; + +impl BeaconStateTypes for FoundationStateParams { + type NumLatestRandaoMixes = U8192; +} + +pub type FoundationBeaconState = BeaconState; diff --git a/eth2/types/src/beacon_state/epoch_cache.rs b/eth2/types/src/beacon_state/epoch_cache.rs index 1a63e9eb9..31becc5d3 100644 --- a/eth2/types/src/beacon_state/epoch_cache.rs +++ b/eth2/types/src/beacon_state/epoch_cache.rs @@ -28,8 +28,8 @@ pub struct EpochCache { impl EpochCache { /// Return a new, fully initialized cache. - pub fn initialized( - state: &BeaconState, + pub fn initialized( + state: &BeaconState, relative_epoch: RelativeEpoch, spec: &ChainSpec, ) -> Result { @@ -200,8 +200,8 @@ pub struct EpochCrosslinkCommitteesBuilder { impl EpochCrosslinkCommitteesBuilder { /// Instantiates a builder that will build for the `state`'s previous epoch. - pub fn for_previous_epoch( - state: &BeaconState, + pub fn for_previous_epoch( + state: &BeaconState, active_validator_indices: Vec, spec: &ChainSpec, ) -> Self { @@ -215,8 +215,8 @@ impl EpochCrosslinkCommitteesBuilder { } /// Instantiates a builder that will build for the `state`'s next epoch. - pub fn for_current_epoch( - state: &BeaconState, + pub fn for_current_epoch( + state: &BeaconState, active_validator_indices: Vec, spec: &ChainSpec, ) -> Self { @@ -233,8 +233,8 @@ impl EpochCrosslinkCommitteesBuilder { /// /// Note: there are two possible epoch builds for the next epoch, one where there is a registry /// change and one where there is not. - pub fn for_next_epoch( - state: &BeaconState, + pub fn for_next_epoch( + state: &BeaconState, active_validator_indices: Vec, registry_change: bool, spec: &ChainSpec, diff --git a/eth2/types/src/beacon_state/epoch_cache/tests.rs b/eth2/types/src/beacon_state/epoch_cache/tests.rs index 5b1e53338..e196560a3 100644 --- a/eth2/types/src/beacon_state/epoch_cache/tests.rs +++ b/eth2/types/src/beacon_state/epoch_cache/tests.rs @@ -4,8 +4,8 @@ use super::*; use crate::test_utils::*; use swap_or_not_shuffle::shuffle_list; -fn do_sane_cache_test( - state: BeaconState, +fn do_sane_cache_test( + state: BeaconState, epoch: Epoch, relative_epoch: RelativeEpoch, validator_count: usize, @@ -64,7 +64,10 @@ fn do_sane_cache_test( } } -fn setup_sane_cache_test(validator_count: usize, spec: &ChainSpec) -> BeaconState { +fn setup_sane_cache_test( + validator_count: usize, + spec: &ChainSpec, +) -> BeaconState { let mut builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, spec); @@ -101,7 +104,7 @@ fn builds_sane_current_epoch_cache() { let mut spec = ChainSpec::few_validators(); spec.shard_count = 4; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let state = setup_sane_cache_test(validator_count as usize, &spec); + let state: FoundationBeaconState = setup_sane_cache_test(validator_count as usize, &spec); do_sane_cache_test( state.clone(), state.current_epoch(&spec), @@ -118,7 +121,7 @@ fn builds_sane_previous_epoch_cache() { let mut spec = ChainSpec::few_validators(); spec.shard_count = 2; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let state = setup_sane_cache_test(validator_count as usize, &spec); + let state: FoundationBeaconState = setup_sane_cache_test(validator_count as usize, &spec); do_sane_cache_test( state.clone(), state.previous_epoch(&spec), @@ -135,7 +138,7 @@ fn builds_sane_next_without_update_epoch_cache() { let mut spec = ChainSpec::few_validators(); spec.shard_count = 2; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let mut state = setup_sane_cache_test(validator_count as usize, &spec); + let mut state: FoundationBeaconState = setup_sane_cache_test(validator_count as usize, &spec); state.validator_registry_update_epoch = state.slot.epoch(spec.slots_per_epoch); do_sane_cache_test( state.clone(), diff --git a/eth2/types/src/beacon_state/tests.rs b/eth2/types/src/beacon_state/tests.rs index d5862559a..759061498 100644 --- a/eth2/types/src/beacon_state/tests.rs +++ b/eth2/types/src/beacon_state/tests.rs @@ -2,16 +2,16 @@ use super::*; use crate::test_utils::*; -ssz_tests!(BeaconState); -cached_tree_hash_tests!(BeaconState); +ssz_tests!(FoundationBeaconState); +cached_tree_hash_tests!(FoundationBeaconState); /// Test that /// /// 1. Using the cache before it's built fails. /// 2. Using the cache after it's build passes. /// 3. Using the cache after it's dropped fails. -fn test_cache_initialization<'a>( - state: &'a mut BeaconState, +fn test_cache_initialization<'a, T: BeaconStateTypes>( + state: &'a mut BeaconState, relative_epoch: RelativeEpoch, spec: &ChainSpec, ) { @@ -46,7 +46,7 @@ fn test_cache_initialization<'a>( #[test] fn cache_initialization() { let spec = ChainSpec::few_validators(); - let (mut state, _keypairs) = + let (mut state, _keypairs): (FoundationBeaconState, Vec) = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec).build(); state.slot = (spec.genesis_epoch + 1).start_slot(spec.slots_per_epoch); @@ -64,7 +64,7 @@ fn tree_hash_cache() { let mut rng = XorShiftRng::from_seed([42; 16]); - let mut state = BeaconState::random_for_test(&mut rng); + let mut state: FoundationBeaconState = BeaconState::random_for_test(&mut rng); let root = state.update_tree_hash_cache().unwrap(); diff --git a/eth2/types/src/crosslink.rs b/eth2/types/src/crosslink.rs index 448f5ea30..cb3ce5615 100644 --- a/eth2/types/src/crosslink.rs +++ b/eth2/types/src/crosslink.rs @@ -1,6 +1,6 @@ use crate::test_utils::TestRandom; use crate::{Epoch, Hash256}; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/deposit.rs b/eth2/types/src/deposit.rs index e8d2f5a4b..1f5d90fab 100644 --- a/eth2/types/src/deposit.rs +++ b/eth2/types/src/deposit.rs @@ -1,6 +1,6 @@ use super::{DepositData, Hash256, TreeHashVector}; use crate::test_utils::TestRandom; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/deposit_data.rs b/eth2/types/src/deposit_data.rs index 38c44d1a7..bee1d503e 100644 --- a/eth2/types/src/deposit_data.rs +++ b/eth2/types/src/deposit_data.rs @@ -1,6 +1,6 @@ use super::DepositInput; use crate::test_utils::TestRandom; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/deposit_input.rs b/eth2/types/src/deposit_input.rs index af1049a20..f44c75f5a 100644 --- a/eth2/types/src/deposit_input.rs +++ b/eth2/types/src/deposit_input.rs @@ -1,7 +1,7 @@ use crate::test_utils::TestRandom; use crate::*; use bls::{PublicKey, Signature}; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/eth1_data.rs b/eth2/types/src/eth1_data.rs index 3c0c3af02..aaf5bca54 100644 --- a/eth2/types/src/eth1_data.rs +++ b/eth2/types/src/eth1_data.rs @@ -1,6 +1,6 @@ use super::Hash256; use crate::test_utils::TestRandom; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/eth1_data_vote.rs b/eth2/types/src/eth1_data_vote.rs index 00818ebf4..27cb0be78 100644 --- a/eth2/types/src/eth1_data_vote.rs +++ b/eth2/types/src/eth1_data_vote.rs @@ -1,6 +1,6 @@ use super::Eth1Data; use crate::test_utils::TestRandom; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/fork.rs b/eth2/types/src/fork.rs index 83d4f5dc6..3e7254dd3 100644 --- a/eth2/types/src/fork.rs +++ b/eth2/types/src/fork.rs @@ -3,7 +3,7 @@ use crate::{ ChainSpec, Epoch, }; use int_to_bytes::int_to_bytes4; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/historical_batch.rs b/eth2/types/src/historical_batch.rs index 13e57131a..3f8baabbc 100644 --- a/eth2/types/src/historical_batch.rs +++ b/eth2/types/src/historical_batch.rs @@ -1,6 +1,6 @@ use crate::test_utils::TestRandom; use crate::{Hash256, TreeHashVector}; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/lib.rs b/eth2/types/src/lib.rs index 070ed6745..efe7f2327 100644 --- a/eth2/types/src/lib.rs +++ b/eth2/types/src/lib.rs @@ -36,6 +36,7 @@ pub mod slot_epoch; pub mod slot_height; pub mod validator; +use beacon_state::FoundationBeaconState; use ethereum_types::{H160, H256, U256}; use std::collections::HashMap; @@ -47,7 +48,7 @@ pub use crate::attester_slashing::AttesterSlashing; pub use crate::beacon_block::BeaconBlock; pub use crate::beacon_block_body::BeaconBlockBody; pub use crate::beacon_block_header::BeaconBlockHeader; -pub use crate::beacon_state::{BeaconState, Error as BeaconStateError}; +pub use crate::beacon_state::{BeaconState, BeaconStateTypes, Error as BeaconStateError}; pub use crate::chain_spec::{ChainSpec, Domain}; pub use crate::crosslink::Crosslink; pub use crate::crosslink_committee::CrosslinkCommittee; @@ -87,6 +88,7 @@ pub type AttesterMap = HashMap<(u64, u64), Vec>; pub type ProposerMap = HashMap; pub use bls::{AggregatePublicKey, AggregateSignature, Keypair, PublicKey, SecretKey, Signature}; +pub use fixed_len_vec::FixedLenVec; pub use libp2p::floodsub::{Topic, TopicBuilder, TopicHash}; pub use libp2p::multiaddr; pub use libp2p::Multiaddr; diff --git a/eth2/types/src/pending_attestation.rs b/eth2/types/src/pending_attestation.rs index b71351f9a..b158f1274 100644 --- a/eth2/types/src/pending_attestation.rs +++ b/eth2/types/src/pending_attestation.rs @@ -1,6 +1,6 @@ use crate::test_utils::TestRandom; use crate::{Attestation, AttestationData, Bitfield, Slot}; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/proposer_slashing.rs b/eth2/types/src/proposer_slashing.rs index bf26ae508..0c419dd56 100644 --- a/eth2/types/src/proposer_slashing.rs +++ b/eth2/types/src/proposer_slashing.rs @@ -1,6 +1,6 @@ use super::BeaconBlockHeader; use crate::test_utils::TestRandom; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/slashable_attestation.rs b/eth2/types/src/slashable_attestation.rs index fb838e0c4..19d9a87b6 100644 --- a/eth2/types/src/slashable_attestation.rs +++ b/eth2/types/src/slashable_attestation.rs @@ -1,5 +1,5 @@ use crate::{test_utils::TestRandom, AggregateSignature, AttestationData, Bitfield, ChainSpec}; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/slot_epoch.rs b/eth2/types/src/slot_epoch.rs index 6c6a92ecb..7f1f704ca 100644 --- a/eth2/types/src/slot_epoch.rs +++ b/eth2/types/src/slot_epoch.rs @@ -1,15 +1,16 @@ +//! The `Slot` and `Epoch` types are defined as newtypes over u64 to enforce type-safety between +//! the two types. +//! +//! `Slot` and `Epoch` have implementations which permit conversion, comparison and math operations +//! between each and `u64`, however specifically not between each other. +//! +//! All math operations on `Slot` and `Epoch` are saturating, they never wrap. +//! +//! It would be easy to define `PartialOrd` and other traits generically across all types which +//! implement `Into`, however this would allow operations between `Slots` and `Epochs` which +//! may lead to programming errors which are not detected by the compiler. + use crate::slot_height::SlotHeight; -/// The `Slot` and `Epoch` types are defined as newtypes over u64 to enforce type-safety between -/// the two types. -/// -/// `Slot` and `Epoch` have implementations which permit conversion, comparison and math operations -/// between each and `u64`, however specifically not between each other. -/// -/// All math operations on `Slot` and `Epoch` are saturating, they never wrap. -/// -/// It would be easy to define `PartialOrd` and other traits generically across all types which -/// implement `Into`, however this would allow operations between `Slots` and `Epochs` which -/// may lead to programming errors which are not detected by the compiler. use crate::test_utils::TestRandom; use rand::RngCore; use serde_derive::{Deserialize, Serialize}; diff --git a/eth2/types/src/slot_epoch_macros.rs b/eth2/types/src/slot_epoch_macros.rs index 4a48bba9f..076efbb77 100644 --- a/eth2/types/src/slot_epoch_macros.rs +++ b/eth2/types/src/slot_epoch_macros.rs @@ -244,8 +244,8 @@ macro_rules! impl_ssz { } } - impl TestRandom for $type { - fn random_for_test(rng: &mut T) -> Self { + impl TestRandom for $type { + fn random_for_test(rng: &mut impl RngCore) -> Self { $type::from(u64::random_for_test(rng)) } } diff --git a/eth2/types/src/slot_height.rs b/eth2/types/src/slot_height.rs index f7a34cbba..b0d5d65d9 100644 --- a/eth2/types/src/slot_height.rs +++ b/eth2/types/src/slot_height.rs @@ -1,5 +1,6 @@ use crate::slot_epoch::{Epoch, Slot}; use crate::test_utils::TestRandom; + use rand::RngCore; use serde_derive::Serialize; use ssz::{ssz_encode, Decodable, DecodeError, Encodable, SszStream}; diff --git a/eth2/types/src/test_utils/test_random.rs b/eth2/types/src/test_utils/test_random.rs index 2d4269b08..ceb785424 100644 --- a/eth2/types/src/test_utils/test_random.rs +++ b/eth2/types/src/test_utils/test_random.rs @@ -1,3 +1,5 @@ +use crate::*; +use fixed_len_vec::typenum::Unsigned; use rand::RngCore; mod address; @@ -8,42 +10,39 @@ mod public_key; mod secret_key; mod signature; -pub trait TestRandom -where - T: RngCore, -{ - fn random_for_test(rng: &mut T) -> Self; +pub trait TestRandom { + fn random_for_test(rng: &mut impl RngCore) -> Self; } -impl TestRandom for bool { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for bool { + fn random_for_test(rng: &mut impl RngCore) -> Self { (rng.next_u32() % 2) == 1 } } -impl TestRandom for u64 { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for u64 { + fn random_for_test(rng: &mut impl RngCore) -> Self { rng.next_u64() } } -impl TestRandom for u32 { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for u32 { + fn random_for_test(rng: &mut impl RngCore) -> Self { rng.next_u32() } } -impl TestRandom for usize { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for usize { + fn random_for_test(rng: &mut impl RngCore) -> Self { rng.next_u32() as usize } } -impl TestRandom for Vec +impl TestRandom for Vec where - U: TestRandom, + U: TestRandom, { - fn random_for_test(rng: &mut T) -> Self { + fn random_for_test(rng: &mut impl RngCore) -> Self { let mut output = vec![]; for _ in 0..(usize::random_for_test(rng) % 4) { @@ -54,10 +53,25 @@ where } } +impl TestRandom for FixedLenVec +where + T: TestRandom + Default, +{ + fn random_for_test(rng: &mut impl RngCore) -> Self { + let mut output = vec![]; + + for _ in 0..(usize::random_for_test(rng) % std::cmp::min(4, N::to_usize())) { + output.push(::random_for_test(rng)); + } + + output.into() + } +} + macro_rules! impl_test_random_for_u8_array { ($len: expr) => { - impl TestRandom for [u8; $len] { - fn random_for_test(rng: &mut T) -> Self { + impl TestRandom for [u8; $len] { + fn random_for_test(rng: &mut impl RngCore) -> Self { let mut bytes = [0; $len]; rng.fill_bytes(&mut bytes); bytes diff --git a/eth2/types/src/test_utils/test_random/address.rs b/eth2/types/src/test_utils/test_random/address.rs index 13de2dec9..3aaad307e 100644 --- a/eth2/types/src/test_utils/test_random/address.rs +++ b/eth2/types/src/test_utils/test_random/address.rs @@ -1,9 +1,8 @@ -use super::TestRandom; +use super::*; use crate::Address; -use rand::RngCore; -impl TestRandom for Address { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for Address { + fn random_for_test(rng: &mut impl RngCore) -> Self { let mut key_bytes = vec![0; 20]; rng.fill_bytes(&mut key_bytes); Address::from_slice(&key_bytes[..]) diff --git a/eth2/types/src/test_utils/test_random/aggregate_signature.rs b/eth2/types/src/test_utils/test_random/aggregate_signature.rs index 6a15f7366..a346d2d88 100644 --- a/eth2/types/src/test_utils/test_random/aggregate_signature.rs +++ b/eth2/types/src/test_utils/test_random/aggregate_signature.rs @@ -1,9 +1,8 @@ -use super::TestRandom; +use super::*; use bls::{AggregateSignature, Signature}; -use rand::RngCore; -impl TestRandom for AggregateSignature { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for AggregateSignature { + fn random_for_test(rng: &mut impl RngCore) -> Self { let signature = Signature::random_for_test(rng); let mut aggregate_signature = AggregateSignature::new(); aggregate_signature.add(&signature); diff --git a/eth2/types/src/test_utils/test_random/bitfield.rs b/eth2/types/src/test_utils/test_random/bitfield.rs index 9748458f1..9a4d21840 100644 --- a/eth2/types/src/test_utils/test_random/bitfield.rs +++ b/eth2/types/src/test_utils/test_random/bitfield.rs @@ -1,9 +1,8 @@ -use super::TestRandom; +use super::*; use crate::Bitfield; -use rand::RngCore; -impl TestRandom for Bitfield { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for Bitfield { + fn random_for_test(rng: &mut impl RngCore) -> Self { let mut raw_bytes = vec![0; 32]; rng.fill_bytes(&mut raw_bytes); Bitfield::from_bytes(&raw_bytes) diff --git a/eth2/types/src/test_utils/test_random/hash256.rs b/eth2/types/src/test_utils/test_random/hash256.rs index a227679da..8733f7de2 100644 --- a/eth2/types/src/test_utils/test_random/hash256.rs +++ b/eth2/types/src/test_utils/test_random/hash256.rs @@ -1,9 +1,8 @@ -use super::TestRandom; +use super::*; use crate::Hash256; -use rand::RngCore; -impl TestRandom for Hash256 { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for Hash256 { + fn random_for_test(rng: &mut impl RngCore) -> Self { let mut key_bytes = vec![0; 32]; rng.fill_bytes(&mut key_bytes); Hash256::from_slice(&key_bytes[..]) diff --git a/eth2/types/src/test_utils/test_random/public_key.rs b/eth2/types/src/test_utils/test_random/public_key.rs index bfccd3e53..d643eaf0b 100644 --- a/eth2/types/src/test_utils/test_random/public_key.rs +++ b/eth2/types/src/test_utils/test_random/public_key.rs @@ -1,9 +1,8 @@ -use super::TestRandom; +use super::*; use bls::{PublicKey, SecretKey}; -use rand::RngCore; -impl TestRandom for PublicKey { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for PublicKey { + fn random_for_test(rng: &mut impl RngCore) -> Self { let secret_key = SecretKey::random_for_test(rng); PublicKey::from_secret_key(&secret_key) } diff --git a/eth2/types/src/test_utils/test_random/secret_key.rs b/eth2/types/src/test_utils/test_random/secret_key.rs index 17481c3de..a833a4488 100644 --- a/eth2/types/src/test_utils/test_random/secret_key.rs +++ b/eth2/types/src/test_utils/test_random/secret_key.rs @@ -1,9 +1,8 @@ -use super::TestRandom; +use super::*; use bls::SecretKey; -use rand::RngCore; -impl TestRandom for SecretKey { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for SecretKey { + fn random_for_test(rng: &mut impl RngCore) -> Self { let mut key_bytes = vec![0; 48]; rng.fill_bytes(&mut key_bytes); /* diff --git a/eth2/types/src/test_utils/test_random/signature.rs b/eth2/types/src/test_utils/test_random/signature.rs index d9995835a..ef5d9a17f 100644 --- a/eth2/types/src/test_utils/test_random/signature.rs +++ b/eth2/types/src/test_utils/test_random/signature.rs @@ -1,9 +1,8 @@ -use super::TestRandom; +use super::*; use bls::{SecretKey, Signature}; -use rand::RngCore; -impl TestRandom for Signature { - fn random_for_test(rng: &mut T) -> Self { +impl TestRandom for Signature { + fn random_for_test(rng: &mut impl RngCore) -> Self { let secret_key = SecretKey::random_for_test(rng); let mut message = vec![0; 32]; rng.fill_bytes(&mut message); diff --git a/eth2/types/src/test_utils/testing_attestation_builder.rs b/eth2/types/src/test_utils/testing_attestation_builder.rs index 162facc8e..2d9b5ac6f 100644 --- a/eth2/types/src/test_utils/testing_attestation_builder.rs +++ b/eth2/types/src/test_utils/testing_attestation_builder.rs @@ -12,8 +12,8 @@ pub struct TestingAttestationBuilder { impl TestingAttestationBuilder { /// Create a new attestation builder. - pub fn new( - state: &BeaconState, + pub fn new( + state: &BeaconState, committee: &[usize], slot: Slot, shard: u64, diff --git a/eth2/types/src/test_utils/testing_attestation_data_builder.rs b/eth2/types/src/test_utils/testing_attestation_data_builder.rs index a270e3859..4cb83a6b8 100644 --- a/eth2/types/src/test_utils/testing_attestation_data_builder.rs +++ b/eth2/types/src/test_utils/testing_attestation_data_builder.rs @@ -10,7 +10,12 @@ pub struct TestingAttestationDataBuilder { impl TestingAttestationDataBuilder { /// Configures a new `AttestationData` which attests to all of the same parameters as the /// state. - pub fn new(state: &BeaconState, shard: u64, slot: Slot, spec: &ChainSpec) -> Self { + pub fn new( + state: &BeaconState, + shard: u64, + slot: Slot, + spec: &ChainSpec, + ) -> Self { let current_epoch = state.current_epoch(spec); let previous_epoch = state.previous_epoch(spec); diff --git a/eth2/types/src/test_utils/testing_beacon_block_builder.rs b/eth2/types/src/test_utils/testing_beacon_block_builder.rs index 549c00ac0..a2ea65949 100644 --- a/eth2/types/src/test_utils/testing_beacon_block_builder.rs +++ b/eth2/types/src/test_utils/testing_beacon_block_builder.rs @@ -82,9 +82,9 @@ impl TestingBeaconBlockBuilder { /// /// Note: the signed messages of the split committees will be identical -- it would be possible /// to aggregate these split attestations. - pub fn insert_attestations( + pub fn insert_attestations( &mut self, - state: &BeaconState, + state: &BeaconState, secret_keys: &[&SecretKey], num_attestations: usize, spec: &ChainSpec, @@ -171,11 +171,11 @@ impl TestingBeaconBlockBuilder { } /// Insert a `Valid` deposit into the state. - pub fn insert_deposit( + pub fn insert_deposit( &mut self, amount: u64, index: u64, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) { let keypair = Keypair::random(); @@ -193,9 +193,9 @@ impl TestingBeaconBlockBuilder { } /// Insert a `Valid` exit into the state. - pub fn insert_exit( + pub fn insert_exit( &mut self, - state: &BeaconState, + state: &BeaconState, validator_index: u64, secret_key: &SecretKey, spec: &ChainSpec, @@ -214,9 +214,9 @@ impl TestingBeaconBlockBuilder { /// /// Note: this will set the validator to be withdrawable by directly modifying the state /// validator registry. This _may_ cause problems historic hashes, etc. - pub fn insert_transfer( + pub fn insert_transfer( &mut self, - state: &BeaconState, + state: &BeaconState, from: u64, to: u64, amount: u64, diff --git a/eth2/types/src/test_utils/testing_beacon_state_builder.rs b/eth2/types/src/test_utils/testing_beacon_state_builder.rs index 9bdd9e149..67f23a44c 100644 --- a/eth2/types/src/test_utils/testing_beacon_state_builder.rs +++ b/eth2/types/src/test_utils/testing_beacon_state_builder.rs @@ -25,12 +25,12 @@ pub fn keypairs_path() -> PathBuf { /// /// This struct should **never be used for production purposes.** #[derive(Clone)] -pub struct TestingBeaconStateBuilder { - state: BeaconState, +pub struct TestingBeaconStateBuilder { + state: BeaconState, keypairs: Vec, } -impl TestingBeaconStateBuilder { +impl TestingBeaconStateBuilder { /// Attempts to load validators from a file in `$HOME/.lighthouse/keypairs.raw_keypairs`. If /// the file is unavailable, it generates the keys at runtime. /// @@ -154,7 +154,7 @@ impl TestingBeaconStateBuilder { } /// Consume the builder and return the `BeaconState` and the keypairs for each validator. - pub fn build(self) -> (BeaconState, Vec) { + pub fn build(self) -> (BeaconState, Vec) { (self.state, self.keypairs) } diff --git a/eth2/types/src/test_utils/testing_pending_attestation_builder.rs b/eth2/types/src/test_utils/testing_pending_attestation_builder.rs index 655b3d1e8..330203448 100644 --- a/eth2/types/src/test_utils/testing_pending_attestation_builder.rs +++ b/eth2/types/src/test_utils/testing_pending_attestation_builder.rs @@ -16,7 +16,12 @@ impl TestingPendingAttestationBuilder { /// /// * The aggregation and custody bitfields will all be empty, they need to be set with /// `Self::add_committee_participation`. - pub fn new(state: &BeaconState, shard: u64, slot: Slot, spec: &ChainSpec) -> Self { + pub fn new( + state: &BeaconState, + shard: u64, + slot: Slot, + spec: &ChainSpec, + ) -> Self { let data_builder = TestingAttestationDataBuilder::new(state, shard, slot, spec); let pending_attestation = PendingAttestation { diff --git a/eth2/types/src/transfer.rs b/eth2/types/src/transfer.rs index aea13fdd7..176a9d75d 100644 --- a/eth2/types/src/transfer.rs +++ b/eth2/types/src/transfer.rs @@ -2,7 +2,7 @@ use super::Slot; use crate::test_utils::TestRandom; use bls::{PublicKey, Signature}; use derivative::Derivative; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/tree_hash_vector.rs b/eth2/types/src/tree_hash_vector.rs index 42a730f25..2600ff62f 100644 --- a/eth2/types/src/tree_hash_vector.rs +++ b/eth2/types/src/tree_hash_vector.rs @@ -100,11 +100,11 @@ where } } -impl TestRandom for TreeHashVector +impl TestRandom for TreeHashVector where - U: TestRandom, + U: TestRandom, { - fn random_for_test(rng: &mut T) -> Self { + fn random_for_test(rng: &mut impl RngCore) -> Self { TreeHashVector::from(vec![ U::random_for_test(rng), U::random_for_test(rng), diff --git a/eth2/types/src/validator.rs b/eth2/types/src/validator.rs index a20eb6426..ff4cabf35 100644 --- a/eth2/types/src/validator.rs +++ b/eth2/types/src/validator.rs @@ -1,5 +1,5 @@ use crate::{test_utils::TestRandom, Epoch, Hash256, PublicKey}; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/types/src/voluntary_exit.rs b/eth2/types/src/voluntary_exit.rs index 8a780db75..a138fb480 100644 --- a/eth2/types/src/voluntary_exit.rs +++ b/eth2/types/src/voluntary_exit.rs @@ -1,6 +1,6 @@ use crate::{test_utils::TestRandom, Epoch}; use bls::Signature; -use rand::RngCore; + use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; diff --git a/eth2/utils/fixed_len_vec/Cargo.toml b/eth2/utils/fixed_len_vec/Cargo.toml new file mode 100644 index 000000000..ddfc33103 --- /dev/null +++ b/eth2/utils/fixed_len_vec/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "fixed_len_vec" +version = "0.1.0" +authors = ["Paul Hauner "] +edition = "2018" + +[dependencies] +cached_tree_hash = { path = "../cached_tree_hash" } +tree_hash = { path = "../tree_hash" } +serde = "1.0" +serde_derive = "1.0" +ssz = { path = "../ssz" } +typenum = "1.10" diff --git a/eth2/utils/fixed_len_vec/src/impls.rs b/eth2/utils/fixed_len_vec/src/impls.rs new file mode 100644 index 000000000..98c70e3eb --- /dev/null +++ b/eth2/utils/fixed_len_vec/src/impls.rs @@ -0,0 +1,70 @@ +use super::*; +// use cached_tree_hash::CachedTreeHash; +// use ssz::{Decodable, Encodable}; +// use tree_hash::TreeHash; + +impl tree_hash::TreeHash for FixedLenVec +where + T: tree_hash::TreeHash, +{ + fn tree_hash_type() -> tree_hash::TreeHashType { + tree_hash::TreeHashType::Vector + } + + fn tree_hash_packed_encoding(&self) -> Vec { + unreachable!("Vector should never be packed.") + } + + fn tree_hash_packing_factor() -> usize { + unreachable!("Vector should never be packed.") + } + + fn tree_hash_root(&self) -> Vec { + tree_hash::impls::vec_tree_hash_root(&self.vec) + } +} + +impl cached_tree_hash::CachedTreeHash for FixedLenVec +where + T: cached_tree_hash::CachedTreeHash + tree_hash::TreeHash, +{ + fn new_tree_hash_cache( + &self, + depth: usize, + ) -> Result { + let (cache, _overlay) = cached_tree_hash::vec::new_tree_hash_cache(&self.vec, depth)?; + + Ok(cache) + } + + fn tree_hash_cache_schema(&self, depth: usize) -> cached_tree_hash::BTreeSchema { + cached_tree_hash::vec::produce_schema(&self.vec, depth) + } + + fn update_tree_hash_cache( + &self, + cache: &mut cached_tree_hash::TreeHashCache, + ) -> Result<(), cached_tree_hash::Error> { + cached_tree_hash::vec::update_tree_hash_cache(&self.vec, cache)?; + + Ok(()) + } +} + +impl ssz::Encodable for FixedLenVec +where + T: ssz::Encodable, +{ + fn ssz_append(&self, s: &mut ssz::SszStream) { + s.append_vec(&self.vec) + } +} + +impl ssz::Decodable for FixedLenVec +where + T: ssz::Decodable + Default, +{ + fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), ssz::DecodeError> { + ssz::decode_ssz_list(bytes, index).and_then(|(vec, i)| Ok((vec.into(), i))) + } +} diff --git a/eth2/types/src/beacon_state/fixed_params.rs b/eth2/utils/fixed_len_vec/src/lib.rs similarity index 51% rename from eth2/types/src/beacon_state/fixed_params.rs rename to eth2/utils/fixed_len_vec/src/lib.rs index 08aa675cf..a2e73a338 100644 --- a/eth2/types/src/beacon_state/fixed_params.rs +++ b/eth2/utils/fixed_len_vec/src/lib.rs @@ -1,9 +1,14 @@ -use std::borrow::{Borrow, BorrowMut}; +use serde_derive::{Deserialize, Serialize}; use std::marker::PhantomData; -use std::ops::{Deref, Index, IndexMut}; +use std::ops::{Index, IndexMut}; use std::slice::SliceIndex; use typenum::Unsigned; +pub use typenum; + +mod impls; + +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub struct FixedLenVec where N: Unsigned, @@ -14,6 +19,7 @@ where impl From> for FixedLenVec { fn from(mut vec: Vec) -> Self { + dbg!(Self::capacity()); vec.resize_with(Self::capacity(), Default::default); Self { @@ -23,6 +29,21 @@ impl From> for FixedLenVec { } } +impl Into> for FixedLenVec { + fn into(self) -> Vec { + self.vec + } +} + +impl Default for FixedLenVec { + fn default() -> Self { + Self { + vec: Vec::default(), + _phantom: PhantomData, + } + } +} + impl FixedLenVec { pub fn capacity() -> usize { N::to_usize() @@ -48,25 +69,43 @@ impl> IndexMut for FixedLenVec { #[cfg(test)] mod test { use super::*; - use typenum::U8192; + use typenum::*; #[test] - fn slice_ops() { + fn indexing() { let vec = vec![1, 2]; let mut fixed: FixedLenVec = vec.clone().into(); assert_eq!(fixed[0], 1); assert_eq!(&fixed[0..1], &vec[0..1]); - assert_eq!(&fixed[..], &vec[..]); + assert_eq!((&fixed[..]).len(), 8192); fixed[1] = 3; assert_eq!(fixed[1], 3); } + + #[test] + fn length() { + let vec = vec![42; 5]; + let fixed: FixedLenVec = FixedLenVec::from(vec.clone()); + assert_eq!(&fixed[..], &vec[0..4]); + + let vec = vec![42; 3]; + let fixed: FixedLenVec = FixedLenVec::from(vec.clone()); + assert_eq!(&fixed[0..3], &vec[..]); + assert_eq!(&fixed[..], &vec![42, 42, 42, 0][..]); + + let vec = vec![]; + let fixed: FixedLenVec = FixedLenVec::from(vec.clone()); + assert_eq!(&fixed[..], &vec![0, 0, 0, 0][..]); + } } -/* -pub trait FixedParams { - type LatestCrosslinks: +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } } -*/ diff --git a/eth2/utils/ssz_derive/src/lib.rs b/eth2/utils/ssz_derive/src/lib.rs index c5b53e934..ebe04b322 100644 --- a/eth2/utils/ssz_derive/src/lib.rs +++ b/eth2/utils/ssz_derive/src/lib.rs @@ -100,6 +100,7 @@ pub fn ssz_encode_derive(input: TokenStream) -> TokenStream { let item = parse_macro_input!(input as DeriveInput); let name = &item.ident; + let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl(); let struct_data = match &item.data { syn::Data::Struct(s) => s, @@ -109,7 +110,7 @@ pub fn ssz_encode_derive(input: TokenStream) -> TokenStream { let field_idents = get_serializable_named_field_idents(&struct_data); let output = quote! { - impl ssz::Encodable for #name { + impl #impl_generics ssz::Encodable for #name #ty_generics #where_clause { fn ssz_append(&self, s: &mut ssz::SszStream) { #( s.append(&self.#field_idents); @@ -140,6 +141,7 @@ pub fn ssz_decode_derive(input: TokenStream) -> TokenStream { let item = parse_macro_input!(input as DeriveInput); let name = &item.ident; + let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl(); let struct_data = match &item.data { syn::Data::Struct(s) => s, @@ -169,7 +171,7 @@ pub fn ssz_decode_derive(input: TokenStream) -> TokenStream { } let output = quote! { - impl ssz::Decodable for #name { + impl #impl_generics ssz::Decodable for #name #ty_generics #where_clause { fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), ssz::DecodeError> { #( #quotes diff --git a/eth2/utils/test_random_derive/src/lib.rs b/eth2/utils/test_random_derive/src/lib.rs index 7920ea695..a268161dd 100644 --- a/eth2/utils/test_random_derive/src/lib.rs +++ b/eth2/utils/test_random_derive/src/lib.rs @@ -21,6 +21,7 @@ fn should_use_default(field: &syn::Field) -> bool { pub fn test_random_derive(input: TokenStream) -> TokenStream { let derived_input = parse_macro_input!(input as DeriveInput); let name = &derived_input.ident; + let (impl_generics, ty_generics, where_clause) = &derived_input.generics.split_for_impl(); let struct_data = match &derived_input.data { syn::Data::Struct(s) => s, @@ -48,8 +49,8 @@ pub fn test_random_derive(input: TokenStream) -> TokenStream { } let output = quote! { - impl TestRandom for #name { - fn random_for_test(rng: &mut T) -> Self { + impl #impl_generics TestRandom for #name #ty_generics #where_clause { + fn random_for_test(rng: &mut impl rand::RngCore) -> Self { Self { #( #quotes diff --git a/eth2/utils/tree_hash_derive/src/lib.rs b/eth2/utils/tree_hash_derive/src/lib.rs index 50727a89f..fe94af181 100644 --- a/eth2/utils/tree_hash_derive/src/lib.rs +++ b/eth2/utils/tree_hash_derive/src/lib.rs @@ -43,6 +43,7 @@ fn should_skip_hashing(field: &syn::Field) -> bool { #[proc_macro_derive(CachedTreeHash, attributes(tree_hash))] pub fn subtree_derive(input: TokenStream) -> TokenStream { let item = parse_macro_input!(input as DeriveInput); + let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl(); let name = &item.ident; @@ -56,7 +57,7 @@ pub fn subtree_derive(input: TokenStream) -> TokenStream { let idents_c = idents_a.clone(); let output = quote! { - impl cached_tree_hash::CachedTreeHash for #name { + impl #impl_generics cached_tree_hash::CachedTreeHash for #name #ty_generics #where_clause { fn new_tree_hash_cache(&self, depth: usize) -> Result { let tree = cached_tree_hash::TreeHashCache::from_subtrees( self, @@ -119,6 +120,7 @@ pub fn tree_hash_derive(input: TokenStream) -> TokenStream { let item = parse_macro_input!(input as DeriveInput); let name = &item.ident; + let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl(); let struct_data = match &item.data { syn::Data::Struct(s) => s, @@ -128,7 +130,7 @@ pub fn tree_hash_derive(input: TokenStream) -> TokenStream { let idents = get_hashable_named_field_idents(&struct_data); let output = quote! { - impl tree_hash::TreeHash for #name { + impl #impl_generics tree_hash::TreeHash for #name #ty_generics #where_clause { fn tree_hash_type() -> tree_hash::TreeHashType { tree_hash::TreeHashType::Container } From 7a67d34293b1121d2aa49b3eb1e446f80913ff13 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 13:26:19 +1000 Subject: [PATCH 03/22] Add `FewValidatorsBeaconState` for testing --- eth2/types/src/beacon_state.rs | 2 +- eth2/types/src/beacon_state/beacon_state_types.rs | 9 +++++++++ eth2/types/src/beacon_state/epoch_cache/tests.rs | 8 +++++--- eth2/types/src/beacon_state/tests.rs | 3 ++- eth2/types/src/lib.rs | 1 - 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index 46c4ae87d..02210443f 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -13,7 +13,7 @@ use test_random_derive::TestRandom; use tree_hash::TreeHash; use tree_hash_derive::{CachedTreeHash, TreeHash}; -pub use beacon_state_types::{BeaconStateTypes, FoundationBeaconState}; +pub use beacon_state_types::{BeaconStateTypes, FewValidatorsBeaconState, FoundationBeaconState}; mod beacon_state_types; mod epoch_cache; diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index 63c038575..887e10c84 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -13,3 +13,12 @@ impl BeaconStateTypes for FoundationStateParams { } pub type FoundationBeaconState = BeaconState; + +#[derive(Clone, PartialEq, Debug)] +pub struct FewValidatorsStateParams; + +impl BeaconStateTypes for FewValidatorsStateParams { + type NumLatestRandaoMixes = U8192; +} + +pub type FewValidatorsBeaconState = BeaconState; diff --git a/eth2/types/src/beacon_state/epoch_cache/tests.rs b/eth2/types/src/beacon_state/epoch_cache/tests.rs index e196560a3..182817bf6 100644 --- a/eth2/types/src/beacon_state/epoch_cache/tests.rs +++ b/eth2/types/src/beacon_state/epoch_cache/tests.rs @@ -1,6 +1,7 @@ #![cfg(test)] use super::*; +use crate::beacon_state::FewValidatorsBeaconState; use crate::test_utils::*; use swap_or_not_shuffle::shuffle_list; @@ -104,7 +105,7 @@ fn builds_sane_current_epoch_cache() { let mut spec = ChainSpec::few_validators(); spec.shard_count = 4; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let state: FoundationBeaconState = setup_sane_cache_test(validator_count as usize, &spec); + let state: FewValidatorsBeaconState = setup_sane_cache_test(validator_count as usize, &spec); do_sane_cache_test( state.clone(), state.current_epoch(&spec), @@ -121,7 +122,7 @@ fn builds_sane_previous_epoch_cache() { let mut spec = ChainSpec::few_validators(); spec.shard_count = 2; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let state: FoundationBeaconState = setup_sane_cache_test(validator_count as usize, &spec); + let state: FewValidatorsBeaconState = setup_sane_cache_test(validator_count as usize, &spec); do_sane_cache_test( state.clone(), state.previous_epoch(&spec), @@ -138,7 +139,8 @@ fn builds_sane_next_without_update_epoch_cache() { let mut spec = ChainSpec::few_validators(); spec.shard_count = 2; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let mut state: FoundationBeaconState = setup_sane_cache_test(validator_count as usize, &spec); + let mut state: FewValidatorsBeaconState = + setup_sane_cache_test(validator_count as usize, &spec); state.validator_registry_update_epoch = state.slot.epoch(spec.slots_per_epoch); do_sane_cache_test( state.clone(), diff --git a/eth2/types/src/beacon_state/tests.rs b/eth2/types/src/beacon_state/tests.rs index 759061498..b840663f0 100644 --- a/eth2/types/src/beacon_state/tests.rs +++ b/eth2/types/src/beacon_state/tests.rs @@ -1,5 +1,6 @@ #![cfg(test)] use super::*; +use crate::beacon_state::{FewValidatorsBeaconState, FoundationBeaconState}; use crate::test_utils::*; ssz_tests!(FoundationBeaconState); @@ -46,7 +47,7 @@ fn test_cache_initialization<'a, T: BeaconStateTypes>( #[test] fn cache_initialization() { let spec = ChainSpec::few_validators(); - let (mut state, _keypairs): (FoundationBeaconState, Vec) = + let (mut state, _keypairs): (FewValidatorsBeaconState, Vec) = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec).build(); state.slot = (spec.genesis_epoch + 1).start_slot(spec.slots_per_epoch); diff --git a/eth2/types/src/lib.rs b/eth2/types/src/lib.rs index efe7f2327..1b8ca7453 100644 --- a/eth2/types/src/lib.rs +++ b/eth2/types/src/lib.rs @@ -36,7 +36,6 @@ pub mod slot_epoch; pub mod slot_height; pub mod validator; -use beacon_state::FoundationBeaconState; use ethereum_types::{H160, H256, U256}; use std::collections::HashMap; From 8cefd20e9dc6a93e1cce9ded3b88af28a0daa8b1 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 15:36:02 +1000 Subject: [PATCH 04/22] Add progress on state_processing fixed-len update --- .../src/common/exit_validator.rs | 4 +- .../src/common/slash_validator.rs | 9 +- .../state_processing/src/get_genesis_state.rs | 6 +- .../src/per_block_processing.rs | 53 +++---- .../validate_attestation.rs | 24 ++-- .../verify_attester_slashing.rs | 12 +- .../per_block_processing/verify_deposit.rs | 19 ++- .../src/per_block_processing/verify_exit.rs | 12 +- .../verify_proposer_slashing.rs | 4 +- .../verify_slashable_attestation.rs | 4 +- .../per_block_processing/verify_transfer.rs | 16 +-- .../src/per_epoch_processing.rs | 34 ++--- .../src/per_epoch_processing/apply_rewards.rs | 26 ++-- .../get_attestation_participants.rs | 4 +- .../inclusion_distance.rs | 12 +- .../per_epoch_processing/process_ejections.rs | 5 +- .../process_exit_queue.rs | 6 +- .../per_epoch_processing/process_slashings.rs | 10 +- .../update_registry_and_shuffling_data.rs | 16 +-- .../validator_statuses.rs | 25 ++-- .../src/per_epoch_processing/winning_root.rs | 14 +- .../src/per_slot_processing.rs | 14 +- eth2/types/src/beacon_state.rs | 135 +++++++----------- .../src/beacon_state/beacon_state_types.rs | 20 ++- eth2/types/src/chain_spec.rs | 16 --- eth2/types/src/historical_batch.rs | 17 ++- eth2/types/src/lib.rs | 2 +- .../testing_attestation_data_builder.rs | 8 +- eth2/utils/fixed_len_vec/src/lib.rs | 16 ++- 29 files changed, 275 insertions(+), 268 deletions(-) diff --git a/eth2/state_processing/src/common/exit_validator.rs b/eth2/state_processing/src/common/exit_validator.rs index a6cfb395e..e71a31b65 100644 --- a/eth2/state_processing/src/common/exit_validator.rs +++ b/eth2/state_processing/src/common/exit_validator.rs @@ -3,8 +3,8 @@ use types::{BeaconStateError as Error, *}; /// Exit the validator of the given `index`. /// /// Spec v0.5.1 -pub fn exit_validator( - state: &mut BeaconState, +pub fn exit_validator( + state: &mut BeaconState, validator_index: usize, spec: &ChainSpec, ) -> Result<(), Error> { diff --git a/eth2/state_processing/src/common/slash_validator.rs b/eth2/state_processing/src/common/slash_validator.rs index c1aad7da1..bb77e914c 100644 --- a/eth2/state_processing/src/common/slash_validator.rs +++ b/eth2/state_processing/src/common/slash_validator.rs @@ -4,8 +4,8 @@ use types::{BeaconStateError as Error, *}; /// Slash the validator with index ``index``. /// /// Spec v0.5.1 -pub fn slash_validator( - state: &mut BeaconState, +pub fn slash_validator( + state: &mut BeaconState, validator_index: usize, spec: &ChainSpec, ) -> Result<(), Error> { @@ -36,8 +36,7 @@ pub fn slash_validator( state.set_slashed_balance( current_epoch, - state.get_slashed_balance(current_epoch, spec)? + effective_balance, - spec, + state.get_slashed_balance(current_epoch)? + effective_balance, )?; let whistleblower_index = @@ -56,7 +55,7 @@ pub fn slash_validator( state.validator_registry[validator_index].slashed = true; state.validator_registry[validator_index].withdrawable_epoch = - current_epoch + Epoch::from(spec.latest_slashed_exit_length); + current_epoch + Epoch::from(T::LatestSlashedExitLength::to_usize()); Ok(()) } diff --git a/eth2/state_processing/src/get_genesis_state.rs b/eth2/state_processing/src/get_genesis_state.rs index 4e9fb6caf..0960187df 100644 --- a/eth2/state_processing/src/get_genesis_state.rs +++ b/eth2/state_processing/src/get_genesis_state.rs @@ -10,12 +10,12 @@ pub enum GenesisError { /// Returns the genesis `BeaconState` /// /// Spec v0.5.1 -pub fn get_genesis_state( +pub fn get_genesis_state( genesis_validator_deposits: &[Deposit], genesis_time: u64, genesis_eth1_data: Eth1Data, spec: &ChainSpec, -) -> Result { +) -> Result, BlockProcessingError> { // Get the genesis `BeaconState` let mut state = BeaconState::genesis(genesis_time, genesis_eth1_data, spec); @@ -37,7 +37,7 @@ pub fn get_genesis_state( .get_cached_active_validator_indices(RelativeEpoch::Current, spec)? .to_vec(); let genesis_active_index_root = Hash256::from_slice(&active_validator_indices.tree_hash_root()); - state.fill_active_index_roots_with(genesis_active_index_root, spec); + state.fill_active_index_roots_with(genesis_active_index_root); // Generate the current shuffling seed. state.current_shuffling_seed = state.generate_seed(spec.genesis_epoch, spec)?; diff --git a/eth2/state_processing/src/per_block_processing.rs b/eth2/state_processing/src/per_block_processing.rs index 58b948f62..e8cf7d957 100644 --- a/eth2/state_processing/src/per_block_processing.rs +++ b/eth2/state_processing/src/per_block_processing.rs @@ -40,8 +40,8 @@ const VERIFY_DEPOSIT_MERKLE_PROOFS: bool = false; /// returns an error describing why the block was invalid or how the function failed to execute. /// /// Spec v0.5.1 -pub fn per_block_processing( - state: &mut BeaconState, +pub fn per_block_processing( + state: &mut BeaconState, block: &BeaconBlock, spec: &ChainSpec, ) -> Result<(), Error> { @@ -55,8 +55,8 @@ pub fn per_block_processing( /// returns an error describing why the block was invalid or how the function failed to execute. /// /// Spec v0.5.1 -pub fn per_block_processing_without_verifying_block_signature( - state: &mut BeaconState, +pub fn per_block_processing_without_verifying_block_signature( + state: &mut BeaconState, block: &BeaconBlock, spec: &ChainSpec, ) -> Result<(), Error> { @@ -70,8 +70,8 @@ pub fn per_block_processing_without_verifying_block_signature( /// returns an error describing why the block was invalid or how the function failed to execute. /// /// Spec v0.5.1 -fn per_block_processing_signature_optional( - mut state: &mut BeaconState, +fn per_block_processing_signature_optional( + mut state: &mut BeaconState, block: &BeaconBlock, should_verify_block_signature: bool, spec: &ChainSpec, @@ -100,8 +100,8 @@ fn per_block_processing_signature_optional( /// Processes the block header. /// /// Spec v0.5.1 -pub fn process_block_header( - state: &mut BeaconState, +pub fn process_block_header( + state: &mut BeaconState, block: &BeaconBlock, spec: &ChainSpec, ) -> Result<(), Error> { @@ -125,8 +125,8 @@ pub fn process_block_header( /// Verifies the signature of a block. /// /// Spec v0.5.1 -pub fn verify_block_signature( - state: &BeaconState, +pub fn verify_block_signature( + state: &BeaconState, block: &BeaconBlock, spec: &ChainSpec, ) -> Result<(), Error> { @@ -153,8 +153,8 @@ pub fn verify_block_signature( /// `state.latest_randao_mixes`. /// /// Spec v0.5.1 -pub fn process_randao( - state: &mut BeaconState, +pub fn process_randao( + state: &mut BeaconState, block: &BeaconBlock, spec: &ChainSpec, ) -> Result<(), Error> { @@ -184,7 +184,10 @@ pub fn process_randao( /// Update the `state.eth1_data_votes` based upon the `eth1_data` provided. /// /// Spec v0.5.1 -pub fn process_eth1_data(state: &mut BeaconState, eth1_data: &Eth1Data) -> Result<(), Error> { +pub fn process_eth1_data( + state: &mut BeaconState, + eth1_data: &Eth1Data, +) -> Result<(), Error> { // Attempt to find a `Eth1DataVote` with matching `Eth1Data`. let matching_eth1_vote_index = state .eth1_data_votes @@ -210,8 +213,8 @@ pub fn process_eth1_data(state: &mut BeaconState, eth1_data: &Eth1Data) -> Resul /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_proposer_slashings( - state: &mut BeaconState, +pub fn process_proposer_slashings( + state: &mut BeaconState, proposer_slashings: &[ProposerSlashing], spec: &ChainSpec, ) -> Result<(), Error> { @@ -243,8 +246,8 @@ pub fn process_proposer_slashings( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_attester_slashings( - state: &mut BeaconState, +pub fn process_attester_slashings( + state: &mut BeaconState, attester_slashings: &[AttesterSlashing], spec: &ChainSpec, ) -> Result<(), Error> { @@ -301,8 +304,8 @@ pub fn process_attester_slashings( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_attestations( - state: &mut BeaconState, +pub fn process_attestations( + state: &mut BeaconState, attestations: &[Attestation], spec: &ChainSpec, ) -> Result<(), Error> { @@ -343,8 +346,8 @@ pub fn process_attestations( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_deposits( - state: &mut BeaconState, +pub fn process_deposits( + state: &mut BeaconState, deposits: &[Deposit], spec: &ChainSpec, ) -> Result<(), Error> { @@ -413,8 +416,8 @@ pub fn process_deposits( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_exits( - state: &mut BeaconState, +pub fn process_exits( + state: &mut BeaconState, voluntary_exits: &[VoluntaryExit], spec: &ChainSpec, ) -> Result<(), Error> { @@ -445,8 +448,8 @@ pub fn process_exits( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_transfers( - state: &mut BeaconState, +pub fn process_transfers( + state: &mut BeaconState, transfers: &[Transfer], spec: &ChainSpec, ) -> Result<(), Error> { diff --git a/eth2/state_processing/src/per_block_processing/validate_attestation.rs b/eth2/state_processing/src/per_block_processing/validate_attestation.rs index 438a75c94..f0ec1b861 100644 --- a/eth2/state_processing/src/per_block_processing/validate_attestation.rs +++ b/eth2/state_processing/src/per_block_processing/validate_attestation.rs @@ -9,8 +9,8 @@ use types::*; /// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn validate_attestation( - state: &BeaconState, +pub fn validate_attestation( + state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, ) -> Result<(), Error> { @@ -18,8 +18,8 @@ pub fn validate_attestation( } /// Like `validate_attestation` but doesn't run checks which may become true in future states. -pub fn validate_attestation_time_independent_only( - state: &BeaconState, +pub fn validate_attestation_time_independent_only( + state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, ) -> Result<(), Error> { @@ -32,8 +32,8 @@ pub fn validate_attestation_time_independent_only( /// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn validate_attestation_without_signature( - state: &BeaconState, +pub fn validate_attestation_without_signature( + state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, ) -> Result<(), Error> { @@ -45,8 +45,8 @@ pub fn validate_attestation_without_signature( /// /// /// Spec v0.5.1 -fn validate_attestation_parametric( - state: &BeaconState, +fn validate_attestation_parametric( + state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, verify_signature: bool, @@ -168,9 +168,9 @@ fn validate_attestation_parametric( /// match the current (or previous) justified epoch and root from the state. /// /// Spec v0.5.1 -fn verify_justified_epoch_and_root( +fn verify_justified_epoch_and_root( attestation: &Attestation, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result<(), Error> { let state_epoch = state.slot.epoch(spec.slots_per_epoch); @@ -223,8 +223,8 @@ fn verify_justified_epoch_and_root( /// - A `validator_index` in `committee` is not in `state.validator_registry`. /// /// Spec v0.5.1 -fn verify_attestation_signature( - state: &BeaconState, +fn verify_attestation_signature( + state: &BeaconState, committee: &[usize], a: &Attestation, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_block_processing/verify_attester_slashing.rs b/eth2/state_processing/src/per_block_processing/verify_attester_slashing.rs index 3527b62e3..804ebd517 100644 --- a/eth2/state_processing/src/per_block_processing/verify_attester_slashing.rs +++ b/eth2/state_processing/src/per_block_processing/verify_attester_slashing.rs @@ -8,8 +8,8 @@ use types::*; /// Returns `Ok(())` if the `AttesterSlashing` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn verify_attester_slashing( - state: &BeaconState, +pub fn verify_attester_slashing( + state: &BeaconState, attester_slashing: &AttesterSlashing, should_verify_slashable_attestations: bool, spec: &ChainSpec, @@ -42,8 +42,8 @@ pub fn verify_attester_slashing( /// Returns Ok(indices) if `indices.len() > 0`. /// /// Spec v0.5.1 -pub fn gather_attester_slashing_indices( - state: &BeaconState, +pub fn gather_attester_slashing_indices( + state: &BeaconState, attester_slashing: &AttesterSlashing, spec: &ChainSpec, ) -> Result, Error> { @@ -57,8 +57,8 @@ pub fn gather_attester_slashing_indices( /// Same as `gather_attester_slashing_indices` but allows the caller to specify the criteria /// for determining whether a given validator should be considered slashed. -pub fn gather_attester_slashing_indices_modular( - state: &BeaconState, +pub fn gather_attester_slashing_indices_modular( + state: &BeaconState, attester_slashing: &AttesterSlashing, is_slashed: F, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_block_processing/verify_deposit.rs b/eth2/state_processing/src/per_block_processing/verify_deposit.rs index 22a62a321..6f810ba84 100644 --- a/eth2/state_processing/src/per_block_processing/verify_deposit.rs +++ b/eth2/state_processing/src/per_block_processing/verify_deposit.rs @@ -16,8 +16,8 @@ use types::*; /// Note: this function is incomplete. /// /// Spec v0.5.1 -pub fn verify_deposit( - state: &BeaconState, +pub fn verify_deposit( + state: &BeaconState, deposit: &Deposit, verify_merkle_branch: bool, spec: &ChainSpec, @@ -47,7 +47,10 @@ pub fn verify_deposit( /// Verify that the `Deposit` index is correct. /// /// Spec v0.5.1 -pub fn verify_deposit_index(state: &BeaconState, deposit: &Deposit) -> Result<(), Error> { +pub fn verify_deposit_index( + state: &BeaconState, + deposit: &Deposit, +) -> Result<(), Error> { verify!( deposit.index == state.deposit_index, Invalid::BadIndex { @@ -65,8 +68,8 @@ pub fn verify_deposit_index(state: &BeaconState, deposit: &Deposit) -> Result<() /// ## Errors /// /// Errors if the state's `pubkey_cache` is not current. -pub fn get_existing_validator_index( - state: &BeaconState, +pub fn get_existing_validator_index( + state: &BeaconState, deposit: &Deposit, ) -> Result, Error> { let deposit_input = &deposit.deposit_data.deposit_input; @@ -89,7 +92,11 @@ pub fn get_existing_validator_index( /// Verify that a deposit is included in the state's eth1 deposit root. /// /// Spec v0.5.1 -fn verify_deposit_merkle_proof(state: &BeaconState, deposit: &Deposit, spec: &ChainSpec) -> bool { +fn verify_deposit_merkle_proof( + state: &BeaconState, + deposit: &Deposit, + spec: &ChainSpec, +) -> bool { let leaf = hash(&get_serialized_deposit_data(deposit)); verify_merkle_proof( Hash256::from_slice(&leaf), diff --git a/eth2/state_processing/src/per_block_processing/verify_exit.rs b/eth2/state_processing/src/per_block_processing/verify_exit.rs index 697188ee9..deaf9379a 100644 --- a/eth2/state_processing/src/per_block_processing/verify_exit.rs +++ b/eth2/state_processing/src/per_block_processing/verify_exit.rs @@ -8,8 +8,8 @@ use types::*; /// Returns `Ok(())` if the `Exit` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn verify_exit( - state: &BeaconState, +pub fn verify_exit( + state: &BeaconState, exit: &VoluntaryExit, spec: &ChainSpec, ) -> Result<(), Error> { @@ -17,8 +17,8 @@ pub fn verify_exit( } /// Like `verify_exit` but doesn't run checks which may become true in future states. -pub fn verify_exit_time_independent_only( - state: &BeaconState, +pub fn verify_exit_time_independent_only( + state: &BeaconState, exit: &VoluntaryExit, spec: &ChainSpec, ) -> Result<(), Error> { @@ -26,8 +26,8 @@ pub fn verify_exit_time_independent_only( } /// Parametric version of `verify_exit` that skips some checks if `time_independent_only` is true. -fn verify_exit_parametric( - state: &BeaconState, +fn verify_exit_parametric( + state: &BeaconState, exit: &VoluntaryExit, spec: &ChainSpec, time_independent_only: bool, diff --git a/eth2/state_processing/src/per_block_processing/verify_proposer_slashing.rs b/eth2/state_processing/src/per_block_processing/verify_proposer_slashing.rs index bbc03dd62..73fffcd64 100644 --- a/eth2/state_processing/src/per_block_processing/verify_proposer_slashing.rs +++ b/eth2/state_processing/src/per_block_processing/verify_proposer_slashing.rs @@ -8,9 +8,9 @@ use types::*; /// Returns `Ok(())` if the `ProposerSlashing` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn verify_proposer_slashing( +pub fn verify_proposer_slashing( proposer_slashing: &ProposerSlashing, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result<(), Error> { let proposer = state diff --git a/eth2/state_processing/src/per_block_processing/verify_slashable_attestation.rs b/eth2/state_processing/src/per_block_processing/verify_slashable_attestation.rs index 89cb93ce5..1e52c6a41 100644 --- a/eth2/state_processing/src/per_block_processing/verify_slashable_attestation.rs +++ b/eth2/state_processing/src/per_block_processing/verify_slashable_attestation.rs @@ -11,8 +11,8 @@ use types::*; /// Returns `Ok(())` if the `SlashableAttestation` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn verify_slashable_attestation( - state: &BeaconState, +pub fn verify_slashable_attestation( + state: &BeaconState, slashable_attestation: &SlashableAttestation, spec: &ChainSpec, ) -> Result<(), Error> { diff --git a/eth2/state_processing/src/per_block_processing/verify_transfer.rs b/eth2/state_processing/src/per_block_processing/verify_transfer.rs index 8b0415508..771d350a5 100644 --- a/eth2/state_processing/src/per_block_processing/verify_transfer.rs +++ b/eth2/state_processing/src/per_block_processing/verify_transfer.rs @@ -11,8 +11,8 @@ use types::*; /// Note: this function is incomplete. /// /// Spec v0.5.1 -pub fn verify_transfer( - state: &BeaconState, +pub fn verify_transfer( + state: &BeaconState, transfer: &Transfer, spec: &ChainSpec, ) -> Result<(), Error> { @@ -20,8 +20,8 @@ pub fn verify_transfer( } /// Like `verify_transfer` but doesn't run checks which may become true in future states. -pub fn verify_transfer_time_independent_only( - state: &BeaconState, +pub fn verify_transfer_time_independent_only( + state: &BeaconState, transfer: &Transfer, spec: &ChainSpec, ) -> Result<(), Error> { @@ -29,8 +29,8 @@ pub fn verify_transfer_time_independent_only( } /// Parametric version of `verify_transfer` that allows some checks to be skipped. -fn verify_transfer_parametric( - state: &BeaconState, +fn verify_transfer_parametric( + state: &BeaconState, transfer: &Transfer, spec: &ChainSpec, time_independent_only: bool, @@ -123,8 +123,8 @@ fn verify_transfer_parametric( /// Does not check that the transfer is valid, however checks for overflow in all actions. /// /// Spec v0.5.1 -pub fn execute_transfer( - state: &mut BeaconState, +pub fn execute_transfer( + state: &mut BeaconState, transfer: &Transfer, spec: &ChainSpec, ) -> Result<(), Error> { diff --git a/eth2/state_processing/src/per_epoch_processing.rs b/eth2/state_processing/src/per_epoch_processing.rs index 87c9b9398..e2ecd47d6 100644 --- a/eth2/state_processing/src/per_epoch_processing.rs +++ b/eth2/state_processing/src/per_epoch_processing.rs @@ -33,7 +33,10 @@ pub type WinningRootHashSet = HashMap; /// returned, a state might be "half-processed" and therefore in an invalid state. /// /// Spec v0.5.1 -pub fn per_epoch_processing(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { +pub fn per_epoch_processing( + state: &mut BeaconState, + spec: &ChainSpec, +) -> Result<(), Error> { // Ensure the previous and next epoch caches are built. state.build_epoch_cache(RelativeEpoch::Previous, spec)?; state.build_epoch_cache(RelativeEpoch::Current, spec)?; @@ -87,7 +90,7 @@ pub fn per_epoch_processing(state: &mut BeaconState, spec: &ChainSpec) -> Result /// Maybe resets the eth1 period. /// /// Spec v0.5.1 -pub fn maybe_reset_eth1_period(state: &mut BeaconState, spec: &ChainSpec) { +pub fn maybe_reset_eth1_period(state: &mut BeaconState, spec: &ChainSpec) { let next_epoch = state.next_epoch(spec); let voting_period = spec.epochs_per_eth1_voting_period; @@ -109,8 +112,8 @@ pub fn maybe_reset_eth1_period(state: &mut BeaconState, spec: &ChainSpec) { /// - `previous_justified_epoch` /// /// Spec v0.5.1 -pub fn update_justification_and_finalization( - state: &mut BeaconState, +pub fn update_justification_and_finalization( + state: &mut BeaconState, total_balances: &TotalBalances, spec: &ChainSpec, ) -> Result<(), Error> { @@ -160,13 +163,13 @@ pub fn update_justification_and_finalization( if new_justified_epoch != state.current_justified_epoch { state.current_justified_epoch = new_justified_epoch; state.current_justified_root = - *state.get_block_root(new_justified_epoch.start_slot(spec.slots_per_epoch), spec)?; + *state.get_block_root(new_justified_epoch.start_slot(spec.slots_per_epoch))?; } if new_finalized_epoch != state.finalized_epoch { state.finalized_epoch = new_finalized_epoch; state.finalized_root = - *state.get_block_root(new_finalized_epoch.start_slot(spec.slots_per_epoch), spec)?; + *state.get_block_root(new_finalized_epoch.start_slot(spec.slots_per_epoch))?; } Ok(()) @@ -179,8 +182,8 @@ pub fn update_justification_and_finalization( /// Also returns a `WinningRootHashSet` for later use during epoch processing. /// /// Spec v0.5.1 -pub fn process_crosslinks( - state: &mut BeaconState, +pub fn process_crosslinks( + state: &mut BeaconState, spec: &ChainSpec, ) -> Result { let mut winning_root_for_shards: WinningRootHashSet = HashMap::new(); @@ -222,7 +225,10 @@ pub fn process_crosslinks( /// Finish up an epoch update. /// /// Spec v0.5.1 -pub fn finish_epoch_update(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { +pub fn finish_epoch_update( + state: &mut BeaconState, + spec: &ChainSpec, +) -> Result<(), Error> { let current_epoch = state.current_epoch(spec); let next_epoch = state.next_epoch(spec); @@ -241,11 +247,7 @@ pub fn finish_epoch_update(state: &mut BeaconState, spec: &ChainSpec) -> Result< state.set_active_index_root(next_epoch, active_index_root, spec)?; // Set total slashed balances - state.set_slashed_balance( - next_epoch, - state.get_slashed_balance(current_epoch, spec)?, - spec, - )?; + state.set_slashed_balance(next_epoch, state.get_slashed_balance(current_epoch)?)?; // Set randao mix state.set_randao_mix( @@ -257,8 +259,8 @@ pub fn finish_epoch_update(state: &mut BeaconState, spec: &ChainSpec) -> Result< state.slot -= 1; } - if next_epoch.as_u64() % (spec.slots_per_historical_root as u64 / spec.slots_per_epoch) == 0 { - let historical_batch: HistoricalBatch = state.historical_batch(); + if next_epoch.as_u64() % (T::SlotsPerHistoricalRoot::to_u64() / spec.slots_per_epoch) == 0 { + let historical_batch = state.historical_batch(); state .historical_roots .push(Hash256::from_slice(&historical_batch.tree_hash_root()[..])); diff --git a/eth2/state_processing/src/per_epoch_processing/apply_rewards.rs b/eth2/state_processing/src/per_epoch_processing/apply_rewards.rs index 9af1ee8c3..fe31ef244 100644 --- a/eth2/state_processing/src/per_epoch_processing/apply_rewards.rs +++ b/eth2/state_processing/src/per_epoch_processing/apply_rewards.rs @@ -33,8 +33,8 @@ impl std::ops::AddAssign for Delta { /// Apply attester and proposer rewards. /// /// Spec v0.5.1 -pub fn apply_rewards( - state: &mut BeaconState, +pub fn apply_rewards( + state: &mut BeaconState, validator_statuses: &mut ValidatorStatuses, winning_root_for_shards: &WinningRootHashSet, spec: &ChainSpec, @@ -80,9 +80,9 @@ pub fn apply_rewards( /// attestation in the previous epoch. /// /// Spec v0.5.1 -fn get_proposer_deltas( +fn get_proposer_deltas( deltas: &mut Vec, - state: &mut BeaconState, + state: &mut BeaconState, validator_statuses: &mut ValidatorStatuses, winning_root_for_shards: &WinningRootHashSet, spec: &ChainSpec, @@ -121,9 +121,9 @@ fn get_proposer_deltas( /// Apply rewards for participation in attestations during the previous epoch. /// /// Spec v0.5.1 -fn get_justification_and_finalization_deltas( +fn get_justification_and_finalization_deltas( deltas: &mut Vec, - state: &BeaconState, + state: &BeaconState, validator_statuses: &ValidatorStatuses, spec: &ChainSpec, ) -> Result<(), Error> { @@ -262,9 +262,9 @@ fn compute_inactivity_leak_delta( /// Calculate the deltas based upon the winning roots for attestations during the previous epoch. /// /// Spec v0.5.1 -fn get_crosslink_deltas( +fn get_crosslink_deltas( deltas: &mut Vec, - state: &BeaconState, + state: &BeaconState, validator_statuses: &ValidatorStatuses, spec: &ChainSpec, ) -> Result<(), Error> { @@ -296,8 +296,8 @@ fn get_crosslink_deltas( /// Returns the base reward for some validator. /// /// Spec v0.5.1 -fn get_base_reward( - state: &BeaconState, +fn get_base_reward( + state: &BeaconState, index: usize, previous_total_balance: u64, spec: &ChainSpec, @@ -313,8 +313,8 @@ fn get_base_reward( /// Returns the inactivity penalty for some validator. /// /// Spec v0.5.1 -fn get_inactivity_penalty( - state: &BeaconState, +fn get_inactivity_penalty( + state: &BeaconState, index: usize, epochs_since_finality: u64, previous_total_balance: u64, @@ -329,6 +329,6 @@ fn get_inactivity_penalty( /// Returns the epochs since the last finalized epoch. /// /// Spec v0.5.1 -fn epochs_since_finality(state: &BeaconState, spec: &ChainSpec) -> Epoch { +fn epochs_since_finality(state: &BeaconState, spec: &ChainSpec) -> Epoch { state.current_epoch(spec) + 1 - state.finalized_epoch } diff --git a/eth2/state_processing/src/per_epoch_processing/get_attestation_participants.rs b/eth2/state_processing/src/per_epoch_processing/get_attestation_participants.rs index bea772204..ddf0d680f 100644 --- a/eth2/state_processing/src/per_epoch_processing/get_attestation_participants.rs +++ b/eth2/state_processing/src/per_epoch_processing/get_attestation_participants.rs @@ -4,8 +4,8 @@ use types::*; /// Returns validator indices which participated in the attestation. /// /// Spec v0.5.1 -pub fn get_attestation_participants( - state: &BeaconState, +pub fn get_attestation_participants( + state: &BeaconState, attestation_data: &AttestationData, bitfield: &Bitfield, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_epoch_processing/inclusion_distance.rs b/eth2/state_processing/src/per_epoch_processing/inclusion_distance.rs index 6b221f513..9d4b36876 100644 --- a/eth2/state_processing/src/per_epoch_processing/inclusion_distance.rs +++ b/eth2/state_processing/src/per_epoch_processing/inclusion_distance.rs @@ -6,8 +6,8 @@ use types::*; /// slot. /// /// Spec v0.5.1 -pub fn inclusion_distance( - state: &BeaconState, +pub fn inclusion_distance( + state: &BeaconState, attestations: &[&PendingAttestation], validator_index: usize, spec: &ChainSpec, @@ -19,8 +19,8 @@ pub fn inclusion_distance( /// Returns the slot of the earliest included attestation for some validator. /// /// Spec v0.5.1 -pub fn inclusion_slot( - state: &BeaconState, +pub fn inclusion_slot( + state: &BeaconState, attestations: &[&PendingAttestation], validator_index: usize, spec: &ChainSpec, @@ -32,8 +32,8 @@ pub fn inclusion_slot( /// Finds the earliest included attestation for some validator. /// /// Spec v0.5.1 -fn earliest_included_attestation( - state: &BeaconState, +fn earliest_included_attestation( + state: &BeaconState, attestations: &[&PendingAttestation], validator_index: usize, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_epoch_processing/process_ejections.rs b/eth2/state_processing/src/per_epoch_processing/process_ejections.rs index 6f64c46f7..5a18d77be 100644 --- a/eth2/state_processing/src/per_epoch_processing/process_ejections.rs +++ b/eth2/state_processing/src/per_epoch_processing/process_ejections.rs @@ -5,7 +5,10 @@ use types::{BeaconStateError as Error, *}; /// ``EJECTION_BALANCE``. /// /// Spec v0.5.1 -pub fn process_ejections(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { +pub fn process_ejections( + state: &mut BeaconState, + spec: &ChainSpec, +) -> Result<(), Error> { // There is an awkward double (triple?) loop here because we can't loop across the borrowed // active validator indices and mutate state in the one loop. let exitable: Vec = state diff --git a/eth2/state_processing/src/per_epoch_processing/process_exit_queue.rs b/eth2/state_processing/src/per_epoch_processing/process_exit_queue.rs index a6362188d..082a64775 100644 --- a/eth2/state_processing/src/per_epoch_processing/process_exit_queue.rs +++ b/eth2/state_processing/src/per_epoch_processing/process_exit_queue.rs @@ -3,7 +3,7 @@ use types::*; /// Process the exit queue. /// /// Spec v0.5.1 -pub fn process_exit_queue(state: &mut BeaconState, spec: &ChainSpec) { +pub fn process_exit_queue(state: &mut BeaconState, spec: &ChainSpec) { let current_epoch = state.current_epoch(spec); let eligible = |index: usize| { @@ -32,8 +32,8 @@ pub fn process_exit_queue(state: &mut BeaconState, spec: &ChainSpec) { /// Initiate an exit for the validator of the given `index`. /// /// Spec v0.5.1 -fn prepare_validator_for_withdrawal( - state: &mut BeaconState, +fn prepare_validator_for_withdrawal( + state: &mut BeaconState, validator_index: usize, spec: &ChainSpec, ) { diff --git a/eth2/state_processing/src/per_epoch_processing/process_slashings.rs b/eth2/state_processing/src/per_epoch_processing/process_slashings.rs index 89a7dd484..e3a038bd7 100644 --- a/eth2/state_processing/src/per_epoch_processing/process_slashings.rs +++ b/eth2/state_processing/src/per_epoch_processing/process_slashings.rs @@ -3,20 +3,20 @@ use types::{BeaconStateError as Error, *}; /// Process slashings. /// /// Spec v0.5.1 -pub fn process_slashings( - state: &mut BeaconState, +pub fn process_slashings( + state: &mut BeaconState, current_total_balance: u64, spec: &ChainSpec, ) -> Result<(), Error> { let current_epoch = state.current_epoch(spec); - let total_at_start = state.get_slashed_balance(current_epoch + 1, spec)?; - let total_at_end = state.get_slashed_balance(current_epoch, spec)?; + let total_at_start = state.get_slashed_balance(current_epoch + 1)?; + let total_at_end = state.get_slashed_balance(current_epoch)?; let total_penalities = total_at_end - total_at_start; for (index, validator) in state.validator_registry.iter().enumerate() { let should_penalize = current_epoch.as_usize() - == validator.withdrawable_epoch.as_usize() - spec.latest_slashed_exit_length / 2; + == validator.withdrawable_epoch.as_usize() - T::LatestSlashedExitLength::to_usize() / 2; if validator.slashed && should_penalize { let effective_balance = state.get_effective_balance(index, spec)?; diff --git a/eth2/state_processing/src/per_epoch_processing/update_registry_and_shuffling_data.rs b/eth2/state_processing/src/per_epoch_processing/update_registry_and_shuffling_data.rs index d290d2987..b1e326225 100644 --- a/eth2/state_processing/src/per_epoch_processing/update_registry_and_shuffling_data.rs +++ b/eth2/state_processing/src/per_epoch_processing/update_registry_and_shuffling_data.rs @@ -5,8 +5,8 @@ use types::*; /// Peforms a validator registry update, if required. /// /// Spec v0.5.1 -pub fn update_registry_and_shuffling_data( - state: &mut BeaconState, +pub fn update_registry_and_shuffling_data( + state: &mut BeaconState, current_total_balance: u64, spec: &ChainSpec, ) -> Result<(), Error> { @@ -50,8 +50,8 @@ pub fn update_registry_and_shuffling_data( /// Returns `true` if the validator registry should be updated during an epoch processing. /// /// Spec v0.5.1 -pub fn should_update_validator_registry( - state: &BeaconState, +pub fn should_update_validator_registry( + state: &BeaconState, spec: &ChainSpec, ) -> Result { if state.finalized_epoch <= state.validator_registry_update_epoch { @@ -79,8 +79,8 @@ pub fn should_update_validator_registry( /// Note: Utilizes the cache and will fail if the appropriate cache is not initialized. /// /// Spec v0.5.1 -pub fn update_validator_registry( - state: &mut BeaconState, +pub fn update_validator_registry( + state: &mut BeaconState, current_total_balance: u64, spec: &ChainSpec, ) -> Result<(), Error> { @@ -134,8 +134,8 @@ pub fn update_validator_registry( /// Activate the validator of the given ``index``. /// /// Spec v0.5.1 -pub fn activate_validator( - state: &mut BeaconState, +pub fn activate_validator( + state: &mut BeaconState, validator_index: usize, is_genesis: bool, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs b/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs index afa78c9c0..b5fba4be1 100644 --- a/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs +++ b/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs @@ -161,7 +161,10 @@ impl ValidatorStatuses { /// - Total balances for the current and previous epochs. /// /// Spec v0.5.1 - pub fn new(state: &BeaconState, spec: &ChainSpec) -> Result { + pub fn new( + state: &BeaconState, + spec: &ChainSpec, + ) -> Result { let mut statuses = Vec::with_capacity(state.validator_registry.len()); let mut total_balances = TotalBalances::default(); @@ -196,9 +199,9 @@ impl ValidatorStatuses { /// `total_balances` fields. /// /// Spec v0.5.1 - pub fn process_attestations( + pub fn process_attestations( &mut self, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result<(), BeaconStateError> { for a in state @@ -262,9 +265,9 @@ impl ValidatorStatuses { /// "winning" shard block root for the previous epoch. /// /// Spec v0.5.1 - pub fn process_winning_roots( + pub fn process_winning_roots( &mut self, - state: &BeaconState, + state: &BeaconState, winning_roots: &WinningRootHashSet, spec: &ChainSpec, ) -> Result<(), BeaconStateError> { @@ -313,14 +316,14 @@ fn is_from_epoch(a: &PendingAttestation, epoch: Epoch, spec: &ChainSpec) -> bool /// the first slot of the given epoch. /// /// Spec v0.5.1 -fn has_common_epoch_boundary_root( +fn has_common_epoch_boundary_root( a: &PendingAttestation, - state: &BeaconState, + state: &BeaconState, epoch: Epoch, spec: &ChainSpec, ) -> Result { let slot = epoch.start_slot(spec.slots_per_epoch); - let state_boundary_root = *state.get_block_root(slot, spec)?; + let state_boundary_root = *state.get_block_root(slot)?; Ok(a.data.target_root == state_boundary_root) } @@ -329,12 +332,12 @@ fn has_common_epoch_boundary_root( /// the current slot of the `PendingAttestation`. /// /// Spec v0.5.1 -fn has_common_beacon_block_root( +fn has_common_beacon_block_root( a: &PendingAttestation, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result { - let state_block_root = *state.get_block_root(a.data.slot, spec)?; + let state_block_root = *state.get_block_root(a.data.slot)?; Ok(a.data.beacon_block_root == state_block_root) } diff --git a/eth2/state_processing/src/per_epoch_processing/winning_root.rs b/eth2/state_processing/src/per_epoch_processing/winning_root.rs index 5d31dff31..246043b05 100644 --- a/eth2/state_processing/src/per_epoch_processing/winning_root.rs +++ b/eth2/state_processing/src/per_epoch_processing/winning_root.rs @@ -35,8 +35,8 @@ impl WinningRoot { /// per-epoch processing. /// /// Spec v0.5.1 -pub fn winning_root( - state: &BeaconState, +pub fn winning_root( + state: &BeaconState, shard: u64, spec: &ChainSpec, ) -> Result, BeaconStateError> { @@ -90,7 +90,11 @@ pub fn winning_root( /// Returns `true` if pending attestation `a` is eligible to become a winning root. /// /// Spec v0.5.1 -fn is_eligible_for_winning_root(state: &BeaconState, a: &PendingAttestation, shard: Shard) -> bool { +fn is_eligible_for_winning_root( + state: &BeaconState, + a: &PendingAttestation, + shard: Shard, +) -> bool { if shard >= state.latest_crosslinks.len() as u64 { return false; } @@ -101,8 +105,8 @@ fn is_eligible_for_winning_root(state: &BeaconState, a: &PendingAttestation, sha /// Returns all indices which voted for a given crosslink. Does not contain duplicates. /// /// Spec v0.5.1 -fn get_attesting_validator_indices( - state: &BeaconState, +fn get_attesting_validator_indices( + state: &BeaconState, shard: u64, crosslink_data_root: &Hash256, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_slot_processing.rs b/eth2/state_processing/src/per_slot_processing.rs index 8f9606723..08875cf4d 100644 --- a/eth2/state_processing/src/per_slot_processing.rs +++ b/eth2/state_processing/src/per_slot_processing.rs @@ -11,7 +11,10 @@ pub enum Error { /// Advances a state forward by one slot, performing per-epoch processing if required. /// /// Spec v0.5.1 -pub fn per_slot_processing(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { +pub fn per_slot_processing( + state: &mut BeaconState, + spec: &ChainSpec, +) -> Result<(), Error> { cache_state(state, spec)?; if (state.slot + 1) % spec.slots_per_epoch == 0 { @@ -23,7 +26,10 @@ pub fn per_slot_processing(state: &mut BeaconState, spec: &ChainSpec) -> Result< Ok(()) } -fn cache_state(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { +fn cache_state( + state: &mut BeaconState, + spec: &ChainSpec, +) -> Result<(), Error> { let previous_slot_state_root = state.update_tree_hash_cache()?; // Note: increment the state slot here to allow use of our `state_root` and `block_root` @@ -39,10 +45,10 @@ fn cache_state(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { } // Store the previous slot's post state transition root. - state.set_state_root(previous_slot, previous_slot_state_root, spec)?; + state.set_state_root(previous_slot, previous_slot_state_root)?; let latest_block_root = Hash256::from_slice(&state.latest_block_header.signed_root()[..]); - state.set_block_root(previous_slot, latest_block_root, spec)?; + state.set_block_root(previous_slot, latest_block_root)?; // Set the state slot back to what it should be. state.slot -= 1; diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index 02210443f..1fc29f8e4 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -5,7 +5,7 @@ use cached_tree_hash::{Error as TreeHashCacheError, TreeHashCache}; use int_to_bytes::int_to_bytes32; use pubkey_cache::PubkeyCache; -use fixed_len_vec::FixedLenVec; +use fixed_len_vec::{typenum::Unsigned, FixedLenVec}; use serde_derive::{Deserialize, Serialize}; use ssz::{hash, ssz_encode}; use ssz_derive::{Decode, Encode}; @@ -15,7 +15,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash}; pub use beacon_state_types::{BeaconStateTypes, FewValidatorsBeaconState, FoundationBeaconState}; -mod beacon_state_types; +pub mod beacon_state_types; mod epoch_cache; mod pubkey_cache; mod tests; @@ -80,7 +80,7 @@ where pub validator_registry_update_epoch: Epoch, // Randomness and committees - pub latest_randao_mixes: FixedLenVec, + pub latest_randao_mixes: FixedLenVec, pub previous_shuffling_start_shard: u64, pub current_shuffling_start_shard: u64, pub previous_shuffling_epoch: Epoch, @@ -100,11 +100,11 @@ where pub finalized_root: Hash256, // Recent state - pub latest_crosslinks: TreeHashVector, - pub latest_block_roots: TreeHashVector, - latest_state_roots: TreeHashVector, - latest_active_index_roots: TreeHashVector, - latest_slashed_balances: TreeHashVector, + pub latest_crosslinks: FixedLenVec, + pub latest_block_roots: FixedLenVec, + latest_state_roots: FixedLenVec, + latest_active_index_roots: FixedLenVec, + latest_slashed_balances: FixedLenVec, pub latest_block_header: BeaconBlockHeader, pub historical_roots: Vec, @@ -169,8 +169,10 @@ impl BeaconState { validator_registry_update_epoch: spec.genesis_epoch, // Randomness and committees - latest_randao_mixes: vec![spec.zero_hash; spec.latest_randao_mixes_length as usize] - .into(), + latest_randao_mixes: FixedLenVec::from(vec![ + spec.zero_hash; + T::LatestRandaoMixesLength::to_usize() + ]), previous_shuffling_start_shard: spec.genesis_start_shard, current_shuffling_start_shard: spec.genesis_start_shard, previous_shuffling_epoch: spec.genesis_epoch, @@ -191,11 +193,21 @@ impl BeaconState { // Recent state latest_crosslinks: vec![initial_crosslink; spec.shard_count as usize].into(), - latest_block_roots: vec![spec.zero_hash; spec.slots_per_historical_root].into(), - latest_state_roots: vec![spec.zero_hash; spec.slots_per_historical_root].into(), - latest_active_index_roots: vec![spec.zero_hash; spec.latest_active_index_roots_length] - .into(), - latest_slashed_balances: vec![0; spec.latest_slashed_exit_length].into(), + latest_block_roots: FixedLenVec::from(vec![ + spec.zero_hash; + T::SlotsPerHistoricalRoot::to_usize() + ]), + latest_state_roots: FixedLenVec::from(vec![ + spec.zero_hash; + T::SlotsPerHistoricalRoot::to_usize() + ]), + latest_active_index_roots: FixedLenVec::from( + vec![spec.zero_hash; T::LatestActiveIndexRootsLength::to_usize()], + ), + latest_slashed_balances: FixedLenVec::from(vec![ + 0; + T::LatestSlashedExitLength::to_usize() + ]), latest_block_header: BeaconBlock::empty(spec).temporary_block_header(spec), historical_roots: vec![], @@ -228,7 +240,7 @@ impl BeaconState { Hash256::from_slice(&self.tree_hash_root()[..]) } - pub fn historical_batch(&self) -> HistoricalBatch { + pub fn historical_batch(&self) -> HistoricalBatch { HistoricalBatch { block_roots: self.latest_block_roots.clone(), state_roots: self.latest_state_roots.clone(), @@ -386,14 +398,9 @@ impl BeaconState { /// Safely obtains the index for latest block roots, given some `slot`. /// /// Spec v0.5.1 - fn get_latest_block_roots_index(&self, slot: Slot, spec: &ChainSpec) -> Result { - if (slot < self.slot) && (self.slot <= slot + spec.slots_per_historical_root as u64) { - let i = slot.as_usize() % spec.slots_per_historical_root; - if i >= self.latest_block_roots.len() { - Err(Error::InsufficientStateRoots) - } else { - Ok(i) - } + fn get_latest_block_roots_index(&self, slot: Slot) -> Result { + if (slot < self.slot) && (self.slot <= slot + self.latest_block_roots.len() as u64) { + Ok(slot.as_usize() % self.latest_block_roots.len()) } else { Err(BeaconStateError::SlotOutOfBounds) } @@ -402,12 +409,8 @@ impl BeaconState { /// Return the block root at a recent `slot`. /// /// Spec v0.5.1 - pub fn get_block_root( - &self, - slot: Slot, - spec: &ChainSpec, - ) -> Result<&Hash256, BeaconStateError> { - let i = self.get_latest_block_roots_index(slot, spec)?; + pub fn get_block_root(&self, slot: Slot) -> Result<&Hash256, BeaconStateError> { + let i = self.get_latest_block_roots_index(slot)?; Ok(&self.latest_block_roots[i]) } @@ -418,9 +421,8 @@ impl BeaconState { &mut self, slot: Slot, block_root: Hash256, - spec: &ChainSpec, ) -> Result<(), BeaconStateError> { - let i = self.get_latest_block_roots_index(slot, spec)?; + let i = self.get_latest_block_roots_index(slot)?; self.latest_block_roots[i] = block_root; Ok(()) } @@ -430,17 +432,10 @@ impl BeaconState { /// Spec v0.5.1 fn get_randao_mix_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result { let current_epoch = self.current_epoch(spec); + let len = T::LatestRandaoMixesLength::to_u64(); - if (current_epoch - (spec.latest_randao_mixes_length as u64) < epoch) - & (epoch <= current_epoch) - { - let i = epoch.as_usize() % spec.latest_randao_mixes_length; - - if i < (&self.latest_randao_mixes[..]).len() { - Ok(i) - } else { - Err(Error::InsufficientRandaoMixes) - } + if (current_epoch - len < epoch) & (epoch <= current_epoch) { + Ok(epoch.as_usize() % len as usize) } else { Err(Error::EpochOutOfBounds) } @@ -459,7 +454,7 @@ impl BeaconState { signature: &Signature, spec: &ChainSpec, ) -> Result<(), Error> { - let i = epoch.as_usize() % spec.latest_randao_mixes_length; + let i = epoch.as_usize() % T::LatestRandaoMixesLength::to_usize(); let signature_hash = Hash256::from_slice(&hash(&ssz_encode(signature))); @@ -496,17 +491,12 @@ impl BeaconState { fn get_active_index_root_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result { let current_epoch = self.current_epoch(spec); - if (current_epoch - spec.latest_active_index_roots_length as u64 + if (current_epoch - self.latest_active_index_roots.len() as u64 + spec.activation_exit_delay < epoch) & (epoch <= current_epoch + spec.activation_exit_delay) { - let i = epoch.as_usize() % spec.latest_active_index_roots_length; - if i < self.latest_active_index_roots.len() { - Ok(i) - } else { - Err(Error::InsufficientIndexRoots) - } + Ok(epoch.as_usize() % self.latest_active_index_roots.len()) } else { Err(Error::EpochOutOfBounds) } @@ -537,22 +527,17 @@ impl BeaconState { /// Replace `active_index_roots` with clones of `index_root`. /// /// Spec v0.5.1 - pub fn fill_active_index_roots_with(&mut self, index_root: Hash256, spec: &ChainSpec) { + pub fn fill_active_index_roots_with(&mut self, index_root: Hash256) { self.latest_active_index_roots = - vec![index_root; spec.latest_active_index_roots_length as usize].into() + vec![index_root; self.latest_active_index_roots.len() as usize].into() } /// Safely obtains the index for latest state roots, given some `slot`. /// /// Spec v0.5.1 - fn get_latest_state_roots_index(&self, slot: Slot, spec: &ChainSpec) -> Result { - if (slot < self.slot) && (self.slot <= slot + spec.slots_per_historical_root as u64) { - let i = slot.as_usize() % spec.slots_per_historical_root; - if i >= self.latest_state_roots.len() { - Err(Error::InsufficientStateRoots) - } else { - Ok(i) - } + fn get_latest_state_roots_index(&self, slot: Slot) -> Result { + if (slot < self.slot) && (self.slot <= slot + self.latest_state_roots.len() as u64) { + Ok(slot.as_usize() % self.latest_state_roots.len()) } else { Err(BeaconStateError::SlotOutOfBounds) } @@ -561,21 +546,16 @@ impl BeaconState { /// Gets the state root for some slot. /// /// Spec v0.5.1 - pub fn get_state_root(&mut self, slot: Slot, spec: &ChainSpec) -> Result<&Hash256, Error> { - let i = self.get_latest_state_roots_index(slot, spec)?; + pub fn get_state_root(&mut self, slot: Slot) -> Result<&Hash256, Error> { + let i = self.get_latest_state_roots_index(slot)?; Ok(&self.latest_state_roots[i]) } /// Sets the latest state root for slot. /// /// Spec v0.5.1 - pub fn set_state_root( - &mut self, - slot: Slot, - state_root: Hash256, - spec: &ChainSpec, - ) -> Result<(), Error> { - let i = self.get_latest_state_roots_index(slot, spec)?; + pub fn set_state_root(&mut self, slot: Slot, state_root: Hash256) -> Result<(), Error> { + let i = self.get_latest_state_roots_index(slot)?; self.latest_state_roots[i] = state_root; Ok(()) } @@ -583,8 +563,8 @@ impl BeaconState { /// Safely obtains the index for `latest_slashed_balances`, given some `epoch`. /// /// Spec v0.5.1 - fn get_slashed_balance_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result { - let i = epoch.as_usize() % spec.latest_slashed_exit_length; + fn get_slashed_balance_index(&self, epoch: Epoch) -> Result { + let i = epoch.as_usize() % self.latest_slashed_balances.len(); // NOTE: the validity of the epoch is not checked. It is not in the spec but it's probably // useful to have. @@ -598,21 +578,16 @@ impl BeaconState { /// Gets the total slashed balances for some epoch. /// /// Spec v0.5.1 - pub fn get_slashed_balance(&self, epoch: Epoch, spec: &ChainSpec) -> Result { - let i = self.get_slashed_balance_index(epoch, spec)?; + pub fn get_slashed_balance(&self, epoch: Epoch) -> Result { + let i = self.get_slashed_balance_index(epoch)?; Ok(self.latest_slashed_balances[i]) } /// Sets the total slashed balances for some epoch. /// /// Spec v0.5.1 - pub fn set_slashed_balance( - &mut self, - epoch: Epoch, - balance: u64, - spec: &ChainSpec, - ) -> Result<(), Error> { - let i = self.get_slashed_balance_index(epoch, spec)?; + pub fn set_slashed_balance(&mut self, epoch: Epoch, balance: u64) -> Result<(), Error> { + let i = self.get_slashed_balance_index(epoch)?; self.latest_slashed_balances[i] = balance; Ok(()) } diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index 887e10c84..41f9f44c8 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -1,15 +1,23 @@ use crate::*; -use fixed_len_vec::typenum::{Unsigned, U8192}; +use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192}; pub trait BeaconStateTypes { - type NumLatestRandaoMixes: Unsigned + Clone + Sync + Send; + type ShardCount: Unsigned + Clone + Sync + Send; + type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send; + type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send; + type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send; + type LatestSlashedExitLength: Unsigned + Clone + Sync + Send; } #[derive(Clone, PartialEq, Debug)] pub struct FoundationStateParams; impl BeaconStateTypes for FoundationStateParams { - type NumLatestRandaoMixes = U8192; + type ShardCount = U1024; + type SlotsPerHistoricalRoot = U8192; + type LatestRandaoMixesLength = U8192; + type LatestActiveIndexRootsLength = U8192; + type LatestSlashedExitLength = U8192; } pub type FoundationBeaconState = BeaconState; @@ -18,7 +26,11 @@ pub type FoundationBeaconState = BeaconState; pub struct FewValidatorsStateParams; impl BeaconStateTypes for FewValidatorsStateParams { - type NumLatestRandaoMixes = U8192; + type ShardCount = U8; + type SlotsPerHistoricalRoot = U8192; + type LatestRandaoMixesLength = U8192; + type LatestActiveIndexRootsLength = U8192; + type LatestSlashedExitLength = U8192; } pub type FewValidatorsBeaconState = BeaconState; diff --git a/eth2/types/src/chain_spec.rs b/eth2/types/src/chain_spec.rs index f3c92b42c..32f36a64d 100644 --- a/eth2/types/src/chain_spec.rs +++ b/eth2/types/src/chain_spec.rs @@ -70,17 +70,9 @@ pub struct ChainSpec { pub min_seed_lookahead: Epoch, pub activation_exit_delay: u64, pub epochs_per_eth1_voting_period: u64, - pub slots_per_historical_root: usize, pub min_validator_withdrawability_delay: Epoch, pub persistent_committee_period: u64, - /* - * State list lengths - */ - pub latest_randao_mixes_length: usize, - pub latest_active_index_roots_length: usize, - pub latest_slashed_exit_length: usize, - /* * Reward and penalty quotients */ @@ -213,17 +205,9 @@ impl ChainSpec { min_seed_lookahead: Epoch::new(1), activation_exit_delay: 4, epochs_per_eth1_voting_period: 16, - slots_per_historical_root: 8_192, min_validator_withdrawability_delay: Epoch::new(256), persistent_committee_period: 2_048, - /* - * State list lengths - */ - latest_randao_mixes_length: 8_192, - latest_active_index_roots_length: 8_192, - latest_slashed_exit_length: 8_192, - /* * Reward and penalty quotients */ diff --git a/eth2/types/src/historical_batch.rs b/eth2/types/src/historical_batch.rs index 3f8baabbc..fef6e2715 100644 --- a/eth2/types/src/historical_batch.rs +++ b/eth2/types/src/historical_batch.rs @@ -1,6 +1,8 @@ use crate::test_utils::TestRandom; -use crate::{Hash256, TreeHashVector}; +use crate::Hash256; +use crate::beacon_state::BeaconStateTypes; +use fixed_len_vec::FixedLenVec; use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use test_random_derive::TestRandom; @@ -21,15 +23,18 @@ use tree_hash_derive::{CachedTreeHash, TreeHash}; CachedTreeHash, TestRandom, )] -pub struct HistoricalBatch { - pub block_roots: TreeHashVector, - pub state_roots: TreeHashVector, +pub struct HistoricalBatch { + pub block_roots: FixedLenVec, + pub state_roots: FixedLenVec, } #[cfg(test)] mod tests { use super::*; + use crate::beacon_state::beacon_state_types::FoundationStateParams; - ssz_tests!(HistoricalBatch); - cached_tree_hash_tests!(HistoricalBatch); + pub type FoundationHistoricalBatch = HistoricalBatch; + + ssz_tests!(FoundationHistoricalBatch); + cached_tree_hash_tests!(FoundationHistoricalBatch); } diff --git a/eth2/types/src/lib.rs b/eth2/types/src/lib.rs index 1b8ca7453..03682439c 100644 --- a/eth2/types/src/lib.rs +++ b/eth2/types/src/lib.rs @@ -87,7 +87,7 @@ pub type AttesterMap = HashMap<(u64, u64), Vec>; pub type ProposerMap = HashMap; pub use bls::{AggregatePublicKey, AggregateSignature, Keypair, PublicKey, SecretKey, Signature}; -pub use fixed_len_vec::FixedLenVec; +pub use fixed_len_vec::{typenum::Unsigned, FixedLenVec}; pub use libp2p::floodsub::{Topic, TopicBuilder, TopicHash}; pub use libp2p::multiaddr; pub use libp2p::Multiaddr; diff --git a/eth2/types/src/test_utils/testing_attestation_data_builder.rs b/eth2/types/src/test_utils/testing_attestation_data_builder.rs index 4cb83a6b8..9d6bc5ec6 100644 --- a/eth2/types/src/test_utils/testing_attestation_data_builder.rs +++ b/eth2/types/src/test_utils/testing_attestation_data_builder.rs @@ -30,22 +30,22 @@ impl TestingAttestationDataBuilder { let target_root = if is_previous_epoch { *state - .get_block_root(previous_epoch.start_slot(spec.slots_per_epoch), spec) + .get_block_root(previous_epoch.start_slot(spec.slots_per_epoch)) .unwrap() } else { *state - .get_block_root(current_epoch.start_slot(spec.slots_per_epoch), spec) + .get_block_root(current_epoch.start_slot(spec.slots_per_epoch)) .unwrap() }; let source_root = *state - .get_block_root(source_epoch.start_slot(spec.slots_per_epoch), spec) + .get_block_root(source_epoch.start_slot(spec.slots_per_epoch)) .unwrap(); let data = AttestationData { // LMD GHOST vote slot, - beacon_block_root: *state.get_block_root(slot, spec).unwrap(), + beacon_block_root: *state.get_block_root(slot).unwrap(), // FFG Vote source_epoch, diff --git a/eth2/utils/fixed_len_vec/src/lib.rs b/eth2/utils/fixed_len_vec/src/lib.rs index a2e73a338..d2d4ec57c 100644 --- a/eth2/utils/fixed_len_vec/src/lib.rs +++ b/eth2/utils/fixed_len_vec/src/lib.rs @@ -17,6 +17,16 @@ where _phantom: PhantomData, } +impl FixedLenVec { + pub fn len(&self) -> usize { + self.vec.len() + } + + pub fn capacity() -> usize { + N::to_usize() + } +} + impl From> for FixedLenVec { fn from(mut vec: Vec) -> Self { dbg!(Self::capacity()); @@ -44,12 +54,6 @@ impl Default for FixedLenVec { } } -impl FixedLenVec { - pub fn capacity() -> usize { - N::to_usize() - } -} - impl> Index for FixedLenVec { type Output = I::Output; From 81c1dcceec6d6db7f47d63dc1396cad152cdc4d3 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 16:29:27 +1000 Subject: [PATCH 05/22] Add `spec` fn to `BeaconStateTypes` --- eth2/types/src/beacon_state.rs | 2 +- .../src/beacon_state/beacon_state_types.rs | 22 ++++++++++++++----- .../src/beacon_state/epoch_cache/tests.rs | 22 +++++++++++++------ eth2/types/src/beacon_state/tests.rs | 10 +++++---- eth2/types/src/chain_spec.rs | 6 ++--- eth2/types/src/historical_batch.rs | 4 ++-- 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index 1fc29f8e4..42022c89f 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -13,7 +13,7 @@ use test_random_derive::TestRandom; use tree_hash::TreeHash; use tree_hash_derive::{CachedTreeHash, TreeHash}; -pub use beacon_state_types::{BeaconStateTypes, FewValidatorsBeaconState, FoundationBeaconState}; +pub use beacon_state_types::*; pub mod beacon_state_types; mod epoch_cache; diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index 41f9f44c8..a77b4d4f1 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -7,30 +7,40 @@ pub trait BeaconStateTypes { type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send; type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send; type LatestSlashedExitLength: Unsigned + Clone + Sync + Send; + + fn spec() -> ChainSpec; } #[derive(Clone, PartialEq, Debug)] -pub struct FoundationStateParams; +pub struct FoundationStateTypes; -impl BeaconStateTypes for FoundationStateParams { +impl BeaconStateTypes for FoundationStateTypes { type ShardCount = U1024; type SlotsPerHistoricalRoot = U8192; type LatestRandaoMixesLength = U8192; type LatestActiveIndexRootsLength = U8192; type LatestSlashedExitLength = U8192; + + fn spec() -> ChainSpec { + ChainSpec::foundation() + } } -pub type FoundationBeaconState = BeaconState; +pub type FoundationBeaconState = BeaconState; #[derive(Clone, PartialEq, Debug)] -pub struct FewValidatorsStateParams; +pub struct FewValidatorsStateTypes; -impl BeaconStateTypes for FewValidatorsStateParams { +impl BeaconStateTypes for FewValidatorsStateTypes { type ShardCount = U8; type SlotsPerHistoricalRoot = U8192; type LatestRandaoMixesLength = U8192; type LatestActiveIndexRootsLength = U8192; type LatestSlashedExitLength = U8192; + + fn spec() -> ChainSpec { + ChainSpec::few_validators() + } } -pub type FewValidatorsBeaconState = BeaconState; +pub type FewValidatorsBeaconState = BeaconState; diff --git a/eth2/types/src/beacon_state/epoch_cache/tests.rs b/eth2/types/src/beacon_state/epoch_cache/tests.rs index 182817bf6..6ba7c9086 100644 --- a/eth2/types/src/beacon_state/epoch_cache/tests.rs +++ b/eth2/types/src/beacon_state/epoch_cache/tests.rs @@ -1,7 +1,7 @@ #![cfg(test)] use super::*; -use crate::beacon_state::FewValidatorsBeaconState; +use crate::beacon_state::FewValidatorsStateTypes; use crate::test_utils::*; use swap_or_not_shuffle::shuffle_list; @@ -102,10 +102,13 @@ fn setup_sane_cache_test( #[test] fn builds_sane_current_epoch_cache() { - let mut spec = ChainSpec::few_validators(); + let mut spec = FewValidatorsStateTypes::spec(); spec.shard_count = 4; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let state: FewValidatorsBeaconState = setup_sane_cache_test(validator_count as usize, &spec); + + let state: BeaconState = + setup_sane_cache_test(validator_count as usize, &spec); + do_sane_cache_test( state.clone(), state.current_epoch(&spec), @@ -119,10 +122,13 @@ fn builds_sane_current_epoch_cache() { #[test] fn builds_sane_previous_epoch_cache() { - let mut spec = ChainSpec::few_validators(); + let mut spec = FewValidatorsStateTypes::spec(); spec.shard_count = 2; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let state: FewValidatorsBeaconState = setup_sane_cache_test(validator_count as usize, &spec); + + let state: BeaconState = + setup_sane_cache_test(validator_count as usize, &spec); + do_sane_cache_test( state.clone(), state.previous_epoch(&spec), @@ -136,11 +142,13 @@ fn builds_sane_previous_epoch_cache() { #[test] fn builds_sane_next_without_update_epoch_cache() { - let mut spec = ChainSpec::few_validators(); + let mut spec = FewValidatorsStateTypes::spec(); spec.shard_count = 2; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let mut state: FewValidatorsBeaconState = + + let mut state: BeaconState = setup_sane_cache_test(validator_count as usize, &spec); + state.validator_registry_update_epoch = state.slot.epoch(spec.slots_per_epoch); do_sane_cache_test( state.clone(), diff --git a/eth2/types/src/beacon_state/tests.rs b/eth2/types/src/beacon_state/tests.rs index b840663f0..8948a94f6 100644 --- a/eth2/types/src/beacon_state/tests.rs +++ b/eth2/types/src/beacon_state/tests.rs @@ -1,6 +1,6 @@ #![cfg(test)] use super::*; -use crate::beacon_state::{FewValidatorsBeaconState, FoundationBeaconState}; +use crate::beacon_state::FewValidatorsStateTypes; use crate::test_utils::*; ssz_tests!(FoundationBeaconState); @@ -46,9 +46,11 @@ fn test_cache_initialization<'a, T: BeaconStateTypes>( #[test] fn cache_initialization() { - let spec = ChainSpec::few_validators(); - let (mut state, _keypairs): (FewValidatorsBeaconState, Vec) = - TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec).build(); + let spec = FewValidatorsStateTypes::spec(); + + let builder: TestingBeaconStateBuilder = + TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec); + let (mut state, _keypairs) = builder.build(); state.slot = (spec.genesis_epoch + 1).start_slot(spec.slots_per_epoch); diff --git a/eth2/types/src/chain_spec.rs b/eth2/types/src/chain_spec.rs index 32f36a64d..974bcfc4a 100644 --- a/eth2/types/src/chain_spec.rs +++ b/eth2/types/src/chain_spec.rs @@ -154,7 +154,7 @@ impl ChainSpec { /// Returns a `ChainSpec` compatible with the Ethereum Foundation specification. /// /// Spec v0.5.1 - pub fn foundation() -> Self { + pub(crate) fn foundation() -> Self { let genesis_slot = Slot::new(2_u64.pow(32)); let slots_per_epoch = 64; let genesis_epoch = genesis_slot.epoch(slots_per_epoch); @@ -248,7 +248,7 @@ impl ChainSpec { /// Returns a `ChainSpec` compatible with the Lighthouse testnet specification. /// /// Spec v0.4.0 - pub fn lighthouse_testnet() -> Self { + pub(crate) fn lighthouse_testnet() -> Self { /* * Lighthouse testnet bootnodes */ @@ -264,7 +264,7 @@ impl ChainSpec { } /// Returns a `ChainSpec` compatible with the specification suitable for 8 validators. - pub fn few_validators() -> Self { + pub(crate) fn few_validators() -> Self { let genesis_slot = Slot::new(2_u64.pow(32)); let slots_per_epoch = 8; let genesis_epoch = genesis_slot.epoch(slots_per_epoch); diff --git a/eth2/types/src/historical_batch.rs b/eth2/types/src/historical_batch.rs index fef6e2715..f9886b8c8 100644 --- a/eth2/types/src/historical_batch.rs +++ b/eth2/types/src/historical_batch.rs @@ -31,9 +31,9 @@ pub struct HistoricalBatch { #[cfg(test)] mod tests { use super::*; - use crate::beacon_state::beacon_state_types::FoundationStateParams; + use crate::beacon_state::beacon_state_types::FoundationStateTypes; - pub type FoundationHistoricalBatch = HistoricalBatch; + pub type FoundationHistoricalBatch = HistoricalBatch; ssz_tests!(FoundationHistoricalBatch); cached_tree_hash_tests!(FoundationHistoricalBatch); From 6ea538938bd35176274dd1e6282c8fdceb2d6bb9 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 16:35:22 +1000 Subject: [PATCH 06/22] Fix `state_processing` under new `BeaconStateTypes` --- eth2/state_processing/src/per_epoch_processing/tests.rs | 5 +++-- .../src/per_epoch_processing/validator_statuses.rs | 3 +-- eth2/types/src/beacon_state.rs | 2 +- eth2/types/src/lib.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eth2/state_processing/src/per_epoch_processing/tests.rs b/eth2/state_processing/src/per_epoch_processing/tests.rs index 69450edcd..bbbd7d7c5 100644 --- a/eth2/state_processing/src/per_epoch_processing/tests.rs +++ b/eth2/state_processing/src/per_epoch_processing/tests.rs @@ -8,9 +8,10 @@ use types::*; fn runs_without_error() { Builder::from_env(Env::default().default_filter_or("error")).init(); - let spec = ChainSpec::few_validators(); + let spec = FewValidatorsStateTypes::spec(); - let mut builder = TestingBeaconStateBuilder::from_deterministic_keypairs(8, &spec); + let mut builder: TestingBeaconStateBuilder = + TestingBeaconStateBuilder::from_deterministic_keypairs(8, &spec); let target_slot = (spec.genesis_epoch + 4).end_slot(spec.slots_per_epoch); builder.teleport_to_slot(target_slot, &spec); diff --git a/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs b/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs index b5fba4be1..038737fd9 100644 --- a/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs +++ b/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs @@ -246,7 +246,7 @@ impl ValidatorStatuses { status.is_previous_epoch_boundary_attester = true; } - if has_common_beacon_block_root(a, state, spec)? { + if has_common_beacon_block_root(a, state)? { self.total_balances.previous_epoch_head_attesters += attesting_balance; status.is_previous_epoch_head_attester = true; } @@ -335,7 +335,6 @@ fn has_common_epoch_boundary_root( fn has_common_beacon_block_root( a: &PendingAttestation, state: &BeaconState, - spec: &ChainSpec, ) -> Result { let state_block_root = *state.get_block_root(a.data.slot)?; diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index 42022c89f..3dc5358c8 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -15,7 +15,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash}; pub use beacon_state_types::*; -pub mod beacon_state_types; +mod beacon_state_types; mod epoch_cache; mod pubkey_cache; mod tests; diff --git a/eth2/types/src/lib.rs b/eth2/types/src/lib.rs index 03682439c..99e64e823 100644 --- a/eth2/types/src/lib.rs +++ b/eth2/types/src/lib.rs @@ -47,7 +47,7 @@ pub use crate::attester_slashing::AttesterSlashing; pub use crate::beacon_block::BeaconBlock; pub use crate::beacon_block_body::BeaconBlockBody; pub use crate::beacon_block_header::BeaconBlockHeader; -pub use crate::beacon_state::{BeaconState, BeaconStateTypes, Error as BeaconStateError}; +pub use crate::beacon_state::{Error as BeaconStateError, *}; pub use crate::chain_spec::{ChainSpec, Domain}; pub use crate::crosslink::Crosslink; pub use crate::crosslink_committee::CrosslinkCommittee; From ae09a0009014f2a507acfaeb0015beba1cd00d29 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 17:06:39 +1000 Subject: [PATCH 07/22] Update `db` crate for new `BeaconStateTypes` --- beacon_node/db/src/stores/beacon_state_store.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/beacon_node/db/src/stores/beacon_state_store.rs b/beacon_node/db/src/stores/beacon_state_store.rs index bb046a113..5a5af33d3 100644 --- a/beacon_node/db/src/stores/beacon_state_store.rs +++ b/beacon_node/db/src/stores/beacon_state_store.rs @@ -2,7 +2,7 @@ use super::STATES_DB_COLUMN as DB_COLUMN; use super::{ClientDB, DBError}; use ssz::decode; use std::sync::Arc; -use types::{BeaconState, Hash256}; +use types::{BeaconState, BeaconStateTypes, FoundationBeaconState, Hash256}; pub struct BeaconStateStore where @@ -19,11 +19,14 @@ impl BeaconStateStore { Self { db } } - pub fn get_deserialized(&self, hash: &Hash256) -> Result, DBError> { + pub fn get_deserialized( + &self, + hash: &Hash256, + ) -> Result>, DBError> { match self.get(&hash)? { None => Ok(None), Some(ssz) => { - let state = decode::(&ssz).map_err(|_| DBError { + let state = decode::>(&ssz).map_err(|_| DBError { message: "Bad State SSZ.".to_string(), })?; Ok(Some(state)) @@ -50,7 +53,7 @@ mod tests { let store = BeaconStateStore::new(db.clone()); let mut rng = XorShiftRng::from_seed([42; 16]); - let state = BeaconState::random_for_test(&mut rng); + let state: FoundationBeaconState = BeaconState::random_for_test(&mut rng); let state_root = state.canonical_root(); store.put(&state_root, &ssz_encode(&state)).unwrap(); From 9fd8af8428f9d1fc9ace23567fd87486a6fbf7a2 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 17:07:26 +1000 Subject: [PATCH 08/22] Update `operations_pool` for new `BeaconStateTypes` --- eth2/operation_pool/src/lib.rs | 95 ++++++++++++------- .../src/beacon_state/beacon_state_types.rs | 6 +- eth2/types/src/historical_batch.rs | 4 +- 3 files changed, 65 insertions(+), 40 deletions(-) diff --git a/eth2/operation_pool/src/lib.rs b/eth2/operation_pool/src/lib.rs index 69a1ccc0b..eed46196a 100644 --- a/eth2/operation_pool/src/lib.rs +++ b/eth2/operation_pool/src/lib.rs @@ -13,10 +13,11 @@ use state_processing::per_block_processing::{ verify_transfer_time_independent_only, }; use std::collections::{btree_map::Entry, hash_map, BTreeMap, HashMap, HashSet}; +use std::marker::PhantomData; use types::chain_spec::Domain; use types::{ - Attestation, AttestationData, AttesterSlashing, BeaconState, ChainSpec, Deposit, Epoch, - ProposerSlashing, Transfer, Validator, VoluntaryExit, + Attestation, AttestationData, AttesterSlashing, BeaconState, BeaconStateTypes, ChainSpec, + Deposit, Epoch, ProposerSlashing, Transfer, Validator, VoluntaryExit, }; #[cfg(test)] @@ -25,7 +26,7 @@ const VERIFY_DEPOSIT_PROOFS: bool = false; const VERIFY_DEPOSIT_PROOFS: bool = false; // TODO: enable this #[derive(Default)] -pub struct OperationPool { +pub struct OperationPool { /// Map from attestation ID (see below) to vectors of attestations. attestations: RwLock>>, /// Map from deposit index to deposit data. @@ -42,6 +43,7 @@ pub struct OperationPool { voluntary_exits: RwLock>, /// Set of transfers. transfers: RwLock>, + _phantom: PhantomData, } /// Serialized `AttestationData` augmented with a domain to encode the fork info. @@ -52,14 +54,22 @@ struct AttestationId(Vec); const DOMAIN_BYTES_LEN: usize = 8; impl AttestationId { - fn from_data(attestation: &AttestationData, state: &BeaconState, spec: &ChainSpec) -> Self { + fn from_data( + attestation: &AttestationData, + state: &BeaconState, + spec: &ChainSpec, + ) -> Self { let mut bytes = ssz_encode(attestation); let epoch = attestation.slot.epoch(spec.slots_per_epoch); bytes.extend_from_slice(&AttestationId::compute_domain_bytes(epoch, state, spec)); AttestationId(bytes) } - fn compute_domain_bytes(epoch: Epoch, state: &BeaconState, spec: &ChainSpec) -> Vec { + fn compute_domain_bytes( + epoch: Epoch, + state: &BeaconState, + spec: &ChainSpec, + ) -> Vec { int_to_bytes8(spec.get_domain(epoch, Domain::Attestation, &state.fork)) } @@ -75,7 +85,11 @@ impl AttestationId { /// receive for including it in a block. // TODO: this could be optimised with a map from validator index to whether that validator has // attested in each of the current and previous epochs. Currently quadractic in number of validators. -fn attestation_score(attestation: &Attestation, state: &BeaconState, spec: &ChainSpec) -> usize { +fn attestation_score( + attestation: &Attestation, + state: &BeaconState, + spec: &ChainSpec, +) -> usize { // Bitfield of validators whose attestations are new/fresh. let mut new_validators = attestation.aggregation_bitfield.clone(); @@ -113,7 +127,7 @@ pub enum DepositInsertStatus { Replaced(Box), } -impl OperationPool { +impl OperationPool { /// Create a new operation pool. pub fn new() -> Self { Self::default() @@ -123,7 +137,7 @@ impl OperationPool { pub fn insert_attestation( &self, attestation: Attestation, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result<(), AttestationValidationError> { // Check that attestation signatures are valid. @@ -169,7 +183,7 @@ impl OperationPool { } /// Get a list of attestations for inclusion in a block. - pub fn get_attestations(&self, state: &BeaconState, spec: &ChainSpec) -> Vec { + pub fn get_attestations(&self, state: &BeaconState, spec: &ChainSpec) -> Vec { // Attestations for the current fork, which may be from the current or previous epoch. let prev_epoch = state.previous_epoch(spec); let current_epoch = state.current_epoch(spec); @@ -204,7 +218,7 @@ impl OperationPool { // TODO: we could probably prune other attestations here: // - ones that are completely covered by attestations included in the state // - maybe ones invalidated by the confirmation of one fork over another - pub fn prune_attestations(&self, finalized_state: &BeaconState, spec: &ChainSpec) { + pub fn prune_attestations(&self, finalized_state: &BeaconState, spec: &ChainSpec) { self.attestations.write().retain(|_, attestations| { // All the attestations in this bucket have the same data, so we only need to // check the first one. @@ -220,7 +234,7 @@ impl OperationPool { pub fn insert_deposit( &self, deposit: Deposit, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result { use DepositInsertStatus::*; @@ -245,7 +259,7 @@ impl OperationPool { /// Get an ordered list of deposits for inclusion in a block. /// /// Take at most the maximum number of deposits, beginning from the current deposit index. - pub fn get_deposits(&self, state: &BeaconState, spec: &ChainSpec) -> Vec { + pub fn get_deposits(&self, state: &BeaconState, spec: &ChainSpec) -> Vec { let start_idx = state.deposit_index; (start_idx..start_idx + spec.max_deposits) .map(|idx| self.deposits.read().get(&idx).cloned()) @@ -255,7 +269,7 @@ impl OperationPool { } /// Remove all deposits with index less than the deposit index of the latest finalised block. - pub fn prune_deposits(&self, state: &BeaconState) -> BTreeMap { + pub fn prune_deposits(&self, state: &BeaconState) -> BTreeMap { let deposits_keep = self.deposits.write().split_off(&state.deposit_index); std::mem::replace(&mut self.deposits.write(), deposits_keep) } @@ -269,7 +283,7 @@ impl OperationPool { pub fn insert_proposer_slashing( &self, slashing: ProposerSlashing, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result<(), ProposerSlashingValidationError> { // TODO: should maybe insert anyway if the proposer is unknown in the validator index, @@ -286,7 +300,7 @@ impl OperationPool { /// Depends on the fork field of the state, but not on the state's epoch. fn attester_slashing_id( slashing: &AttesterSlashing, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> (AttestationId, AttestationId) { ( @@ -299,7 +313,7 @@ impl OperationPool { pub fn insert_attester_slashing( &self, slashing: AttesterSlashing, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result<(), AttesterSlashingValidationError> { verify_attester_slashing(state, &slashing, true, spec)?; @@ -315,7 +329,7 @@ impl OperationPool { /// earlier in the block. pub fn get_slashings( &self, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> (Vec, Vec) { let proposer_slashings = filter_limit_operations( @@ -370,7 +384,7 @@ impl OperationPool { } /// Prune proposer slashings for all slashed or withdrawn validators. - pub fn prune_proposer_slashings(&self, finalized_state: &BeaconState, spec: &ChainSpec) { + pub fn prune_proposer_slashings(&self, finalized_state: &BeaconState, spec: &ChainSpec) { prune_validator_hash_map( &mut self.proposer_slashings.write(), |validator| { @@ -383,7 +397,7 @@ impl OperationPool { /// Prune attester slashings for all slashed or withdrawn validators, or attestations on another /// fork. - pub fn prune_attester_slashings(&self, finalized_state: &BeaconState, spec: &ChainSpec) { + pub fn prune_attester_slashings(&self, finalized_state: &BeaconState, spec: &ChainSpec) { self.attester_slashings.write().retain(|id, slashing| { let fork_ok = &Self::attester_slashing_id(slashing, finalized_state, spec) == id; let curr_epoch = finalized_state.current_epoch(spec); @@ -402,7 +416,7 @@ impl OperationPool { pub fn insert_voluntary_exit( &self, exit: VoluntaryExit, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result<(), ExitValidationError> { verify_exit_time_independent_only(state, &exit, spec)?; @@ -413,7 +427,11 @@ impl OperationPool { } /// Get a list of voluntary exits for inclusion in a block. - pub fn get_voluntary_exits(&self, state: &BeaconState, spec: &ChainSpec) -> Vec { + pub fn get_voluntary_exits( + &self, + state: &BeaconState, + spec: &ChainSpec, + ) -> Vec { filter_limit_operations( self.voluntary_exits.read().values(), |exit| verify_exit(state, exit, spec).is_ok(), @@ -422,7 +440,7 @@ impl OperationPool { } /// Prune if validator has already exited at the last finalized state. - pub fn prune_voluntary_exits(&self, finalized_state: &BeaconState, spec: &ChainSpec) { + pub fn prune_voluntary_exits(&self, finalized_state: &BeaconState, spec: &ChainSpec) { prune_validator_hash_map( &mut self.voluntary_exits.write(), |validator| validator.is_exited_at(finalized_state.current_epoch(spec)), @@ -434,7 +452,7 @@ impl OperationPool { pub fn insert_transfer( &self, transfer: Transfer, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, ) -> Result<(), TransferValidationError> { // The signature of the transfer isn't hashed, but because we check @@ -448,7 +466,7 @@ impl OperationPool { /// Get a list of transfers for inclusion in a block. // TODO: improve the economic optimality of this function by accounting for // dependencies between transfers in the same block e.g. A pays B, B pays C - pub fn get_transfers(&self, state: &BeaconState, spec: &ChainSpec) -> Vec { + pub fn get_transfers(&self, state: &BeaconState, spec: &ChainSpec) -> Vec { self.transfers .read() .iter() @@ -460,14 +478,14 @@ impl OperationPool { } /// Prune the set of transfers by removing all those whose slot has already passed. - pub fn prune_transfers(&self, finalized_state: &BeaconState) { + pub fn prune_transfers(&self, finalized_state: &BeaconState) { self.transfers .write() .retain(|transfer| transfer.slot > finalized_state.slot) } /// Prune all types of transactions given the latest finalized state. - pub fn prune_all(&self, finalized_state: &BeaconState, spec: &ChainSpec) { + pub fn prune_all(&self, finalized_state: &BeaconState, spec: &ChainSpec) { self.prune_attestations(finalized_state, spec); self.prune_deposits(finalized_state); self.prune_proposer_slashings(finalized_state, spec); @@ -487,7 +505,10 @@ impl OperationPool { /// /// - Their `AttestationData` is equal. /// - `attestation` does not contain any signatures that `PendingAttestation` does not have. -fn superior_attestation_exists_in_state(state: &BeaconState, attestation: &Attestation) -> bool { +fn superior_attestation_exists_in_state( + state: &BeaconState, + attestation: &Attestation, +) -> bool { state .current_epoch_attestations .iter() @@ -522,10 +543,10 @@ where /// The keys in the map should be validator indices, which will be looked up /// in the state's validator registry and then passed to `prune_if`. /// Entries for unknown validators will be kept. -fn prune_validator_hash_map( +fn prune_validator_hash_map( map: &mut HashMap, prune_if: F, - finalized_state: &BeaconState, + finalized_state: &BeaconState, ) where F: Fn(&Validator) -> bool, { @@ -649,7 +670,11 @@ mod tests { } // Create a random deposit (with a valid proof of posession) - fn make_deposit(rng: &mut XorShiftRng, state: &BeaconState, spec: &ChainSpec) -> Deposit { + fn make_deposit( + rng: &mut XorShiftRng, + state: &BeaconState, + spec: &ChainSpec, + ) -> Deposit { let keypair = Keypair::random(); let mut deposit = Deposit::random_for_test(rng); let mut deposit_input = DepositInput { @@ -668,9 +693,9 @@ mod tests { } // Create `count` dummy deposits with sequential deposit IDs beginning from `start`. - fn dummy_deposits( + fn dummy_deposits( rng: &mut XorShiftRng, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, start: u64, count: u64, @@ -685,9 +710,11 @@ mod tests { .collect() } - fn test_state(rng: &mut XorShiftRng) -> (ChainSpec, BeaconState) { - let spec = ChainSpec::foundation(); + fn test_state(rng: &mut XorShiftRng) -> (ChainSpec, BeaconState) { + let spec = FoundationStateTypes::spec(); + let mut state = BeaconState::random_for_test(rng); + state.fork = Fork::genesis(&spec); (spec, state) diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index a77b4d4f1..4d296feed 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -1,7 +1,7 @@ use crate::*; use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192}; -pub trait BeaconStateTypes { +pub trait BeaconStateTypes: Default { type ShardCount: Unsigned + Clone + Sync + Send; type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send; type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send; @@ -11,7 +11,7 @@ pub trait BeaconStateTypes { fn spec() -> ChainSpec; } -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug, Default)] pub struct FoundationStateTypes; impl BeaconStateTypes for FoundationStateTypes { @@ -28,7 +28,7 @@ impl BeaconStateTypes for FoundationStateTypes { pub type FoundationBeaconState = BeaconState; -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug, Default)] pub struct FewValidatorsStateTypes; impl BeaconStateTypes for FewValidatorsStateTypes { diff --git a/eth2/types/src/historical_batch.rs b/eth2/types/src/historical_batch.rs index f9886b8c8..ecd7aad89 100644 --- a/eth2/types/src/historical_batch.rs +++ b/eth2/types/src/historical_batch.rs @@ -1,7 +1,6 @@ use crate::test_utils::TestRandom; -use crate::Hash256; +use crate::*; -use crate::beacon_state::BeaconStateTypes; use fixed_len_vec::FixedLenVec; use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; @@ -31,7 +30,6 @@ pub struct HistoricalBatch { #[cfg(test)] mod tests { use super::*; - use crate::beacon_state::beacon_state_types::FoundationStateTypes; pub type FoundationHistoricalBatch = HistoricalBatch; From 51dc97ee42b64250900f0e22b63b48cf78a24f3c Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 18:18:17 +1000 Subject: [PATCH 09/22] Allow `fork_choice` and `beacon_chain` to compile --- beacon_node/beacon_chain/src/beacon_chain.rs | 50 +++++++++---------- beacon_node/beacon_chain/src/checkpoint.rs | 12 ++--- beacon_node/beacon_chain/src/initialise.rs | 20 ++++++-- .../testing_beacon_chain_builder.rs | 17 ++++--- eth2/fork_choice/src/bitwise_lmd_ghost.rs | 13 +++-- eth2/fork_choice/src/optimized_lmd_ghost.rs | 13 +++-- eth2/fork_choice/src/slow_lmd_ghost.rs | 13 +++-- .../src/beacon_state/beacon_state_types.rs | 13 ++--- 8 files changed, 87 insertions(+), 64 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 41a718655..2bbb6901c 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -83,30 +83,31 @@ impl BlockProcessingOutcome { } } -pub struct BeaconChain { +pub struct BeaconChain { pub block_store: Arc>, pub state_store: Arc>, pub slot_clock: U, - pub op_pool: OperationPool, - canonical_head: RwLock, - finalized_head: RwLock, - pub state: RwLock, + pub op_pool: OperationPool, + canonical_head: RwLock>, + finalized_head: RwLock>, + pub state: RwLock>, pub spec: ChainSpec, pub fork_choice: RwLock, } -impl BeaconChain +impl BeaconChain where T: ClientDB, U: SlotClock, F: ForkChoice, + B: BeaconStateTypes, { /// Instantiate a new Beacon Chain, from genesis. pub fn from_genesis( state_store: Arc>, block_store: Arc>, slot_clock: U, - mut genesis_state: BeaconState, + mut genesis_state: BeaconState, genesis_block: BeaconBlock, spec: ChainSpec, fork_choice: F, @@ -218,7 +219,7 @@ where // // If we get `SlotOutOfBounds` error, load the oldest available historic // state from the DB. - match state.get_block_root(slot, spec) { + match state.get_block_root(slot) { Ok(root) => { if slot < earliest_slot { break; @@ -230,9 +231,9 @@ where Err(BeaconStateError::SlotOutOfBounds) => { // Read the earliest historic state in the current slot. let earliest_historic_slot = - state.slot - Slot::from(spec.slots_per_historical_root); + state.slot - Slot::from(B::SlotsPerHistoricalRoot::to_usize()); // Load the earlier state from disk. - let new_state_root = state.get_state_root(earliest_historic_slot, spec)?; + let new_state_root = state.get_state_root(earliest_historic_slot)?; // Break if the DB is unable to load the state. state = match self.state_store.get_deserialized(&new_state_root) { @@ -270,7 +271,7 @@ where &self, new_beacon_block: BeaconBlock, new_beacon_block_root: Hash256, - new_beacon_state: BeaconState, + new_beacon_state: BeaconState, new_beacon_state_root: Hash256, ) { debug!( @@ -292,7 +293,7 @@ where /// It is important to note that the `beacon_state` returned may not match the present slot. It /// is the state as it was when the head block was received, which could be some slots prior to /// now. - pub fn head(&self) -> RwLockReadGuard { + pub fn head(&self) -> RwLockReadGuard> { self.canonical_head.read() } @@ -302,7 +303,7 @@ where /// state and calling `catchup_state` as it will not result in an old state being installed and /// then having it iteratively updated -- in such a case it's possible for another thread to /// find the state at an old slot. - pub fn update_state(&self, mut state: BeaconState) -> Result<(), Error> { + pub fn update_state(&self, mut state: BeaconState) -> Result<(), Error> { let present_slot = match self.slot_clock.present_slot() { Ok(Some(slot)) => slot, _ => return Err(Error::UnableToReadSlot), @@ -357,7 +358,7 @@ where &self, new_beacon_block: BeaconBlock, new_beacon_block_root: Hash256, - new_beacon_state: BeaconState, + new_beacon_state: BeaconState, new_beacon_state_root: Hash256, ) { let mut finalized_head = self.finalized_head.write(); @@ -371,7 +372,7 @@ where /// Returns a read-lock guarded `CheckPoint` struct for reading the justified head (as chosen, /// indirectly, by the fork-choice rule). - pub fn finalized_head(&self) -> RwLockReadGuard { + pub fn finalized_head(&self) -> RwLockReadGuard> { self.finalized_head.read() } @@ -493,17 +494,14 @@ where } else { // If the current head block is not from this slot, use the slot from the previous // epoch. - *self.state.read().get_block_root( - current_epoch_start_slot - self.spec.slots_per_epoch, - &self.spec, - )? + *self + .state + .read() + .get_block_root(current_epoch_start_slot - self.spec.slots_per_epoch)? } } else { // If we're not on the first slot of the epoch. - *self - .state - .read() - .get_block_root(current_epoch_start_slot, &self.spec)? + *self.state.read().get_block_root(current_epoch_start_slot)? }; Ok(AttestationData { @@ -667,7 +665,7 @@ where pub fn produce_block( &self, randao_reveal: Signature, - ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { + ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { debug!("Producing block at slot {}...", self.state.read().slot); let mut state = self.state.read().clone(); @@ -677,7 +675,7 @@ where trace!("Finding attestations for new block..."); let previous_block_root = *state - .get_block_root(state.slot - 1, &self.spec) + .get_block_root(state.slot - 1) .map_err(|_| BlockProductionError::UnableToGetBlockRootFromState)?; let (proposer_slashings, attester_slashings) = @@ -762,7 +760,7 @@ where /// /// This could be a very expensive operation and should only be done in testing/analysis /// activities. - pub fn chain_dump(&self) -> Result, Error> { + pub fn chain_dump(&self) -> Result>, Error> { let mut dump = vec![]; let mut last_slot = CheckPoint { diff --git a/beacon_node/beacon_chain/src/checkpoint.rs b/beacon_node/beacon_chain/src/checkpoint.rs index 78227e5c8..c3757949f 100644 --- a/beacon_node/beacon_chain/src/checkpoint.rs +++ b/beacon_node/beacon_chain/src/checkpoint.rs @@ -1,22 +1,22 @@ use serde_derive::Serialize; -use types::{BeaconBlock, BeaconState, Hash256}; +use types::{BeaconBlock, BeaconState, BeaconStateTypes, Hash256}; /// Represents some block and it's associated state. Generally, this will be used for tracking the /// head, justified head and finalized head. #[derive(Clone, Serialize, PartialEq, Debug)] -pub struct CheckPoint { +pub struct CheckPoint { pub beacon_block: BeaconBlock, pub beacon_block_root: Hash256, - pub beacon_state: BeaconState, + pub beacon_state: BeaconState, pub beacon_state_root: Hash256, } -impl CheckPoint { +impl CheckPoint { /// Create a new checkpoint. pub fn new( beacon_block: BeaconBlock, beacon_block_root: Hash256, - beacon_state: BeaconState, + beacon_state: BeaconState, beacon_state_root: Hash256, ) -> Self { Self { @@ -32,7 +32,7 @@ impl CheckPoint { &mut self, beacon_block: BeaconBlock, beacon_block_root: Hash256, - beacon_state: BeaconState, + beacon_state: BeaconState, beacon_state_root: Hash256, ) { self.beacon_block = beacon_block; diff --git a/beacon_node/beacon_chain/src/initialise.rs b/beacon_node/beacon_chain/src/initialise.rs index c66dd63b1..284393c02 100644 --- a/beacon_node/beacon_chain/src/initialise.rs +++ b/beacon_node/beacon_chain/src/initialise.rs @@ -11,14 +11,21 @@ use std::path::PathBuf; use std::sync::Arc; use tree_hash::TreeHash; use types::test_utils::TestingBeaconStateBuilder; -use types::{BeaconBlock, ChainSpec, Hash256}; +use types::{BeaconBlock, ChainSpec, FewValidatorsStateTypes, FoundationStateTypes, Hash256}; //TODO: Correct this for prod //TODO: Account for historical db pub fn initialise_beacon_chain( spec: &ChainSpec, db_name: Option<&PathBuf>, -) -> Arc>> { +) -> Arc< + BeaconChain< + DiskDB, + SystemTimeSlotClock, + BitwiseLMDGhost, + FoundationStateTypes, + >, +> { // set up the db let db = Arc::new(DiskDB::open( db_name.expect("Database directory must be included"), @@ -64,7 +71,14 @@ pub fn initialise_beacon_chain( pub fn initialise_test_beacon_chain( spec: &ChainSpec, _db_name: Option<&PathBuf>, -) -> Arc>> { +) -> Arc< + BeaconChain< + MemoryDB, + SystemTimeSlotClock, + BitwiseLMDGhost, + FewValidatorsStateTypes, + >, +> { let db = Arc::new(MemoryDB::open()); let block_store = Arc::new(BeaconBlockStore::new(db.clone())); let state_store = Arc::new(BeaconStateStore::new(db.clone())); diff --git a/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs b/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs index d174670c0..9f9838ae7 100644 --- a/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs +++ b/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs @@ -7,17 +7,18 @@ use fork_choice::BitwiseLMDGhost; use slot_clock::TestingSlotClock; use std::sync::Arc; use tree_hash::TreeHash; -use types::test_utils::TestingBeaconStateBuilder; use types::*; +use types::{test_utils::TestingBeaconStateBuilder, BeaconStateTypes, FewValidatorsStateTypes}; -type TestingBeaconChain = BeaconChain>; +type TestingBeaconChain = + BeaconChain, B>; -pub struct TestingBeaconChainBuilder { - state_builder: TestingBeaconStateBuilder, +pub struct TestingBeaconChainBuilder { + state_builder: TestingBeaconStateBuilder, } -impl TestingBeaconChainBuilder { - pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain { +impl TestingBeaconChainBuilder { + pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain { let db = Arc::new(MemoryDB::open()); let block_store = Arc::new(BeaconBlockStore::new(db.clone())); let state_store = Arc::new(BeaconStateStore::new(db.clone())); @@ -43,8 +44,8 @@ impl TestingBeaconChainBuilder { } } -impl From for TestingBeaconChainBuilder { - fn from(state_builder: TestingBeaconStateBuilder) -> TestingBeaconChainBuilder { +impl From> for TestingBeaconChainBuilder { + fn from(state_builder: TestingBeaconStateBuilder) -> TestingBeaconChainBuilder { TestingBeaconChainBuilder { state_builder } } } diff --git a/eth2/fork_choice/src/bitwise_lmd_ghost.rs b/eth2/fork_choice/src/bitwise_lmd_ghost.rs index 8ae0251d2..66100dbc1 100644 --- a/eth2/fork_choice/src/bitwise_lmd_ghost.rs +++ b/eth2/fork_choice/src/bitwise_lmd_ghost.rs @@ -9,8 +9,9 @@ use db::{ }; use log::{debug, trace}; use std::collections::HashMap; +use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Hash256, Slot, SlotHeight}; +use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot, SlotHeight}; //TODO: Pruning - Children //TODO: Handle Syncing @@ -33,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 { } /// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm. -pub struct BitwiseLMDGhost { +pub struct BitwiseLMDGhost { /// A cache of known ancestors at given heights for a specific block. //TODO: Consider FnvHashMap cache: HashMap, Hash256>, @@ -50,9 +51,10 @@ pub struct BitwiseLMDGhost { /// State storage access. state_store: Arc>, max_known_height: SlotHeight, + _phantom: PhantomData, } -impl BitwiseLMDGhost +impl BitwiseLMDGhost where T: ClientDB + Sized, { @@ -68,6 +70,7 @@ where max_known_height: SlotHeight::new(0), block_store, state_store, + _phantom: PhantomData, } } @@ -85,7 +88,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -240,7 +243,7 @@ where } } -impl ForkChoice for BitwiseLMDGhost { +impl ForkChoice for BitwiseLMDGhost { fn add_block( &mut self, block: &BeaconBlock, diff --git a/eth2/fork_choice/src/optimized_lmd_ghost.rs b/eth2/fork_choice/src/optimized_lmd_ghost.rs index ee2919e85..3e43e2153 100644 --- a/eth2/fork_choice/src/optimized_lmd_ghost.rs +++ b/eth2/fork_choice/src/optimized_lmd_ghost.rs @@ -9,8 +9,9 @@ use db::{ use log::{debug, trace}; use std::cmp::Ordering; use std::collections::HashMap; +use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Hash256, Slot, SlotHeight}; +use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot, SlotHeight}; //TODO: Pruning - Children //TODO: Handle Syncing @@ -33,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 { } /// Stores the necessary data structures to run the optimised lmd ghost algorithm. -pub struct OptimizedLMDGhost { +pub struct OptimizedLMDGhost { /// A cache of known ancestors at given heights for a specific block. //TODO: Consider FnvHashMap cache: HashMap, Hash256>, @@ -50,9 +51,10 @@ pub struct OptimizedLMDGhost { /// State storage access. state_store: Arc>, max_known_height: SlotHeight, + _phantom: PhantomData, } -impl OptimizedLMDGhost +impl OptimizedLMDGhost where T: ClientDB + Sized, { @@ -68,6 +70,7 @@ where max_known_height: SlotHeight::new(0), block_store, state_store, + _phantom: PhantomData, } } @@ -85,7 +88,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -211,7 +214,7 @@ where } } -impl ForkChoice for OptimizedLMDGhost { +impl ForkChoice for OptimizedLMDGhost { fn add_block( &mut self, block: &BeaconBlock, diff --git a/eth2/fork_choice/src/slow_lmd_ghost.rs b/eth2/fork_choice/src/slow_lmd_ghost.rs index 4b236cba4..c621870d1 100644 --- a/eth2/fork_choice/src/slow_lmd_ghost.rs +++ b/eth2/fork_choice/src/slow_lmd_ghost.rs @@ -7,12 +7,13 @@ use db::{ }; use log::{debug, trace}; use std::collections::HashMap; +use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Hash256, Slot}; +use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot}; //TODO: Pruning and syncing -pub struct SlowLMDGhost { +pub struct SlowLMDGhost { /// The latest attestation targets as a map of validator index to block hash. //TODO: Could this be a fixed size vec latest_attestation_targets: HashMap, @@ -22,9 +23,10 @@ pub struct SlowLMDGhost { block_store: Arc>, /// State storage access. state_store: Arc>, + _phantom: PhantomData, } -impl SlowLMDGhost +impl SlowLMDGhost where T: ClientDB + Sized, { @@ -37,6 +39,7 @@ where children: HashMap::new(), block_store, state_store, + _phantom: PhantomData, } } @@ -54,7 +57,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -105,7 +108,7 @@ where } } -impl ForkChoice for SlowLMDGhost { +impl ForkChoice for SlowLMDGhost { /// Process when a block is added fn add_block( &mut self, diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index 4d296feed..5012ebb37 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -1,12 +1,13 @@ use crate::*; use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192}; +use std::fmt::Debug; -pub trait BeaconStateTypes: Default { - type ShardCount: Unsigned + Clone + Sync + Send; - type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send; - type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send; - type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send; - type LatestSlashedExitLength: Unsigned + Clone + Sync + Send; +pub trait BeaconStateTypes: Default + Sync + Send + Clone + Debug + PartialEq { + type ShardCount: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type LatestSlashedExitLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; fn spec() -> ChainSpec; } From 42b7aa89d440d5c69596e912898f2e62a308cc72 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 8 May 2019 19:38:18 +1000 Subject: [PATCH 10/22] Update `network` and `rpc` to `BeaconStateTypes` --- beacon_node/network/src/beacon_chain.rs | 22 +++++++++++-------- beacon_node/network/src/message_handler.rs | 11 +++++----- beacon_node/network/src/service.rs | 14 +++++++----- beacon_node/network/src/sync/import_queue.rs | 10 ++++----- beacon_node/network/src/sync/simple_sync.rs | 16 +++++++------- beacon_node/rpc/src/attestation.rs | 8 +++---- beacon_node/rpc/src/beacon_block.rs | 8 +++---- beacon_node/rpc/src/beacon_chain.rs | 19 ++++++++-------- beacon_node/rpc/src/beacon_node.rs | 7 +++--- beacon_node/rpc/src/lib.rs | 5 +++-- beacon_node/rpc/src/validator.rs | 8 +++---- .../src/beacon_state/beacon_state_types.rs | 2 +- 12 files changed, 70 insertions(+), 60 deletions(-) diff --git a/beacon_node/network/src/beacon_chain.rs b/beacon_node/network/src/beacon_chain.rs index 827adeb3c..2ab446c52 100644 --- a/beacon_node/network/src/beacon_chain.rs +++ b/beacon_node/network/src/beacon_chain.rs @@ -8,19 +8,22 @@ use beacon_chain::{ AttestationValidationError, CheckPoint, }; use eth2_libp2p::rpc::HelloMessage; -use types::{Attestation, BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Epoch, Hash256, Slot}; +use types::{ + Attestation, BeaconBlock, BeaconBlockBody, BeaconBlockHeader, BeaconStateTypes, Epoch, Hash256, + Slot, +}; pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome, InvalidBlock}; /// The network's API to the beacon chain. -pub trait BeaconChain: Send + Sync { +pub trait BeaconChain: Send + Sync { fn get_spec(&self) -> &ChainSpec; - fn get_state(&self) -> RwLockReadGuard; + fn get_state(&self) -> RwLockReadGuard>; fn slot(&self) -> Slot; - fn head(&self) -> RwLockReadGuard; + fn head(&self) -> RwLockReadGuard>; fn get_block(&self, block_root: &Hash256) -> Result, BeaconChainError>; @@ -28,7 +31,7 @@ pub trait BeaconChain: Send + Sync { fn best_block_root(&self) -> Hash256; - fn finalized_head(&self) -> RwLockReadGuard; + fn finalized_head(&self) -> RwLockReadGuard>; fn finalized_epoch(&self) -> Epoch; @@ -62,17 +65,18 @@ pub trait BeaconChain: Send + Sync { fn is_new_block_root(&self, beacon_block_root: &Hash256) -> Result; } -impl BeaconChain for RawBeaconChain +impl BeaconChain for RawBeaconChain where T: ClientDB + Sized, U: SlotClock, F: ForkChoice, + B: BeaconStateTypes, { fn get_spec(&self) -> &ChainSpec { &self.spec } - fn get_state(&self) -> RwLockReadGuard { + fn get_state(&self) -> RwLockReadGuard> { self.state.read() } @@ -80,7 +84,7 @@ where self.get_state().slot } - fn head(&self) -> RwLockReadGuard { + fn head(&self) -> RwLockReadGuard> { self.head() } @@ -92,7 +96,7 @@ where self.get_state().finalized_epoch } - fn finalized_head(&self) -> RwLockReadGuard { + fn finalized_head(&self) -> RwLockReadGuard> { self.finalized_head() } diff --git a/beacon_node/network/src/message_handler.rs b/beacon_node/network/src/message_handler.rs index c5ba25f82..90aff0041 100644 --- a/beacon_node/network/src/message_handler.rs +++ b/beacon_node/network/src/message_handler.rs @@ -13,6 +13,7 @@ use slog::{debug, warn}; use std::collections::HashMap; use std::sync::Arc; use std::time::Instant; +use types::BeaconStateTypes; /// Timeout for RPC requests. // const REQUEST_TIMEOUT: Duration = Duration::from_secs(30); @@ -20,11 +21,11 @@ use std::time::Instant; // const HELLO_TIMEOUT: Duration = Duration::from_secs(30); /// Handles messages received from the network and client and organises syncing. -pub struct MessageHandler { +pub struct MessageHandler { /// Currently loaded and initialised beacon chain. - _chain: Arc, + _chain: Arc>, /// The syncing framework. - sync: SimpleSync, + sync: SimpleSync, /// The context required to send messages to, and process messages from peers. network_context: NetworkContext, /// The `MessageHandler` logger. @@ -44,10 +45,10 @@ pub enum HandlerMessage { PubsubMessage(PeerId, Box), } -impl MessageHandler { +impl MessageHandler { /// Initializes and runs the MessageHandler. pub fn spawn( - beacon_chain: Arc, + beacon_chain: Arc>, network_send: crossbeam_channel::Sender, executor: &tokio::runtime::TaskExecutor, log: slog::Logger, diff --git a/beacon_node/network/src/service.rs b/beacon_node/network/src/service.rs index 06e3f7af9..b7c6e58ec 100644 --- a/beacon_node/network/src/service.rs +++ b/beacon_node/network/src/service.rs @@ -10,22 +10,23 @@ use futures::prelude::*; use futures::sync::oneshot; use futures::Stream; use slog::{debug, info, o, trace}; +use std::marker::PhantomData; use std::sync::Arc; use tokio::runtime::TaskExecutor; -use types::Topic; +use types::{BeaconStateTypes, Topic}; /// Service that handles communication between internal services and the eth2_libp2p network service. -pub struct Service { +pub struct Service { //libp2p_service: Arc>, _libp2p_exit: oneshot::Sender<()>, network_send: crossbeam_channel::Sender, - //message_handler: MessageHandler, - //message_handler_send: Sender, + _phantom: PhantomData, //message_handler: MessageHandler, + //message_handler_send: Sender } -impl Service { +impl Service { pub fn new( - beacon_chain: Arc, + beacon_chain: Arc>, config: &NetworkConfig, executor: &TaskExecutor, log: slog::Logger, @@ -56,6 +57,7 @@ impl Service { let network_service = Service { _libp2p_exit: libp2p_exit, network_send: network_send.clone(), + _phantom: PhantomData, }; Ok((Arc::new(network_service), network_send)) diff --git a/beacon_node/network/src/sync/import_queue.rs b/beacon_node/network/src/sync/import_queue.rs index 106e3eb66..418b5c1b0 100644 --- a/beacon_node/network/src/sync/import_queue.rs +++ b/beacon_node/network/src/sync/import_queue.rs @@ -5,7 +5,7 @@ use slog::{debug, error}; use std::sync::Arc; use std::time::{Duration, Instant}; use tree_hash::TreeHash; -use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Hash256, Slot}; +use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, BeaconStateTypes, Hash256, Slot}; /// Provides a queue for fully and partially built `BeaconBlock`s. /// @@ -19,8 +19,8 @@ use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Hash256, Slot}; /// `BeaconBlockBody` as the key. /// - It is possible for multiple distinct blocks to have identical `BeaconBlockBodies`. Therefore /// we cannot use a `HashMap` keyed by the root of `BeaconBlockBody`. -pub struct ImportQueue { - pub chain: Arc, +pub struct ImportQueue { + pub chain: Arc>, /// Partially imported blocks, keyed by the root of `BeaconBlockBody`. pub partials: Vec, /// Time before a queue entry is considered state. @@ -29,9 +29,9 @@ pub struct ImportQueue { log: slog::Logger, } -impl ImportQueue { +impl ImportQueue { /// Return a new, empty queue. - pub fn new(chain: Arc, stale_time: Duration, log: slog::Logger) -> Self { + pub fn new(chain: Arc>, stale_time: Duration, log: slog::Logger) -> Self { Self { chain, partials: vec![], diff --git a/beacon_node/network/src/sync/simple_sync.rs b/beacon_node/network/src/sync/simple_sync.rs index 1b57fbc00..c54a24678 100644 --- a/beacon_node/network/src/sync/simple_sync.rs +++ b/beacon_node/network/src/sync/simple_sync.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; use tree_hash::TreeHash; -use types::{Attestation, BeaconBlock, Epoch, Hash256, Slot}; +use types::{Attestation, BeaconBlock, BeaconStateTypes, Epoch, Hash256, Slot}; /// The number of slots that we can import blocks ahead of us, before going into full Sync mode. const SLOT_IMPORT_TOLERANCE: u64 = 100; @@ -88,8 +88,8 @@ impl From for PeerSyncInfo { } } -impl From<&Arc> for PeerSyncInfo { - fn from(chain: &Arc) -> PeerSyncInfo { +impl From<&Arc>> for PeerSyncInfo { + fn from(chain: &Arc>) -> PeerSyncInfo { Self::from(chain.hello_message()) } } @@ -103,22 +103,22 @@ pub enum SyncState { } /// Simple Syncing protocol. -pub struct SimpleSync { +pub struct SimpleSync { /// A reference to the underlying beacon chain. - chain: Arc, + chain: Arc>, /// A mapping of Peers to their respective PeerSyncInfo. known_peers: HashMap, /// A queue to allow importing of blocks - import_queue: ImportQueue, + import_queue: ImportQueue, /// The current state of the syncing protocol. state: SyncState, /// Sync logger. log: slog::Logger, } -impl SimpleSync { +impl SimpleSync { /// Instantiate a `SimpleSync` instance, with no peers and an empty queue. - pub fn new(beacon_chain: Arc, log: &slog::Logger) -> Self { + pub fn new(beacon_chain: Arc>, log: &slog::Logger) -> Self { let sync_logger = log.new(o!("Service"=> "Sync")); let queue_item_stale_time = Duration::from_secs(QUEUE_STALE_SECS); diff --git a/beacon_node/rpc/src/attestation.rs b/beacon_node/rpc/src/attestation.rs index 3abfdac59..eab6a8cd1 100644 --- a/beacon_node/rpc/src/attestation.rs +++ b/beacon_node/rpc/src/attestation.rs @@ -9,15 +9,15 @@ use protos::services_grpc::AttestationService; use slog::{error, info, trace, warn}; use ssz::{ssz_encode, Decodable}; use std::sync::Arc; -use types::Attestation; +use types::{Attestation, BeaconStateTypes}; #[derive(Clone)] -pub struct AttestationServiceInstance { - pub chain: Arc, +pub struct AttestationServiceInstance { + pub chain: Arc>, pub log: slog::Logger, } -impl AttestationService for AttestationServiceInstance { +impl AttestationService for AttestationServiceInstance { /// Produce the `AttestationData` for signing by a validator. fn produce_attestation_data( &mut self, diff --git a/beacon_node/rpc/src/beacon_block.rs b/beacon_node/rpc/src/beacon_block.rs index 450bcbca1..fb6a08acc 100644 --- a/beacon_node/rpc/src/beacon_block.rs +++ b/beacon_node/rpc/src/beacon_block.rs @@ -13,16 +13,16 @@ use slog::Logger; use slog::{error, info, trace, warn}; use ssz::{ssz_encode, Decodable}; use std::sync::Arc; -use types::{BeaconBlock, Signature, Slot}; +use types::{BeaconBlock, BeaconStateTypes, Signature, Slot}; #[derive(Clone)] -pub struct BeaconBlockServiceInstance { - pub chain: Arc, +pub struct BeaconBlockServiceInstance { + pub chain: Arc>, pub network_chan: crossbeam_channel::Sender, pub log: Logger, } -impl BeaconBlockService for BeaconBlockServiceInstance { +impl BeaconBlockService for BeaconBlockServiceInstance { /// Produce a `BeaconBlock` for signing by a validator. fn produce_beacon_block( &mut self, diff --git a/beacon_node/rpc/src/beacon_chain.rs b/beacon_node/rpc/src/beacon_chain.rs index ddc91b73c..9456c8857 100644 --- a/beacon_node/rpc/src/beacon_chain.rs +++ b/beacon_node/rpc/src/beacon_chain.rs @@ -8,15 +8,15 @@ use beacon_chain::{ AttestationValidationError, BlockProductionError, }; pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome}; -use types::{Attestation, AttestationData, BeaconBlock}; +use types::{Attestation, AttestationData, BeaconBlock, BeaconStateTypes}; /// The RPC's API to the beacon chain. -pub trait BeaconChain: Send + Sync { +pub trait BeaconChain: Send + Sync { fn get_spec(&self) -> &ChainSpec; - fn get_state(&self) -> RwLockReadGuard; + fn get_state(&self) -> RwLockReadGuard>; - fn get_mut_state(&self) -> RwLockWriteGuard; + fn get_mut_state(&self) -> RwLockWriteGuard>; fn process_block(&self, block: BeaconBlock) -> Result; @@ -24,7 +24,7 @@ pub trait BeaconChain: Send + Sync { fn produce_block( &self, randao_reveal: Signature, - ) -> Result<(BeaconBlock, BeaconState), BlockProductionError>; + ) -> Result<(BeaconBlock, BeaconState), BlockProductionError>; fn produce_attestation_data(&self, shard: u64) -> Result; @@ -34,21 +34,22 @@ pub trait BeaconChain: Send + Sync { ) -> Result<(), AttestationValidationError>; } -impl BeaconChain for RawBeaconChain +impl BeaconChain for RawBeaconChain where T: ClientDB + Sized, U: SlotClock, F: ForkChoice, + B: BeaconStateTypes, { fn get_spec(&self) -> &ChainSpec { &self.spec } - fn get_state(&self) -> RwLockReadGuard { + fn get_state(&self) -> RwLockReadGuard> { self.state.read() } - fn get_mut_state(&self) -> RwLockWriteGuard { + fn get_mut_state(&self) -> RwLockWriteGuard> { self.state.write() } @@ -62,7 +63,7 @@ where fn produce_block( &self, randao_reveal: Signature, - ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { + ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { self.produce_block(randao_reveal) } diff --git a/beacon_node/rpc/src/beacon_node.rs b/beacon_node/rpc/src/beacon_node.rs index a9b8df343..ed36b3deb 100644 --- a/beacon_node/rpc/src/beacon_node.rs +++ b/beacon_node/rpc/src/beacon_node.rs @@ -5,14 +5,15 @@ use protos::services::{Empty, Fork, NodeInfoResponse}; use protos::services_grpc::BeaconNodeService; use slog::{trace, warn}; use std::sync::Arc; +use types::BeaconStateTypes; #[derive(Clone)] -pub struct BeaconNodeServiceInstance { - pub chain: Arc, +pub struct BeaconNodeServiceInstance { + pub chain: Arc>, pub log: slog::Logger, } -impl BeaconNodeService for BeaconNodeServiceInstance { +impl BeaconNodeService for BeaconNodeServiceInstance { /// Provides basic node information. fn info(&mut self, ctx: RpcContext, _req: Empty, sink: UnarySink) { trace!(self.log, "Node info requested via RPC"); diff --git a/beacon_node/rpc/src/lib.rs b/beacon_node/rpc/src/lib.rs index 5aac4ce55..ef1a6fc76 100644 --- a/beacon_node/rpc/src/lib.rs +++ b/beacon_node/rpc/src/lib.rs @@ -21,12 +21,13 @@ use protos::services_grpc::{ use slog::{info, o, warn}; use std::sync::Arc; use tokio::runtime::TaskExecutor; +use types::BeaconStateTypes; -pub fn start_server( +pub fn start_server( config: &RPCConfig, executor: &TaskExecutor, network_chan: crossbeam_channel::Sender, - beacon_chain: Arc, + beacon_chain: Arc>, log: &slog::Logger, ) -> exit_future::Signal { let log = log.new(o!("Service"=>"RPC")); diff --git a/beacon_node/rpc/src/validator.rs b/beacon_node/rpc/src/validator.rs index 4bef1e2e6..8bddcd91a 100644 --- a/beacon_node/rpc/src/validator.rs +++ b/beacon_node/rpc/src/validator.rs @@ -7,16 +7,16 @@ use protos::services_grpc::ValidatorService; use slog::{trace, warn}; use ssz::decode; use std::sync::Arc; -use types::{Epoch, RelativeEpoch}; +use types::{BeaconStateTypes, Epoch, RelativeEpoch}; #[derive(Clone)] -pub struct ValidatorServiceInstance { - pub chain: Arc, +pub struct ValidatorServiceInstance { + pub chain: Arc>, pub log: slog::Logger, } //TODO: Refactor Errors -impl ValidatorService for ValidatorServiceInstance { +impl ValidatorService for ValidatorServiceInstance { /// For a list of validator public keys, this function returns the slot at which each /// validator must propose a block, attest to a shard, their shard committee and the shard they /// need to attest to. diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index 5012ebb37..1a45088d1 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -2,7 +2,7 @@ use crate::*; use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192}; use std::fmt::Debug; -pub trait BeaconStateTypes: Default + Sync + Send + Clone + Debug + PartialEq { +pub trait BeaconStateTypes: 'static + Default + Sync + Send + Clone + Debug + PartialEq { type ShardCount: Unsigned + Clone + Sync + Send + Debug + PartialEq; type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send + Debug + PartialEq; type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; From 4c0c93f0c97cfee7cdeddb5f306611fc5bbec056 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 9 May 2019 09:40:32 +1000 Subject: [PATCH 11/22] Update `beacon_node` to work w/ `BeaconStateTypes` --- beacon_node/client/src/client_config.rs | 4 ++-- beacon_node/client/src/client_types.rs | 14 +++++++++----- beacon_node/client/src/lib.rs | 8 +++++--- .../src/beacon_state/beacon_state_types.rs | 18 ++++++++++++++++++ eth2/utils/fixed_len_vec/src/lib.rs | 1 - 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/beacon_node/client/src/client_config.rs b/beacon_node/client/src/client_config.rs index 407171ff5..74ef5f2e5 100644 --- a/beacon_node/client/src/client_config.rs +++ b/beacon_node/client/src/client_config.rs @@ -9,8 +9,8 @@ use std::net::{IpAddr, Ipv4Addr}; use std::path::PathBuf; use types::multiaddr::Protocol; use types::multiaddr::ToMultiaddr; -use types::ChainSpec; use types::Multiaddr; +use types::{BeaconStateTypes, ChainSpec, LighthouseTestnetStateTypes}; /// Stores the client configuration for this Lighthouse instance. #[derive(Debug, Clone)] @@ -35,7 +35,7 @@ impl Default for ClientConfig { fs::create_dir_all(&data_dir) .unwrap_or_else(|_| panic!("Unable to create {:?}", &data_dir)); - let default_spec = ChainSpec::lighthouse_testnet(); + let default_spec = LighthouseTestnetStateTypes::spec(); let default_net_conf = NetworkConfig::new(default_spec.boot_nodes.clone()); Self { diff --git a/beacon_node/client/src/client_types.rs b/beacon_node/client/src/client_types.rs index f5abc77ce..b934b508e 100644 --- a/beacon_node/client/src/client_types.rs +++ b/beacon_node/client/src/client_types.rs @@ -7,6 +7,7 @@ use beacon_chain::{ BeaconChain, }; use fork_choice::ForkChoice; +use types::{BeaconStateTypes, FewValidatorsStateTypes, FoundationStateTypes}; use std::sync::Arc; @@ -14,10 +15,11 @@ pub trait ClientTypes { type DB: ClientDB + 'static; type SlotClock: SlotClock + 'static; type ForkChoice: ForkChoice + 'static; + type BeaconStateTypes: BeaconStateTypes + 'static; fn initialise_beacon_chain( config: &ClientConfig, - ) -> Arc>; + ) -> Arc>; } pub struct StandardClientType; @@ -25,11 +27,12 @@ pub struct StandardClientType; impl ClientTypes for StandardClientType { type DB = DiskDB; type SlotClock = SystemTimeSlotClock; - type ForkChoice = BitwiseLMDGhost; + type ForkChoice = BitwiseLMDGhost; + type BeaconStateTypes = FoundationStateTypes; fn initialise_beacon_chain( config: &ClientConfig, - ) -> Arc> { + ) -> Arc> { initialise::initialise_beacon_chain(&config.spec, Some(&config.db_name)) } } @@ -39,11 +42,12 @@ pub struct TestingClientType; impl ClientTypes for TestingClientType { type DB = MemoryDB; type SlotClock = SystemTimeSlotClock; - type ForkChoice = BitwiseLMDGhost; + type ForkChoice = BitwiseLMDGhost; + type BeaconStateTypes = FewValidatorsStateTypes; fn initialise_beacon_chain( config: &ClientConfig, - ) -> Arc> { + ) -> Arc> { initialise::initialise_test_beacon_chain(&config.spec, None) } } diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index 6a21493b1..466256735 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -20,6 +20,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use tokio::runtime::TaskExecutor; use tokio::timer::Interval; +use types::BeaconStateTypes; /// Main beacon node client service. This provides the connection and initialisation of the clients /// sub-services in multiple threads. @@ -27,9 +28,9 @@ pub struct Client { /// Configuration for the lighthouse client. _config: ClientConfig, /// The beacon chain for the running client. - _beacon_chain: Arc>, + _beacon_chain: Arc>, /// Reference to the network service. - pub network: Arc, + pub network: Arc>, /// Signal to terminate the RPC server. pub rpc_exit_signal: Option, /// Signal to terminate the slot timer. @@ -141,11 +142,12 @@ impl Client { } } -fn do_state_catchup(chain: &Arc>, log: &slog::Logger) +fn do_state_catchup(chain: &Arc>, log: &slog::Logger) where T: ClientDB, U: SlotClock, F: ForkChoice, + B: BeaconStateTypes, { if let Some(genesis_height) = chain.slots_since_genesis() { let result = chain.catchup_state(); diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index 1a45088d1..f66591669 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -12,6 +12,7 @@ pub trait BeaconStateTypes: 'static + Default + Sync + Send + Clone + Debug + Pa fn spec() -> ChainSpec; } +/// Ethereum Foundation specifications. #[derive(Clone, PartialEq, Debug, Default)] pub struct FoundationStateTypes; @@ -45,3 +46,20 @@ impl BeaconStateTypes for FewValidatorsStateTypes { } pub type FewValidatorsBeaconState = BeaconState; + +#[derive(Clone, PartialEq, Debug, Default)] +pub struct LighthouseTestnetStateTypes; + +impl BeaconStateTypes for LighthouseTestnetStateTypes { + type ShardCount = U8; + type SlotsPerHistoricalRoot = U8192; + type LatestRandaoMixesLength = U8192; + type LatestActiveIndexRootsLength = U8192; + type LatestSlashedExitLength = U8192; + + fn spec() -> ChainSpec { + ChainSpec::lighthouse_testnet() + } +} + +pub type LighthouseTestnetBeaconState = BeaconState; diff --git a/eth2/utils/fixed_len_vec/src/lib.rs b/eth2/utils/fixed_len_vec/src/lib.rs index d2d4ec57c..0d811566b 100644 --- a/eth2/utils/fixed_len_vec/src/lib.rs +++ b/eth2/utils/fixed_len_vec/src/lib.rs @@ -29,7 +29,6 @@ impl FixedLenVec { impl From> for FixedLenVec { fn from(mut vec: Vec) -> Self { - dbg!(Self::capacity()); vec.resize_with(Self::capacity(), Default::default); Self { From 49c92ef1670891111efdcc74c06062cbcd1478f7 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 9 May 2019 11:48:14 +1000 Subject: [PATCH 12/22] Remove attester, block_producer & test_harness --- Cargo.toml | 3 - beacon_node/beacon_chain/Cargo.toml | 1 - .../beacon_chain/test_harness/Cargo.toml | 43 -- .../beacon_chain/test_harness/README.md | 150 ----- .../specs/validator_registry.yaml | 63 -- .../test_harness/src/beacon_chain_harness.rs | 350 ----------- .../beacon_chain/test_harness/src/bin.rs | 102 ---- .../beacon_chain/test_harness/src/gen_keys.rs | 21 - .../beacon_chain/test_harness/src/lib.rs | 33 - .../beacon_chain/test_harness/src/run_test.rs | 37 -- .../test_harness/src/test_case.rs | 312 ---------- .../test_harness/src/test_case/config.rs | 135 ----- .../test_harness/src/test_case/results.rs | 34 -- .../test_harness/src/test_case/state_check.rs | 206 ------- .../src/test_case/yaml_helpers.rs | 19 - .../validator_harness/direct_beacon_node.rs | 100 --- .../src/validator_harness/direct_duties.rs | 74 --- .../src/validator_harness/local_signer.rs | 36 -- .../test_harness/src/validator_harness/mod.rs | 119 ---- .../beacon_chain/test_harness/tests/chain.rs | 46 -- beacon_node/network/Cargo.toml | 1 - beacon_node/network/tests/tests.rs | 570 ------------------ eth2/attester/Cargo.toml | 11 - eth2/attester/src/lib.rs | 257 -------- eth2/attester/src/test_utils/epoch_map.rs | 44 -- eth2/attester/src/test_utils/local_signer.rs | 31 - eth2/attester/src/test_utils/mod.rs | 7 - .../src/test_utils/simulated_beacon_node.rs | 44 -- eth2/attester/src/traits.rs | 49 -- eth2/block_proposer/Cargo.toml | 12 - eth2/block_proposer/src/lib.rs | 303 ---------- .../src/test_utils/epoch_map.rs | 36 -- .../src/test_utils/local_signer.rs | 35 -- eth2/block_proposer/src/test_utils/mod.rs | 7 - .../src/test_utils/simulated_beacon_node.rs | 48 -- eth2/block_proposer/src/traits.rs | 50 -- validator_client/Cargo.toml | 2 - 37 files changed, 3391 deletions(-) delete mode 100644 beacon_node/beacon_chain/test_harness/Cargo.toml delete mode 100644 beacon_node/beacon_chain/test_harness/README.md delete mode 100644 beacon_node/beacon_chain/test_harness/specs/validator_registry.yaml delete mode 100644 beacon_node/beacon_chain/test_harness/src/beacon_chain_harness.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/bin.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/gen_keys.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/lib.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/run_test.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/test_case.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/test_case/config.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/test_case/results.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/test_case/state_check.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/test_case/yaml_helpers.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/validator_harness/direct_beacon_node.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/validator_harness/direct_duties.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/validator_harness/local_signer.rs delete mode 100644 beacon_node/beacon_chain/test_harness/src/validator_harness/mod.rs delete mode 100644 beacon_node/beacon_chain/test_harness/tests/chain.rs delete mode 100644 beacon_node/network/tests/tests.rs delete mode 100644 eth2/attester/Cargo.toml delete mode 100644 eth2/attester/src/lib.rs delete mode 100644 eth2/attester/src/test_utils/epoch_map.rs delete mode 100644 eth2/attester/src/test_utils/local_signer.rs delete mode 100644 eth2/attester/src/test_utils/mod.rs delete mode 100644 eth2/attester/src/test_utils/simulated_beacon_node.rs delete mode 100644 eth2/attester/src/traits.rs delete mode 100644 eth2/block_proposer/Cargo.toml delete mode 100644 eth2/block_proposer/src/lib.rs delete mode 100644 eth2/block_proposer/src/test_utils/epoch_map.rs delete mode 100644 eth2/block_proposer/src/test_utils/local_signer.rs delete mode 100644 eth2/block_proposer/src/test_utils/mod.rs delete mode 100644 eth2/block_proposer/src/test_utils/simulated_beacon_node.rs delete mode 100644 eth2/block_proposer/src/traits.rs diff --git a/Cargo.toml b/Cargo.toml index 37ec4ad0f..eb472c346 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,5 @@ [workspace] members = [ - "eth2/attester", - "eth2/block_proposer", "eth2/fork_choice", "eth2/operation_pool", "eth2/state_processing", @@ -32,7 +30,6 @@ members = [ "beacon_node/rpc", "beacon_node/version", "beacon_node/beacon_chain", - "beacon_node/beacon_chain/test_harness", "protos", "validator_client", "account_manager", diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index e2a4527a9..34b6e11c6 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Paul Hauner ", "Age Manning "] -edition = "2018" - -[[bin]] -name = "test_harness" -path = "src/bin.rs" - -[lib] -name = "test_harness" -path = "src/lib.rs" - -[dev-dependencies] -state_processing = { path = "../../../eth2/state_processing" } - -[dependencies] -attester = { path = "../../../eth2/attester" } -beacon_chain = { path = "../../beacon_chain" } -block_proposer = { path = "../../../eth2/block_proposer" } -bls = { path = "../../../eth2/utils/bls" } -boolean-bitfield = { path = "../../../eth2/utils/boolean-bitfield" } -clap = "2.32.0" -db = { path = "../../db" } -parking_lot = "0.7" -failure = "0.1" -failure_derive = "0.1" -fork_choice = { path = "../../../eth2/fork_choice" } -hashing = { path = "../../../eth2/utils/hashing" } -int_to_bytes = { path = "../../../eth2/utils/int_to_bytes" } -log = "0.4" -env_logger = "0.6.0" -rayon = "1.0" -serde = "1.0" -serde_derive = "1.0" -serde_json = "1.0" -serde_yaml = "0.8" -slot_clock = { path = "../../../eth2/utils/slot_clock" } -ssz = { path = "../../../eth2/utils/ssz" } -tree_hash = { path = "../../../eth2/utils/tree_hash" } -types = { path = "../../../eth2/types" } -yaml-rust = "0.4.2" diff --git a/beacon_node/beacon_chain/test_harness/README.md b/beacon_node/beacon_chain/test_harness/README.md deleted file mode 100644 index 9dfd90d60..000000000 --- a/beacon_node/beacon_chain/test_harness/README.md +++ /dev/null @@ -1,150 +0,0 @@ -# Test Harness - -Provides a testing environment for the `BeaconChain`, `Attester` and `BlockProposer` objects. - -This environment bypasses networking and client run-times and connects the `Attester` and `Proposer` -directly to the `BeaconChain` via an `Arc`. - -The `BeaconChainHarness` contains a single `BeaconChain` instance and many `ValidatorHarness` -instances. All of the `ValidatorHarness` instances work to advance the `BeaconChain` by -producing blocks and attestations. - -The crate consists of a library and binary, examples for using both are -described below. - -## YAML - -Both the library and the binary are capable of parsing tests from a YAML file, -in fact this is the sole purpose of the binary. - -You can find YAML test cases [here](specs/). An example is included below: - -```yaml -title: Validator Registry Tests -summary: Tests deposit and slashing effects on validator registry. -test_suite: validator_registry -fork: tchaikovsky -version: 1.0 -test_cases: - - config: - slots_per_epoch: 64 - deposits_for_chain_start: 1000 - num_slots: 64 - skip_slots: [2, 3] - deposits: - # At slot 1, create a new validator deposit of 32 ETH. - - slot: 1 - amount: 32 - # Trigger more deposits... - - slot: 3 - amount: 32 - - slot: 5 - amount: 32 - proposer_slashings: - # At slot 2, trigger a proposer slashing for validator #42. - - slot: 2 - validator_index: 42 - # Trigger another slashing... - - slot: 8 - validator_index: 13 - attester_slashings: - # At slot 2, trigger an attester slashing for validators #11 and #12. - - slot: 2 - validator_indices: [11, 12] - # Trigger another slashing... - - slot: 5 - validator_indices: [14] - results: - num_skipped_slots: 2 - states: - - slot: 63 - num_validators: 1003 - slashed_validators: [11, 12, 13, 14, 42] - exited_validators: [] - -``` - -Thanks to [prsym](http://github.com/prysmaticlabs/prysm) for coming up with the -base YAML format. - -### Notes - -Wherever `slot` is used, it is actually the "slot height", or slots since -genesis. This allows the tests to disregard the `GENESIS_EPOCH`. - -### Differences from Prysmatic's format - -1. The detail for `deposits`, `proposer_slashings` and `attester_slashings` is - ommitted from the test specification. It assumed they should be valid - objects. -2. There is a `states` list in `results` that runs checks against any state - specified by a `slot` number. This is in contrast to the variables in - `results` that assume the last (highest) state should be inspected. - -#### Reasoning - -Respective reasonings for above changes: - -1. This removes the concerns of the actual object structure from the tests. - This allows for more variation in the deposits/slashings objects without - needing to update the tests. Also, it makes it makes it easier to create - tests. -2. This gives more fine-grained control over the tests. It allows for checking - that certain events happened at certain times whilst making the tests only - slightly more verbose. - -_Notes: it may be useful to add an extra field to each slashing type to -indicate if it should be valid or not. It also may be useful to add an option -for double-vote/surround-vote attester slashings. The `amount` field was left -on `deposits` as it changes the behaviour of state significantly._ - -## Binary Usage Example - -Follow these steps to run as a binary: - -1. Navigate to the root of this crate (where this readme is located) -2. Run `$ cargo run --release -- --yaml examples/validator_registry.yaml` - -_Note: the `--release` flag builds the binary without all the debugging -instrumentation. The test is much faster built using `--release`. As is -customary in cargo, the flags before `--` are passed to cargo and the flags -after are passed to the binary._ - -### CLI Options - -``` -Lighthouse Test Harness Runner 0.0.1 -Sigma Prime -Runs `test_harness` using a YAML test_case. - -USAGE: - test_harness --log-level --yaml - -FLAGS: - -h, --help Prints help information - -V, --version Prints version information - -OPTIONS: - --log-level Logging level. [default: debug] [possible values: error, warn, info, debug, trace] - --yaml YAML file test_case. -``` - - -## Library Usage Example - -```rust -use test_harness::BeaconChainHarness; -use types::ChainSpec; - -let validator_count = 8; -let spec = ChainSpec::few_validators(); - -let mut harness = BeaconChainHarness::new(spec, validator_count); - -harness.advance_chain_with_block(); - -let chain = harness.chain_dump().unwrap(); - -// One block should have been built on top of the genesis block. -assert_eq!(chain.len(), 2); -``` diff --git a/beacon_node/beacon_chain/test_harness/specs/validator_registry.yaml b/beacon_node/beacon_chain/test_harness/specs/validator_registry.yaml deleted file mode 100644 index ad9c899cf..000000000 --- a/beacon_node/beacon_chain/test_harness/specs/validator_registry.yaml +++ /dev/null @@ -1,63 +0,0 @@ -title: Validator Registry Tests -summary: Tests deposit and slashing effects on validator registry. -test_suite: validator_registry -fork: tchaikovsky -version: 1.0 -test_cases: - - config: - slots_per_epoch: 64 - deposits_for_chain_start: 1000 - num_slots: 64 - skip_slots: [2, 3] - persistent_committee_period: 0 - deposits: - # At slot 1, create a new validator deposit of 5 ETH. - - slot: 1 - amount: 5000000000 - # Trigger more deposits... - - slot: 3 - amount: 5000000000 - - slot: 5 - amount: 32000000000 - exits: - # At slot 10, submit an exit for validator #50. - - slot: 10 - validator_index: 50 - transfers: - - slot: 6 - from: 1000 - to: 1001 - amount: 5000000000 - proposer_slashings: - # At slot 2, trigger a proposer slashing for validator #42. - - slot: 2 - validator_index: 42 - # Trigger another slashing... - - slot: 8 - validator_index: 13 - attester_slashings: - # At slot 2, trigger an attester slashing for validators #11 and #12. - - slot: 2 - validator_indices: [11, 12] - # Trigger another slashing... - - slot: 5 - validator_indices: [14] - results: - num_skipped_slots: 2 - states: - - slot: 63 - num_validators: 1003 - num_previous_epoch_attestations: 0 - # slots_per_epoch - attestation_inclusion_delay - skip_slots - num_current_epoch_attestations: 57 - slashed_validators: [11, 12, 13, 14, 42] - exited_validators: [] - exit_initiated_validators: [50] - balances: - - validator_index: 1000 - comparison: "eq" - balance: 0 - - validator_index: 1001 - comparison: "eq" - balance: 10000000000 - diff --git a/beacon_node/beacon_chain/test_harness/src/beacon_chain_harness.rs b/beacon_node/beacon_chain/test_harness/src/beacon_chain_harness.rs deleted file mode 100644 index 34b559478..000000000 --- a/beacon_node/beacon_chain/test_harness/src/beacon_chain_harness.rs +++ /dev/null @@ -1,350 +0,0 @@ -use super::ValidatorHarness; -use beacon_chain::{BeaconChain, BlockProcessingOutcome}; -pub use beacon_chain::{BeaconChainError, CheckPoint}; -use db::{ - stores::{BeaconBlockStore, BeaconStateStore}, - MemoryDB, -}; -use fork_choice::BitwiseLMDGhost; -use log::debug; -use rayon::prelude::*; -use slot_clock::TestingSlotClock; -use std::sync::Arc; -use tree_hash::TreeHash; -use types::{test_utils::TestingBeaconStateBuilder, *}; - -type TestingBeaconChain = BeaconChain>; - -/// The beacon chain harness simulates a single beacon node with `validator_count` validators connected -/// to it. Each validator is provided a borrow to the beacon chain, where it may read -/// information and submit blocks/attestations for processing. -/// -/// This test harness is useful for testing validator and internal state transition logic. It -/// is not useful for testing that multiple beacon nodes can reach consensus. -pub struct BeaconChainHarness { - pub db: Arc, - pub beacon_chain: Arc, - pub block_store: Arc>, - pub state_store: Arc>, - pub validators: Vec, - pub spec: Arc, -} - -impl BeaconChainHarness { - /// Create a new harness with: - /// - /// - A keypair, `BlockProducer` and `Attester` for each validator. - /// - A new BeaconChain struct where the given validators are in the genesis. - pub fn new(spec: ChainSpec, validator_count: usize) -> Self { - let state_builder = - TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, &spec); - Self::from_beacon_state_builder(state_builder, spec) - } - - pub fn from_beacon_state_builder( - state_builder: TestingBeaconStateBuilder, - spec: ChainSpec, - ) -> Self { - let db = Arc::new(MemoryDB::open()); - let block_store = Arc::new(BeaconBlockStore::new(db.clone())); - let state_store = Arc::new(BeaconStateStore::new(db.clone())); - let slot_clock = TestingSlotClock::new(spec.genesis_slot.as_u64()); - let fork_choice = BitwiseLMDGhost::new(block_store.clone(), state_store.clone()); - - let (mut genesis_state, keypairs) = state_builder.build(); - - let mut genesis_block = BeaconBlock::empty(&spec); - genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root()); - - genesis_state - .build_epoch_cache(RelativeEpoch::Previous, &spec) - .unwrap(); - genesis_state - .build_epoch_cache(RelativeEpoch::Current, &spec) - .unwrap(); - genesis_state - .build_epoch_cache(RelativeEpoch::NextWithoutRegistryChange, &spec) - .unwrap(); - genesis_state - .build_epoch_cache(RelativeEpoch::NextWithRegistryChange, &spec) - .unwrap(); - - // Create the Beacon Chain - let beacon_chain = Arc::new( - BeaconChain::from_genesis( - state_store.clone(), - block_store.clone(), - slot_clock, - genesis_state, - genesis_block, - spec.clone(), - fork_choice, - ) - .unwrap(), - ); - - let spec = Arc::new(spec); - - debug!("Creating validator producer and attester instances..."); - - // Spawn the test validator instances. - let validators: Vec = keypairs - .iter() - .map(|keypair| { - ValidatorHarness::new(keypair.clone(), beacon_chain.clone(), spec.clone()) - }) - .collect(); - - debug!("Created {} ValidatorHarnesss", validators.len()); - - Self { - db, - beacon_chain, - block_store, - state_store, - validators, - spec, - } - } - - /// Move the `slot_clock` for the `BeaconChain` forward one slot. - /// - /// This is the equivalent of advancing a system clock forward one `SLOT_DURATION`. - /// - /// Returns the new slot. - pub fn increment_beacon_chain_slot(&mut self) -> Slot { - let slot = self.beacon_chain.present_slot() + 1; - - let nth_slot = slot - - slot - .epoch(self.spec.slots_per_epoch) - .start_slot(self.spec.slots_per_epoch); - let nth_epoch = slot.epoch(self.spec.slots_per_epoch) - self.spec.genesis_epoch; - debug!( - "Advancing BeaconChain to slot {}, epoch {} (epoch height: {}, slot {} in epoch.).", - slot, - slot.epoch(self.spec.slots_per_epoch), - nth_epoch, - nth_slot - ); - - self.beacon_chain.slot_clock.set_slot(slot.as_u64()); - self.beacon_chain - .catchup_state() - .expect("Failed to catch state"); - slot - } - - pub fn gather_attesations(&mut self) -> Vec { - let present_slot = self.beacon_chain.present_slot(); - let state = self.beacon_chain.state.read(); - - let mut attestations = vec![]; - - for committee in state - .get_crosslink_committees_at_slot(present_slot, &self.spec) - .unwrap() - { - for &validator in &committee.committee { - let duties = state - .get_attestation_duties(validator, &self.spec) - .unwrap() - .expect("Attesting validators by definition have duties"); - - // Obtain `AttestationData` from the beacon chain. - let data = self - .beacon_chain - .produce_attestation_data(duties.shard) - .unwrap(); - - // Produce an aggregate signature with a single signature. - let aggregate_signature = { - let message = AttestationDataAndCustodyBit { - data: data.clone(), - custody_bit: false, - } - .tree_hash_root(); - let domain = self.spec.get_domain( - state.slot.epoch(self.spec.slots_per_epoch), - Domain::Attestation, - &state.fork, - ); - let sig = - Signature::new(&message, domain, &self.validators[validator].keypair.sk); - - let mut agg_sig = AggregateSignature::new(); - agg_sig.add(&sig); - - agg_sig - }; - - let mut aggregation_bitfield = Bitfield::with_capacity(duties.committee_len); - let custody_bitfield = Bitfield::with_capacity(duties.committee_len); - - aggregation_bitfield.set(duties.committee_index, true); - - attestations.push(Attestation { - aggregation_bitfield, - data, - custody_bitfield, - aggregate_signature, - }) - } - } - - attestations - } - - /// Get the block from the proposer for the slot. - /// - /// Note: the validator will only produce it _once per slot_. So, if you call this twice you'll - /// only get a block once. - pub fn produce_block(&mut self) -> BeaconBlock { - let present_slot = self.beacon_chain.present_slot(); - - let proposer = self.beacon_chain.block_proposer(present_slot).unwrap(); - - debug!( - "Producing block from validator #{} for slot {}.", - proposer, present_slot - ); - - // Ensure the validators slot clock is accurate. - self.validators[proposer].set_slot(present_slot); - - self.validators[proposer].produce_block().unwrap() - } - - /// Advances the chain with a BeaconBlock and attestations from all validators. - /// - /// This is the ideal scenario for the Beacon Chain, 100% honest participation from - /// validators. - pub fn advance_chain_with_block(&mut self) -> BeaconBlock { - self.increment_beacon_chain_slot(); - - // Produce a new block. - let block = self.produce_block(); - debug!("Submitting block for processing..."); - match self.beacon_chain.process_block(block.clone()) { - Ok(BlockProcessingOutcome::ValidBlock(_)) => {} - other => panic!("block processing failed with {:?}", other), - }; - debug!("...block processed by BeaconChain."); - - debug!("Producing attestations..."); - - // Produce new attestations. - let attestations = self.gather_attesations(); - - debug!("Processing {} attestations...", attestations.len()); - - attestations - .par_iter() - .enumerate() - .for_each(|(i, attestation)| { - self.beacon_chain - .process_attestation(attestation.clone()) - .unwrap_or_else(|_| panic!("Attestation {} invalid: {:?}", i, attestation)); - }); - - debug!("Attestations processed."); - - block - } - - /// Signs a message using some validators secret key with the `Fork` info from the latest state - /// of the `BeaconChain`. - /// - /// Useful for producing slashable messages and other objects that `BeaconChainHarness` does - /// not produce naturally. - pub fn validator_sign( - &self, - validator_index: usize, - message: &[u8], - epoch: Epoch, - domain_type: Domain, - ) -> Option { - let validator = self.validators.get(validator_index)?; - - let domain = self - .spec - .get_domain(epoch, domain_type, &self.beacon_chain.state.read().fork); - - Some(Signature::new(message, domain, &validator.keypair.sk)) - } - - /// Returns the current `Fork` of the `beacon_chain`. - pub fn fork(&self) -> Fork { - self.beacon_chain.state.read().fork.clone() - } - - /// Returns the current `epoch` of the `beacon_chain`. - pub fn epoch(&self) -> Epoch { - self.beacon_chain - .state - .read() - .slot - .epoch(self.spec.slots_per_epoch) - } - - /// Returns the keypair for some validator index. - pub fn validator_keypair(&self, validator_index: usize) -> Option<&Keypair> { - self.validators - .get(validator_index) - .and_then(|v| Some(&v.keypair)) - } - - /// Submit a deposit to the `BeaconChain` and, if given a keypair, create a new - /// `ValidatorHarness` instance for this validator. - /// - /// If a new `ValidatorHarness` was created, the validator should become fully operational as - /// if the validator were created during `BeaconChainHarness` instantiation. - pub fn add_deposit(&mut self, deposit: Deposit, keypair: Option) { - self.beacon_chain.process_deposit(deposit).unwrap(); - - // If a keypair is present, add a new `ValidatorHarness` to the rig. - if let Some(keypair) = keypair { - let validator = - ValidatorHarness::new(keypair, self.beacon_chain.clone(), self.spec.clone()); - self.validators.push(validator); - } - } - - /// Submit an exit to the `BeaconChain` for inclusion in some block. - /// - /// Note: the `ValidatorHarness` for this validator continues to exist. Once it is exited it - /// will stop receiving duties from the beacon chain and just do nothing when prompted to - /// produce/attest. - pub fn add_exit(&mut self, exit: VoluntaryExit) { - self.beacon_chain.process_voluntary_exit(exit).unwrap(); - } - - /// Submit an transfer to the `BeaconChain` for inclusion in some block. - pub fn add_transfer(&mut self, transfer: Transfer) { - self.beacon_chain.process_transfer(transfer).unwrap(); - } - - /// Submit a proposer slashing to the `BeaconChain` for inclusion in some block. - pub fn add_proposer_slashing(&mut self, proposer_slashing: ProposerSlashing) { - self.beacon_chain - .process_proposer_slashing(proposer_slashing) - .unwrap(); - } - - /// Submit an attester slashing to the `BeaconChain` for inclusion in some block. - pub fn add_attester_slashing(&mut self, attester_slashing: AttesterSlashing) { - self.beacon_chain - .process_attester_slashing(attester_slashing) - .unwrap(); - } - - /// Executes the fork choice rule on the `BeaconChain`, selecting a new canonical head. - pub fn run_fork_choice(&mut self) { - self.beacon_chain.fork_choice().unwrap() - } - - /// Dump all blocks and states from the canonical beacon chain. - pub fn chain_dump(&self) -> Result, BeaconChainError> { - self.beacon_chain.chain_dump() - } -} diff --git a/beacon_node/beacon_chain/test_harness/src/bin.rs b/beacon_node/beacon_chain/test_harness/src/bin.rs deleted file mode 100644 index 3afc921de..000000000 --- a/beacon_node/beacon_chain/test_harness/src/bin.rs +++ /dev/null @@ -1,102 +0,0 @@ -use clap::{App, Arg, SubCommand}; -use env_logger::{Builder, Env}; -use gen_keys::gen_keys; -use run_test::run_test; -use std::fs; -use types::test_utils::keypairs_path; -use types::ChainSpec; - -mod beacon_chain_harness; -mod gen_keys; -mod run_test; -mod test_case; -mod validator_harness; - -use validator_harness::ValidatorHarness; - -fn main() { - let validator_file_path = keypairs_path(); - - let _ = fs::create_dir(validator_file_path.parent().unwrap()); - - let matches = App::new("Lighthouse Test Harness Runner") - .version("0.0.1") - .author("Sigma Prime ") - .about("Runs `test_harness` using a YAML test_case.") - .arg( - Arg::with_name("log") - .long("log-level") - .short("l") - .value_name("LOG_LEVEL") - .help("Logging level.") - .possible_values(&["error", "warn", "info", "debug", "trace"]) - .default_value("debug") - .required(true), - ) - .arg( - Arg::with_name("spec") - .long("spec") - .short("s") - .value_name("SPECIFICATION") - .help("ChainSpec instantiation.") - .possible_values(&["foundation", "few_validators"]) - .default_value("foundation"), - ) - .subcommand( - SubCommand::with_name("run_test") - .about("Executes a YAML test specification") - .arg( - Arg::with_name("yaml") - .long("yaml") - .value_name("FILE") - .help("YAML file test_case.") - .required(true), - ) - .arg( - Arg::with_name("validators_dir") - .long("validators-dir") - .short("v") - .value_name("VALIDATORS_DIR") - .help("A directory with validator deposits and keypair YAML."), - ), - ) - .subcommand( - SubCommand::with_name("gen_keys") - .about("Builds a file of BLS keypairs for faster tests.") - .arg( - Arg::with_name("validator_count") - .long("validator_count") - .short("n") - .value_name("VALIDATOR_COUNT") - .help("Number of validators to generate.") - .required(true), - ) - .arg( - Arg::with_name("output_file") - .long("output_file") - .short("d") - .value_name("GENESIS_TIME") - .help("Output directory for generated YAML.") - .default_value(validator_file_path.to_str().unwrap()), - ), - ) - .get_matches(); - - if let Some(log_level) = matches.value_of("log") { - Builder::from_env(Env::default().default_filter_or(log_level)).init(); - } - - let _spec = match matches.value_of("spec") { - Some("foundation") => ChainSpec::foundation(), - Some("few_validators") => ChainSpec::few_validators(), - _ => unreachable!(), // Has a default value, should always exist. - }; - - if let Some(matches) = matches.subcommand_matches("run_test") { - run_test(matches); - } - - if let Some(matches) = matches.subcommand_matches("gen_keys") { - gen_keys(matches); - } -} diff --git a/beacon_node/beacon_chain/test_harness/src/gen_keys.rs b/beacon_node/beacon_chain/test_harness/src/gen_keys.rs deleted file mode 100644 index abd512423..000000000 --- a/beacon_node/beacon_chain/test_harness/src/gen_keys.rs +++ /dev/null @@ -1,21 +0,0 @@ -use clap::{value_t, ArgMatches}; -use log::debug; -use std::path::Path; -use types::test_utils::{generate_deterministic_keypairs, KeypairsFile}; - -/// Creates a file containing BLS keypairs. -pub fn gen_keys(matches: &ArgMatches) { - let validator_count = value_t!(matches.value_of("validator_count"), usize) - .expect("Validator count is required argument"); - let output_file = matches - .value_of("output_file") - .expect("Output file has a default value."); - - let keypairs = generate_deterministic_keypairs(validator_count); - - debug!("Writing keypairs to file..."); - - let keypairs_path = Path::new(output_file); - - keypairs.to_raw_file(&keypairs_path, &keypairs).unwrap(); -} diff --git a/beacon_node/beacon_chain/test_harness/src/lib.rs b/beacon_node/beacon_chain/test_harness/src/lib.rs deleted file mode 100644 index e93fa7003..000000000 --- a/beacon_node/beacon_chain/test_harness/src/lib.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! Provides a testing environment for the `BeaconChain`, `Attester` and `BlockProposer` objects. -//! -//! This environment bypasses networking and client run-times and connects the `Attester` and `Proposer` -//! directly to the `BeaconChain` via an `Arc`. -//! -//! The `BeaconChainHarness` contains a single `BeaconChain` instance and many `ValidatorHarness` -//! instances. All of the `ValidatorHarness` instances work to advance the `BeaconChain` by -//! producing blocks and attestations. -//! -//! Example: -//! ```rust,no_run -//! use test_harness::BeaconChainHarness; -//! use types::ChainSpec; -//! -//! let validator_count = 8; -//! let spec = ChainSpec::few_validators(); -//! -//! let mut harness = BeaconChainHarness::new(spec, validator_count); -//! -//! harness.advance_chain_with_block(); -//! -//! let chain = harness.chain_dump().unwrap(); -//! -//! // One block should have been built on top of the genesis block. -//! assert_eq!(chain.len(), 2); -//! ``` - -mod beacon_chain_harness; -pub mod test_case; -mod validator_harness; - -pub use self::beacon_chain_harness::BeaconChainHarness; -pub use self::validator_harness::ValidatorHarness; diff --git a/beacon_node/beacon_chain/test_harness/src/run_test.rs b/beacon_node/beacon_chain/test_harness/src/run_test.rs deleted file mode 100644 index 4caa299d6..000000000 --- a/beacon_node/beacon_chain/test_harness/src/run_test.rs +++ /dev/null @@ -1,37 +0,0 @@ -use crate::test_case::TestCase; -use clap::ArgMatches; -use std::{fs::File, io::prelude::*}; -use yaml_rust::YamlLoader; - -/// Runs a YAML-specified test case. -pub fn run_test(matches: &ArgMatches) { - if let Some(yaml_file) = matches.value_of("yaml") { - let docs = { - let mut file = File::open(yaml_file).unwrap(); - - let mut yaml_str = String::new(); - file.read_to_string(&mut yaml_str).unwrap(); - - YamlLoader::load_from_str(&yaml_str).unwrap() - }; - - for doc in &docs { - // For each `test_cases` YAML in the document, build a `TestCase`, execute it and - // assert that the execution result matches the test_case description. - // - // In effect, for each `test_case` a new `BeaconChainHarness` is created from genesis - // and a new `BeaconChain` is built as per the test_case. - // - // After the `BeaconChain` has been built out as per the test_case, a dump of all blocks - // and states in the chain is obtained and checked against the `results` specified in - // the `test_case`. - // - // If any of the expectations in the results are not met, the process - // panics with a message. - for test_case in doc["test_cases"].as_vec().unwrap() { - let test_case = TestCase::from_yaml(test_case); - test_case.assert_result_valid(test_case.execute()) - } - } - } -} diff --git a/beacon_node/beacon_chain/test_harness/src/test_case.rs b/beacon_node/beacon_chain/test_harness/src/test_case.rs deleted file mode 100644 index 28c7ae8a8..000000000 --- a/beacon_node/beacon_chain/test_harness/src/test_case.rs +++ /dev/null @@ -1,312 +0,0 @@ -//! Defines execution and testing specs for a `BeaconChainHarness` instance. Supports loading from -//! a YAML file. - -use crate::beacon_chain_harness::BeaconChainHarness; -use beacon_chain::CheckPoint; -use log::{info, warn}; -use tree_hash::SignedRoot; -use types::*; - -use types::test_utils::*; -use yaml_rust::Yaml; - -mod config; -mod results; -mod state_check; -mod yaml_helpers; - -pub use config::Config; -pub use results::Results; -pub use state_check::StateCheck; - -/// Defines the execution and testing of a `BeaconChainHarness` instantiation. -/// -/// Typical workflow is: -/// -/// 1. Instantiate the `TestCase` from YAML: `let test_case = TestCase::from_yaml(&my_yaml);` -/// 2. Execute the test_case: `let result = test_case.execute();` -/// 3. Test the results against the test_case: `test_case.assert_result_valid(result);` -#[derive(Debug)] -pub struct TestCase { - /// Defines the execution. - pub config: Config, - /// Defines tests to run against the execution result. - pub results: Results, -} - -/// The result of executing a `TestCase`. -/// -pub struct ExecutionResult { - /// The canonical beacon chain generated from the execution. - pub chain: Vec, - /// The spec used for execution. - pub spec: ChainSpec, -} - -impl TestCase { - /// Load the test case from a YAML document. - pub fn from_yaml(test_case: &Yaml) -> Self { - Self { - results: Results::from_yaml(&test_case["results"]), - config: Config::from_yaml(&test_case["config"]), - } - } - - /// Return a `ChainSpec::foundation()`. - /// - /// If specified in `config`, returns it with a modified `slots_per_epoch`. - fn spec(&self) -> ChainSpec { - let mut spec = ChainSpec::foundation(); - - if let Some(n) = self.config.slots_per_epoch { - spec.slots_per_epoch = n; - } - - if let Some(n) = self.config.persistent_committee_period { - spec.persistent_committee_period = n; - } - - spec - } - - /// Executes the test case, returning an `ExecutionResult`. - #[allow(clippy::cyclomatic_complexity)] - pub fn execute(&self) -> ExecutionResult { - let spec = self.spec(); - let validator_count = self.config.deposits_for_chain_start; - let slots = self.config.num_slots; - - info!( - "Building BeaconChainHarness with {} validators...", - validator_count - ); - - let mut harness = BeaconChainHarness::new(spec, validator_count); - - info!("Starting simulation across {} slots...", slots); - - // Start at 1 because genesis counts as a slot. - for slot_height in 1..slots { - // Used to ensure that deposits in the same slot have incremental deposit indices. - let mut deposit_index_offset = 0; - - // Feed deposits to the BeaconChain. - if let Some(ref deposits) = self.config.deposits { - for (slot, amount) in deposits { - if *slot == slot_height { - info!("Including deposit at slot height {}.", slot_height); - let (deposit, keypair) = - build_deposit(&harness, *amount, deposit_index_offset); - harness.add_deposit(deposit, Some(keypair.clone())); - deposit_index_offset += 1; - } - } - } - - // Feed proposer slashings to the BeaconChain. - if let Some(ref slashings) = self.config.proposer_slashings { - for (slot, validator_index) in slashings { - if *slot == slot_height { - info!( - "Including proposer slashing at slot height {} for validator #{}.", - slot_height, validator_index - ); - let slashing = build_proposer_slashing(&harness, *validator_index); - harness.add_proposer_slashing(slashing); - } - } - } - - // Feed attester slashings to the BeaconChain. - if let Some(ref slashings) = self.config.attester_slashings { - for (slot, validator_indices) in slashings { - if *slot == slot_height { - info!( - "Including attester slashing at slot height {} for validators {:?}.", - slot_height, validator_indices - ); - let slashing = - build_double_vote_attester_slashing(&harness, &validator_indices[..]); - harness.add_attester_slashing(slashing); - } - } - } - - // Feed exits to the BeaconChain. - if let Some(ref exits) = self.config.exits { - for (slot, validator_index) in exits { - if *slot == slot_height { - info!( - "Including exit at slot height {} for validator {}.", - slot_height, validator_index - ); - let exit = build_exit(&harness, *validator_index); - harness.add_exit(exit); - } - } - } - - // Feed transfers to the BeaconChain. - if let Some(ref transfers) = self.config.transfers { - for (slot, from, to, amount) in transfers { - if *slot == slot_height { - info!( - "Including transfer at slot height {} from validator {}.", - slot_height, from - ); - let transfer = build_transfer(&harness, *from, *to, *amount); - harness.add_transfer(transfer); - } - } - } - - // Build a block or skip a slot. - match self.config.skip_slots { - Some(ref skip_slots) if skip_slots.contains(&slot_height) => { - warn!("Skipping slot at height {}.", slot_height); - harness.increment_beacon_chain_slot(); - } - _ => { - info!("Producing block at slot height {}.", slot_height); - harness.advance_chain_with_block(); - } - } - } - - harness.run_fork_choice(); - - info!("Test execution complete!"); - - info!("Building chain dump for analysis..."); - - ExecutionResult { - chain: harness.chain_dump().expect("Chain dump failed."), - spec: (*harness.spec).clone(), - } - } - - /// Checks that the `ExecutionResult` is consistent with the specifications in `self.results`. - /// - /// # Panics - /// - /// Panics with a message if any result does not match exepectations. - pub fn assert_result_valid(&self, execution_result: ExecutionResult) { - info!("Verifying test results..."); - let spec = &execution_result.spec; - - if let Some(num_skipped_slots) = self.results.num_skipped_slots { - assert_eq!( - execution_result.chain.len(), - self.config.num_slots as usize - num_skipped_slots, - "actual skipped slots != expected." - ); - info!( - "OK: Chain length is {} ({} skipped slots).", - execution_result.chain.len(), - num_skipped_slots - ); - } - - if let Some(ref state_checks) = self.results.state_checks { - for checkpoint in &execution_result.chain { - let state = &checkpoint.beacon_state; - - for state_check in state_checks { - let adjusted_state_slot = - state.slot - spec.genesis_epoch.start_slot(spec.slots_per_epoch); - - if state_check.slot == adjusted_state_slot { - state_check.assert_valid(state, spec); - } - } - } - } - } -} - -/// Builds a `Deposit` this is valid for the given `BeaconChainHarness` at its next slot. -fn build_transfer( - harness: &BeaconChainHarness, - sender: u64, - recipient: u64, - amount: u64, -) -> Transfer { - let slot = harness.beacon_chain.state.read().slot + 1; - - let mut builder = TestingTransferBuilder::new(sender, recipient, amount, slot); - - let keypair = harness.validator_keypair(sender as usize).unwrap(); - builder.sign(keypair.clone(), &harness.fork(), &harness.spec); - - builder.build() -} - -/// Builds a `Deposit` this is valid for the given `BeaconChainHarness`. -/// -/// `index_offset` is used to ensure that `deposit.index == state.index` when adding multiple -/// deposits. -fn build_deposit( - harness: &BeaconChainHarness, - amount: u64, - index_offset: u64, -) -> (Deposit, Keypair) { - let keypair = Keypair::random(); - - let mut builder = TestingDepositBuilder::new(keypair.pk.clone(), amount); - builder.set_index(harness.beacon_chain.state.read().deposit_index + index_offset); - builder.sign(&keypair, harness.epoch(), &harness.fork(), &harness.spec); - - (builder.build(), keypair) -} - -/// Builds a `VoluntaryExit` this is valid for the given `BeaconChainHarness`. -fn build_exit(harness: &BeaconChainHarness, validator_index: u64) -> VoluntaryExit { - let epoch = harness - .beacon_chain - .state - .read() - .current_epoch(&harness.spec); - - let mut exit = VoluntaryExit { - epoch, - validator_index, - signature: Signature::empty_signature(), - }; - - let message = exit.signed_root(); - - exit.signature = harness - .validator_sign(validator_index as usize, &message[..], epoch, Domain::Exit) - .expect("Unable to sign VoluntaryExit"); - - exit -} - -/// Builds an `AttesterSlashing` for some `validator_indices`. -/// -/// Signs the message using a `BeaconChainHarness`. -fn build_double_vote_attester_slashing( - harness: &BeaconChainHarness, - validator_indices: &[u64], -) -> AttesterSlashing { - let signer = |validator_index: u64, message: &[u8], epoch: Epoch, domain: Domain| { - harness - .validator_sign(validator_index as usize, message, epoch, domain) - .expect("Unable to sign AttesterSlashing") - }; - - TestingAttesterSlashingBuilder::double_vote(validator_indices, signer) -} - -/// Builds an `ProposerSlashing` for some `validator_index`. -/// -/// Signs the message using a `BeaconChainHarness`. -fn build_proposer_slashing(harness: &BeaconChainHarness, validator_index: u64) -> ProposerSlashing { - let signer = |validator_index: u64, message: &[u8], epoch: Epoch, domain: Domain| { - harness - .validator_sign(validator_index as usize, message, epoch, domain) - .expect("Unable to sign AttesterSlashing") - }; - - TestingProposerSlashingBuilder::double_vote(validator_index, signer, &harness.spec) -} diff --git a/beacon_node/beacon_chain/test_harness/src/test_case/config.rs b/beacon_node/beacon_chain/test_harness/src/test_case/config.rs deleted file mode 100644 index 12d5da2d7..000000000 --- a/beacon_node/beacon_chain/test_harness/src/test_case/config.rs +++ /dev/null @@ -1,135 +0,0 @@ -use super::yaml_helpers::{as_u64, as_usize, as_vec_u64}; -use types::*; -use yaml_rust::Yaml; - -pub type ValidatorIndex = u64; -pub type ValidatorIndices = Vec; -pub type GweiAmount = u64; - -pub type DepositTuple = (SlotHeight, GweiAmount); -pub type ExitTuple = (SlotHeight, ValidatorIndex); -pub type ProposerSlashingTuple = (SlotHeight, ValidatorIndex); -pub type AttesterSlashingTuple = (SlotHeight, ValidatorIndices); -/// (slot_height, from, to, amount) -pub type TransferTuple = (SlotHeight, ValidatorIndex, ValidatorIndex, GweiAmount); - -/// Defines the execution of a `BeaconStateHarness` across a series of slots. -#[derive(Debug)] -pub struct Config { - /// Initial validators. - pub deposits_for_chain_start: usize, - /// Number of slots in an epoch. - pub slots_per_epoch: Option, - /// Affects the number of epochs a validator must be active before they can withdraw. - pub persistent_committee_period: Option, - /// Number of slots to build before ending execution. - pub num_slots: u64, - /// Number of slots that should be skipped due to inactive validator. - pub skip_slots: Option>, - /// Deposits to be included during execution. - pub deposits: Option>, - /// Proposer slashings to be included during execution. - pub proposer_slashings: Option>, - /// Attester slashings to be including during execution. - pub attester_slashings: Option>, - /// Exits to be including during execution. - pub exits: Option>, - /// Transfers to be including during execution. - pub transfers: Option>, -} - -impl Config { - /// Load from a YAML document. - /// - /// Expects to receive the `config` section of the document. - pub fn from_yaml(yaml: &Yaml) -> Self { - Self { - deposits_for_chain_start: as_usize(&yaml, "deposits_for_chain_start") - .expect("Must specify validator count"), - slots_per_epoch: as_u64(&yaml, "slots_per_epoch"), - persistent_committee_period: as_u64(&yaml, "persistent_committee_period"), - num_slots: as_u64(&yaml, "num_slots").expect("Must specify `config.num_slots`"), - skip_slots: as_vec_u64(yaml, "skip_slots"), - deposits: parse_deposits(&yaml), - proposer_slashings: parse_proposer_slashings(&yaml), - attester_slashings: parse_attester_slashings(&yaml), - exits: parse_exits(&yaml), - transfers: parse_transfers(&yaml), - } - } -} - -/// Parse the `transfers` section of the YAML document. -fn parse_transfers(yaml: &Yaml) -> Option> { - let mut tuples = vec![]; - - for exit in yaml["transfers"].as_vec()? { - let slot = as_u64(exit, "slot").expect("Incomplete transfer (slot)"); - let from = as_u64(exit, "from").expect("Incomplete transfer (from)"); - let to = as_u64(exit, "to").expect("Incomplete transfer (to)"); - let amount = as_u64(exit, "amount").expect("Incomplete transfer (amount)"); - - tuples.push((SlotHeight::from(slot), from, to, amount)); - } - - Some(tuples) -} - -/// Parse the `attester_slashings` section of the YAML document. -fn parse_exits(yaml: &Yaml) -> Option> { - let mut tuples = vec![]; - - for exit in yaml["exits"].as_vec()? { - let slot = as_u64(exit, "slot").expect("Incomplete exit (slot)"); - let validator_index = - as_u64(exit, "validator_index").expect("Incomplete exit (validator_index)"); - - tuples.push((SlotHeight::from(slot), validator_index)); - } - - Some(tuples) -} - -/// Parse the `attester_slashings` section of the YAML document. -fn parse_attester_slashings(yaml: &Yaml) -> Option> { - let mut slashings = vec![]; - - for slashing in yaml["attester_slashings"].as_vec()? { - let slot = as_u64(slashing, "slot").expect("Incomplete attester_slashing (slot)"); - let validator_indices = as_vec_u64(slashing, "validator_indices") - .expect("Incomplete attester_slashing (validator_indices)"); - - slashings.push((SlotHeight::from(slot), validator_indices)); - } - - Some(slashings) -} - -/// Parse the `proposer_slashings` section of the YAML document. -fn parse_proposer_slashings(yaml: &Yaml) -> Option> { - let mut slashings = vec![]; - - for slashing in yaml["proposer_slashings"].as_vec()? { - let slot = as_u64(slashing, "slot").expect("Incomplete proposer slashing (slot)_"); - let validator_index = as_u64(slashing, "validator_index") - .expect("Incomplete proposer slashing (validator_index)"); - - slashings.push((SlotHeight::from(slot), validator_index)); - } - - Some(slashings) -} - -/// Parse the `deposits` section of the YAML document. -fn parse_deposits(yaml: &Yaml) -> Option> { - let mut deposits = vec![]; - - for deposit in yaml["deposits"].as_vec()? { - let slot = as_u64(deposit, "slot").expect("Incomplete deposit (slot)"); - let amount = as_u64(deposit, "amount").expect("Incomplete deposit (amount)"); - - deposits.push((SlotHeight::from(slot), amount)) - } - - Some(deposits) -} diff --git a/beacon_node/beacon_chain/test_harness/src/test_case/results.rs b/beacon_node/beacon_chain/test_harness/src/test_case/results.rs deleted file mode 100644 index 596418c0f..000000000 --- a/beacon_node/beacon_chain/test_harness/src/test_case/results.rs +++ /dev/null @@ -1,34 +0,0 @@ -use super::state_check::StateCheck; -use super::yaml_helpers::as_usize; -use yaml_rust::Yaml; - -/// A series of tests to be carried out upon an `ExecutionResult`, returned from executing a -/// `TestCase`. -#[derive(Debug)] -pub struct Results { - pub num_skipped_slots: Option, - pub state_checks: Option>, -} - -impl Results { - /// Load from a YAML document. - /// - /// Expects the `results` section of the YAML document. - pub fn from_yaml(yaml: &Yaml) -> Self { - Self { - num_skipped_slots: as_usize(yaml, "num_skipped_slots"), - state_checks: parse_state_checks(yaml), - } - } -} - -/// Parse the `state_checks` section of the YAML document. -fn parse_state_checks(yaml: &Yaml) -> Option> { - let mut states = vec![]; - - for state_yaml in yaml["states"].as_vec()? { - states.push(StateCheck::from_yaml(state_yaml)); - } - - Some(states) -} diff --git a/beacon_node/beacon_chain/test_harness/src/test_case/state_check.rs b/beacon_node/beacon_chain/test_harness/src/test_case/state_check.rs deleted file mode 100644 index c6bdf8978..000000000 --- a/beacon_node/beacon_chain/test_harness/src/test_case/state_check.rs +++ /dev/null @@ -1,206 +0,0 @@ -use super::yaml_helpers::{as_u64, as_usize, as_vec_u64}; -use log::info; -use types::*; -use yaml_rust::Yaml; - -type ValidatorIndex = u64; -type BalanceGwei = u64; - -type BalanceCheckTuple = (ValidatorIndex, String, BalanceGwei); - -/// Tests to be conducted upon a `BeaconState` object generated during the execution of a -/// `TestCase`. -#[derive(Debug)] -pub struct StateCheck { - /// Checked against `beacon_state.slot`. - pub slot: Slot, - /// Checked against `beacon_state.validator_registry.len()`. - pub num_validators: Option, - /// The number of pending attestations from the previous epoch that should be in the state. - pub num_previous_epoch_attestations: Option, - /// The number of pending attestations from the current epoch that should be in the state. - pub num_current_epoch_attestations: Option, - /// A list of validator indices which have been penalized. Must be in ascending order. - pub slashed_validators: Option>, - /// A list of validator indices which have been fully exited. Must be in ascending order. - pub exited_validators: Option>, - /// A list of validator indices which have had an exit initiated. Must be in ascending order. - pub exit_initiated_validators: Option>, - /// A list of balances to check. - pub balances: Option>, -} - -impl StateCheck { - /// Load from a YAML document. - /// - /// Expects the `state_check` section of the YAML document. - pub fn from_yaml(yaml: &Yaml) -> Self { - Self { - slot: Slot::from(as_u64(&yaml, "slot").expect("State must specify slot")), - num_validators: as_usize(&yaml, "num_validators"), - num_previous_epoch_attestations: as_usize(&yaml, "num_previous_epoch_attestations"), - num_current_epoch_attestations: as_usize(&yaml, "num_current_epoch_attestations"), - slashed_validators: as_vec_u64(&yaml, "slashed_validators"), - exited_validators: as_vec_u64(&yaml, "exited_validators"), - exit_initiated_validators: as_vec_u64(&yaml, "exit_initiated_validators"), - balances: parse_balances(&yaml), - } - } - - /// Performs all checks against a `BeaconState` - /// - /// # Panics - /// - /// Panics with an error message if any test fails. - #[allow(clippy::cyclomatic_complexity)] - pub fn assert_valid(&self, state: &BeaconState, spec: &ChainSpec) { - let state_epoch = state.slot.epoch(spec.slots_per_epoch); - - info!("Running state check for slot height {}.", self.slot); - - // Check the state slot. - assert_eq!( - self.slot, - state.slot - spec.genesis_epoch.start_slot(spec.slots_per_epoch), - "State slot is invalid." - ); - - // Check the validator count - if let Some(num_validators) = self.num_validators { - assert_eq!( - state.validator_registry.len(), - num_validators, - "State validator count != expected." - ); - info!("OK: num_validators = {}.", num_validators); - } - - // Check the previous epoch attestations - if let Some(n) = self.num_previous_epoch_attestations { - assert_eq!( - state.previous_epoch_attestations.len(), - n, - "previous epoch attestations count != expected." - ); - info!("OK: num_previous_epoch_attestations = {}.", n); - } - - // Check the current epoch attestations - if let Some(n) = self.num_current_epoch_attestations { - assert_eq!( - state.current_epoch_attestations.len(), - n, - "current epoch attestations count != expected." - ); - info!("OK: num_current_epoch_attestations = {}.", n); - } - - // Check for slashed validators. - if let Some(ref slashed_validators) = self.slashed_validators { - let actually_slashed_validators: Vec = state - .validator_registry - .iter() - .enumerate() - .filter_map(|(i, validator)| { - if validator.slashed { - Some(i as u64) - } else { - None - } - }) - .collect(); - assert_eq!( - actually_slashed_validators, *slashed_validators, - "Slashed validators != expected." - ); - info!("OK: slashed_validators = {:?}.", slashed_validators); - } - - // Check for exited validators. - if let Some(ref exited_validators) = self.exited_validators { - let actually_exited_validators: Vec = state - .validator_registry - .iter() - .enumerate() - .filter_map(|(i, validator)| { - if validator.is_exited_at(state_epoch) { - Some(i as u64) - } else { - None - } - }) - .collect(); - assert_eq!( - actually_exited_validators, *exited_validators, - "Exited validators != expected." - ); - info!("OK: exited_validators = {:?}.", exited_validators); - } - - // Check for validators that have initiated exit. - if let Some(ref exit_initiated_validators) = self.exit_initiated_validators { - let actual: Vec = state - .validator_registry - .iter() - .enumerate() - .filter_map(|(i, validator)| { - if validator.initiated_exit { - Some(i as u64) - } else { - None - } - }) - .collect(); - assert_eq!( - actual, *exit_initiated_validators, - "Exit initiated validators != expected." - ); - info!( - "OK: exit_initiated_validators = {:?}.", - exit_initiated_validators - ); - } - - // Check validator balances. - if let Some(ref balances) = self.balances { - for (index, comparison, expected) in balances { - let actual = *state - .validator_balances - .get(*index as usize) - .expect("Balance check specifies unknown validator"); - - let result = match comparison.as_ref() { - "eq" => actual == *expected, - _ => panic!("Unknown balance comparison (use `eq`)"), - }; - assert!( - result, - format!( - "Validator balance for {}: {} !{} {}.", - index, actual, comparison, expected - ) - ); - info!("OK: validator balance for {:?}.", index); - } - } - } -} - -/// Parse the `transfers` section of the YAML document. -fn parse_balances(yaml: &Yaml) -> Option> { - let mut tuples = vec![]; - - for exit in yaml["balances"].as_vec()? { - let from = - as_u64(exit, "validator_index").expect("Incomplete balance check (validator_index)"); - let comparison = exit["comparison"] - .clone() - .into_string() - .expect("Incomplete balance check (amount)"); - let balance = as_u64(exit, "balance").expect("Incomplete balance check (balance)"); - - tuples.push((from, comparison, balance)); - } - - Some(tuples) -} diff --git a/beacon_node/beacon_chain/test_harness/src/test_case/yaml_helpers.rs b/beacon_node/beacon_chain/test_harness/src/test_case/yaml_helpers.rs deleted file mode 100644 index c499b3c0f..000000000 --- a/beacon_node/beacon_chain/test_harness/src/test_case/yaml_helpers.rs +++ /dev/null @@ -1,19 +0,0 @@ -use yaml_rust::Yaml; - -pub fn as_usize(yaml: &Yaml, key: &str) -> Option { - yaml[key].as_i64().and_then(|n| Some(n as usize)) -} - -pub fn as_u64(yaml: &Yaml, key: &str) -> Option { - yaml[key].as_i64().and_then(|n| Some(n as u64)) -} - -pub fn as_vec_u64(yaml: &Yaml, key: &str) -> Option> { - yaml[key].clone().into_vec().and_then(|vec| { - Some( - vec.iter() - .map(|item| item.as_i64().unwrap() as u64) - .collect(), - ) - }) -} diff --git a/beacon_node/beacon_chain/test_harness/src/validator_harness/direct_beacon_node.rs b/beacon_node/beacon_chain/test_harness/src/validator_harness/direct_beacon_node.rs deleted file mode 100644 index d47fd44b9..000000000 --- a/beacon_node/beacon_chain/test_harness/src/validator_harness/direct_beacon_node.rs +++ /dev/null @@ -1,100 +0,0 @@ -use attester::{ - BeaconNode as AttesterBeaconNode, BeaconNodeError as NodeError, - PublishOutcome as AttestationPublishOutcome, -}; -use beacon_chain::BeaconChain; -use block_proposer::{ - BeaconNode as BeaconBlockNode, BeaconNodeError as BeaconBlockNodeError, - PublishOutcome as BlockPublishOutcome, -}; -use db::ClientDB; -use fork_choice::ForkChoice; -use parking_lot::RwLock; -use slot_clock::SlotClock; -use std::sync::Arc; -use types::{AttestationData, BeaconBlock, FreeAttestation, Signature, Slot}; - -/// Connect directly to a borrowed `BeaconChain` instance so an attester/producer can request/submit -/// blocks/attestations. -/// -/// `BeaconBlock`s and `FreeAttestation`s are not actually published to the `BeaconChain`, instead -/// they are stored inside this struct. This is to allow one to benchmark the submission of the -/// block/attestation directly, or modify it before submission. -pub struct DirectBeaconNode { - beacon_chain: Arc>, - published_blocks: RwLock>, - published_attestations: RwLock>, -} - -impl DirectBeaconNode { - pub fn new(beacon_chain: Arc>) -> Self { - Self { - beacon_chain, - published_blocks: RwLock::new(vec![]), - published_attestations: RwLock::new(vec![]), - } - } - - /// Get the last published block (if any). - pub fn last_published_block(&self) -> Option { - Some(self.published_blocks.read().last()?.clone()) - } -} - -impl AttesterBeaconNode for DirectBeaconNode { - fn produce_attestation_data( - &self, - _slot: Slot, - shard: u64, - ) -> Result, NodeError> { - match self.beacon_chain.produce_attestation_data(shard) { - Ok(attestation_data) => Ok(Some(attestation_data)), - Err(e) => Err(NodeError::RemoteFailure(format!("{:?}", e))), - } - } - - fn publish_attestation( - &self, - free_attestation: FreeAttestation, - ) -> Result { - self.published_attestations.write().push(free_attestation); - Ok(AttestationPublishOutcome::ValidAttestation) - } -} - -impl BeaconBlockNode for DirectBeaconNode { - /// Requests a new `BeaconBlock from the `BeaconChain`. - fn produce_beacon_block( - &self, - slot: Slot, - randao_reveal: &Signature, - ) -> Result, BeaconBlockNodeError> { - let (block, _state) = self - .beacon_chain - .produce_block(randao_reveal.clone()) - .map_err(|e| { - BeaconBlockNodeError::RemoteFailure(format!("Did not produce block: {:?}", e)) - })?; - - if block.slot == slot { - Ok(Some(block)) - } else { - Err(BeaconBlockNodeError::RemoteFailure( - "Unable to produce at non-current slot.".to_string(), - )) - } - } - - /// A block is not _actually_ published to the `BeaconChain`, instead it is stored in the - /// `published_block_vec` and a successful `ValidBlock` is returned to the caller. - /// - /// The block may be retrieved and then applied to the `BeaconChain` manually, potentially in a - /// benchmarking scenario. - fn publish_beacon_block( - &self, - block: BeaconBlock, - ) -> Result { - self.published_blocks.write().push(block); - Ok(BlockPublishOutcome::ValidBlock) - } -} diff --git a/beacon_node/beacon_chain/test_harness/src/validator_harness/direct_duties.rs b/beacon_node/beacon_chain/test_harness/src/validator_harness/direct_duties.rs deleted file mode 100644 index dec93c334..000000000 --- a/beacon_node/beacon_chain/test_harness/src/validator_harness/direct_duties.rs +++ /dev/null @@ -1,74 +0,0 @@ -use attester::{ - DutiesReader as AttesterDutiesReader, DutiesReaderError as AttesterDutiesReaderError, -}; -use beacon_chain::BeaconChain; -use block_proposer::{ - DutiesReader as ProducerDutiesReader, DutiesReaderError as ProducerDutiesReaderError, -}; -use db::ClientDB; -use fork_choice::ForkChoice; -use slot_clock::SlotClock; -use std::sync::Arc; -use types::{Fork, PublicKey, Slot}; - -/// Connects directly to a borrowed `BeaconChain` and reads attester/proposer duties directly from -/// it. -pub struct DirectDuties { - beacon_chain: Arc>, - pubkey: PublicKey, -} - -impl DirectDuties { - pub fn new(pubkey: PublicKey, beacon_chain: Arc>) -> Self { - Self { - beacon_chain, - pubkey, - } - } -} - -impl ProducerDutiesReader for DirectDuties { - fn is_block_production_slot(&self, slot: Slot) -> Result { - let validator_index = self - .beacon_chain - .validator_index(&self.pubkey) - .ok_or_else(|| ProducerDutiesReaderError::UnknownValidator)?; - - match self.beacon_chain.block_proposer(slot) { - Ok(proposer) if proposer == validator_index => Ok(true), - Ok(_) => Ok(false), - Err(_) => Err(ProducerDutiesReaderError::UnknownEpoch), - } - } - - fn fork(&self) -> Result { - Ok(self.beacon_chain.state.read().fork.clone()) - } -} - -impl AttesterDutiesReader for DirectDuties { - fn validator_index(&self) -> Option { - match self.beacon_chain.validator_index(&self.pubkey) { - Some(index) => Some(index as u64), - None => None, - } - } - - fn attestation_shard(&self, slot: Slot) -> Result, AttesterDutiesReaderError> { - if let Some(validator_index) = self.validator_index() { - match self - .beacon_chain - .validator_attestion_slot_and_shard(validator_index as usize) - { - Ok(Some((attest_slot, attest_shard))) if attest_slot == slot => { - Ok(Some(attest_shard)) - } - Ok(Some(_)) => Ok(None), - Ok(None) => Err(AttesterDutiesReaderError::UnknownEpoch), - Err(_) => unreachable!("Error when getting validator attestation shard."), - } - } else { - Err(AttesterDutiesReaderError::UnknownValidator) - } - } -} diff --git a/beacon_node/beacon_chain/test_harness/src/validator_harness/local_signer.rs b/beacon_node/beacon_chain/test_harness/src/validator_harness/local_signer.rs deleted file mode 100644 index 803af5045..000000000 --- a/beacon_node/beacon_chain/test_harness/src/validator_harness/local_signer.rs +++ /dev/null @@ -1,36 +0,0 @@ -use attester::Signer as AttesterSigner; -use block_proposer::Signer as BlockProposerSigner; -use types::{Keypair, Signature}; - -/// A test-only struct used to perform signing for a proposer or attester. -pub struct LocalSigner { - keypair: Keypair, -} - -impl LocalSigner { - /// Produce a new TestSigner with signing enabled by default. - pub fn new(keypair: Keypair) -> Self { - Self { keypair } - } - - /// Sign some message. - fn bls_sign(&self, message: &[u8], domain: u64) -> Option { - Some(Signature::new(message, domain, &self.keypair.sk)) - } -} - -impl BlockProposerSigner for LocalSigner { - fn sign_block_proposal(&self, message: &[u8], domain: u64) -> Option { - self.bls_sign(message, domain) - } - - fn sign_randao_reveal(&self, message: &[u8], domain: u64) -> Option { - self.bls_sign(message, domain) - } -} - -impl AttesterSigner for LocalSigner { - fn sign_attestation_message(&self, message: &[u8], domain: u64) -> Option { - self.bls_sign(message, domain) - } -} diff --git a/beacon_node/beacon_chain/test_harness/src/validator_harness/mod.rs b/beacon_node/beacon_chain/test_harness/src/validator_harness/mod.rs deleted file mode 100644 index 815d4b23b..000000000 --- a/beacon_node/beacon_chain/test_harness/src/validator_harness/mod.rs +++ /dev/null @@ -1,119 +0,0 @@ -mod direct_beacon_node; -mod direct_duties; -mod local_signer; - -use attester::Attester; -use beacon_chain::BeaconChain; -use block_proposer::PollOutcome as BlockPollOutcome; -use block_proposer::{BlockProducer, Error as BlockPollError}; -use db::MemoryDB; -use direct_beacon_node::DirectBeaconNode; -use direct_duties::DirectDuties; -use fork_choice::BitwiseLMDGhost; -use local_signer::LocalSigner; -use slot_clock::TestingSlotClock; -use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Keypair, Slot}; - -#[derive(Debug, PartialEq)] -pub enum BlockProduceError { - DidNotProduce(BlockPollOutcome), - PollError(BlockPollError), -} - -type TestingBlockProducer = BlockProducer< - TestingSlotClock, - DirectBeaconNode>, - DirectDuties>, - LocalSigner, ->; - -type TestingAttester = Attester< - TestingSlotClock, - DirectBeaconNode>, - DirectDuties>, - LocalSigner, ->; - -/// A `BlockProducer` and `Attester` which sign using a common keypair. -/// -/// The test validator connects directly to a borrowed `BeaconChain` struct. It is useful for -/// testing that the core proposer and attester logic is functioning. Also for supporting beacon -/// chain tests. -pub struct ValidatorHarness { - pub block_producer: TestingBlockProducer, - pub attester: TestingAttester, - pub spec: Arc, - pub epoch_map: Arc>>, - pub keypair: Keypair, - pub beacon_node: Arc>>, - pub slot_clock: Arc, - pub signer: Arc, -} - -impl ValidatorHarness { - /// Create a new ValidatorHarness that signs with the given keypair, operates per the given spec and connects to the - /// supplied beacon node. - /// - /// A `BlockProducer` and `Attester` is created.. - pub fn new( - keypair: Keypair, - beacon_chain: Arc>>, - spec: Arc, - ) -> Self { - let slot_clock = Arc::new(TestingSlotClock::new(spec.genesis_slot.as_u64())); - let signer = Arc::new(LocalSigner::new(keypair.clone())); - let beacon_node = Arc::new(DirectBeaconNode::new(beacon_chain.clone())); - let epoch_map = Arc::new(DirectDuties::new(keypair.pk.clone(), beacon_chain.clone())); - - let block_producer = BlockProducer::new( - spec.clone(), - epoch_map.clone(), - slot_clock.clone(), - beacon_node.clone(), - signer.clone(), - ); - - let attester = Attester::new( - epoch_map.clone(), - slot_clock.clone(), - beacon_node.clone(), - signer.clone(), - ); - - Self { - block_producer, - attester, - spec, - epoch_map, - keypair, - beacon_node, - slot_clock, - signer, - } - } - - /// Run the `poll` function on the `BlockProducer` and produce a block. - /// - /// An error is returned if the producer refuses to produce. - pub fn produce_block(&mut self) -> Result { - // Using `DirectBeaconNode`, the validator will always return sucessufully if it tries to - // publish a block. - match self.block_producer.poll() { - Ok(BlockPollOutcome::BlockProduced(_)) => {} - Ok(outcome) => return Err(BlockProduceError::DidNotProduce(outcome)), - Err(error) => return Err(BlockProduceError::PollError(error)), - }; - Ok(self - .beacon_node - .last_published_block() - .expect("Unable to obtain produced block.")) - } - - /// Set the validators slot clock to the specified slot. - /// - /// The validators slot clock will always read this value until it is set to something else. - pub fn set_slot(&mut self, slot: Slot) { - self.slot_clock.set_slot(slot.as_u64()) - } -} diff --git a/beacon_node/beacon_chain/test_harness/tests/chain.rs b/beacon_node/beacon_chain/test_harness/tests/chain.rs deleted file mode 100644 index d47de6889..000000000 --- a/beacon_node/beacon_chain/test_harness/tests/chain.rs +++ /dev/null @@ -1,46 +0,0 @@ -#![cfg(not(debug_assertions))] - -use env_logger::{Builder, Env}; -use log::debug; -use test_harness::BeaconChainHarness; -use types::ChainSpec; - -#[test] -fn it_can_build_on_genesis_block() { - Builder::from_env(Env::default().default_filter_or("info")).init(); - - let spec = ChainSpec::few_validators(); - let validator_count = 8; - - let mut harness = BeaconChainHarness::new(spec, validator_count as usize); - - harness.advance_chain_with_block(); -} - -#[test] -#[ignore] -fn it_can_produce_past_first_epoch_boundary() { - Builder::from_env(Env::default().default_filter_or("info")).init(); - - let spec = ChainSpec::few_validators(); - let validator_count = 8; - - debug!("Starting harness build..."); - - let mut harness = BeaconChainHarness::new(spec, validator_count); - - debug!("Harness built, tests starting.."); - - let blocks = harness.spec.slots_per_epoch * 2 + 1; - - for i in 0..blocks { - harness.advance_chain_with_block(); - debug!("Produced block {}/{}.", i + 1, blocks); - } - - harness.run_fork_choice(); - - let dump = harness.chain_dump().expect("Chain dump failed."); - - assert_eq!(dump.len() as u64, blocks + 1); // + 1 for genesis block. -} diff --git a/beacon_node/network/Cargo.toml b/beacon_node/network/Cargo.toml index 36bf1f141..9cac12659 100644 --- a/beacon_node/network/Cargo.toml +++ b/beacon_node/network/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Age Manning "] edition = "2018" [dev-dependencies] -test_harness = { path = "../beacon_chain/test_harness" } sloggers = "0.3.2" [dependencies] diff --git a/beacon_node/network/tests/tests.rs b/beacon_node/network/tests/tests.rs deleted file mode 100644 index 47d5482d3..000000000 --- a/beacon_node/network/tests/tests.rs +++ /dev/null @@ -1,570 +0,0 @@ -use crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}; -use eth2_libp2p::rpc::methods::*; -use eth2_libp2p::rpc::{RPCMethod, RPCRequest, RPCResponse, RequestId}; -use eth2_libp2p::{PeerId, RPCEvent}; -use network::beacon_chain::BeaconChain as NetworkBeaconChain; -use network::message_handler::{HandlerMessage, MessageHandler}; -use network::service::{NetworkMessage, OutgoingMessage}; -use sloggers::terminal::{Destination, TerminalLoggerBuilder}; -use sloggers::types::Severity; -use sloggers::Build; -use std::time::Duration; -use test_harness::BeaconChainHarness; -use tokio::runtime::TaskExecutor; -use types::{test_utils::TestingBeaconStateBuilder, *}; - -pub struct SyncNode { - pub id: usize, - sender: Sender, - receiver: Receiver, - peer_id: PeerId, - harness: BeaconChainHarness, -} - -impl SyncNode { - fn from_beacon_state_builder( - id: usize, - executor: &TaskExecutor, - state_builder: TestingBeaconStateBuilder, - spec: &ChainSpec, - logger: slog::Logger, - ) -> Self { - let harness = BeaconChainHarness::from_beacon_state_builder(state_builder, spec.clone()); - - let (network_sender, network_receiver) = unbounded(); - let message_handler_sender = MessageHandler::spawn( - harness.beacon_chain.clone(), - network_sender, - executor, - logger, - ) - .unwrap(); - - Self { - id, - sender: message_handler_sender, - receiver: network_receiver, - peer_id: PeerId::random(), - harness, - } - } - - fn increment_beacon_chain_slot(&mut self) { - self.harness.increment_beacon_chain_slot(); - } - - fn send(&self, message: HandlerMessage) { - self.sender.send(message).unwrap(); - } - - fn recv(&self) -> Result { - self.receiver.recv_timeout(Duration::from_millis(500)) - } - - fn hello_message(&self) -> HelloMessage { - self.harness.beacon_chain.hello_message() - } - - pub fn connect_to(&mut self, node: &SyncNode) { - let message = HandlerMessage::PeerDialed(self.peer_id.clone()); - node.send(message); - } - - /// Reads the receive queue from one node and passes the message to the other. Also returns a - /// copy of the message. - /// - /// self -----> node - /// | - /// us - /// - /// Named after the unix `tee` command. - fn tee(&mut self, node: &SyncNode) -> NetworkMessage { - let network_message = self.recv().expect("Timeout on tee"); - - let handler_message = match network_message.clone() { - NetworkMessage::Send(_to_peer_id, OutgoingMessage::RPC(event)) => { - HandlerMessage::RPC(self.peer_id.clone(), event) - } - _ => panic!("tee cannot parse {:?}", network_message), - }; - - node.send(handler_message); - - network_message - } - - fn tee_hello_request(&mut self, node: &SyncNode) -> HelloMessage { - let request = self.tee_rpc_request(node); - - match request { - RPCRequest::Hello(message) => message, - _ => panic!("tee_hello_request got: {:?}", request), - } - } - - fn tee_hello_response(&mut self, node: &SyncNode) -> HelloMessage { - let response = self.tee_rpc_response(node); - - match response { - RPCResponse::Hello(message) => message, - _ => panic!("tee_hello_response got: {:?}", response), - } - } - - fn tee_block_root_request(&mut self, node: &SyncNode) -> BeaconBlockRootsRequest { - let msg = self.tee_rpc_request(node); - - match msg { - RPCRequest::BeaconBlockRoots(data) => data, - _ => panic!("tee_block_root_request got: {:?}", msg), - } - } - - fn tee_block_root_response(&mut self, node: &SyncNode) -> BeaconBlockRootsResponse { - let msg = self.tee_rpc_response(node); - - match msg { - RPCResponse::BeaconBlockRoots(data) => data, - _ => panic!("tee_block_root_response got: {:?}", msg), - } - } - - fn tee_block_header_request(&mut self, node: &SyncNode) -> BeaconBlockHeadersRequest { - let msg = self.tee_rpc_request(node); - - match msg { - RPCRequest::BeaconBlockHeaders(data) => data, - _ => panic!("tee_block_header_request got: {:?}", msg), - } - } - - fn tee_block_header_response(&mut self, node: &SyncNode) -> BeaconBlockHeadersResponse { - let msg = self.tee_rpc_response(node); - - match msg { - RPCResponse::BeaconBlockHeaders(data) => data, - _ => panic!("tee_block_header_response got: {:?}", msg), - } - } - - fn tee_block_body_request(&mut self, node: &SyncNode) -> BeaconBlockBodiesRequest { - let msg = self.tee_rpc_request(node); - - match msg { - RPCRequest::BeaconBlockBodies(data) => data, - _ => panic!("tee_block_body_request got: {:?}", msg), - } - } - - fn tee_block_body_response(&mut self, node: &SyncNode) -> BeaconBlockBodiesResponse { - let msg = self.tee_rpc_response(node); - - match msg { - RPCResponse::BeaconBlockBodies(data) => data, - _ => panic!("tee_block_body_response got: {:?}", msg), - } - } - - fn tee_rpc_request(&mut self, node: &SyncNode) -> RPCRequest { - let network_message = self.tee(node); - - match network_message { - NetworkMessage::Send( - _peer_id, - OutgoingMessage::RPC(RPCEvent::Request { - id: _, - method_id: _, - body, - }), - ) => body, - _ => panic!("tee_rpc_request failed! got {:?}", network_message), - } - } - - fn tee_rpc_response(&mut self, node: &SyncNode) -> RPCResponse { - let network_message = self.tee(node); - - match network_message { - NetworkMessage::Send( - _peer_id, - OutgoingMessage::RPC(RPCEvent::Response { - id: _, - method_id: _, - result, - }), - ) => result, - _ => panic!("tee_rpc_response failed! got {:?}", network_message), - } - } - - pub fn get_block_root_request(&self) -> BeaconBlockRootsRequest { - let request = self.recv_rpc_request().expect("No block root request"); - - match request { - RPCRequest::BeaconBlockRoots(request) => request, - _ => panic!("Did not get block root request"), - } - } - - pub fn get_block_headers_request(&self) -> BeaconBlockHeadersRequest { - let request = self.recv_rpc_request().expect("No block headers request"); - - match request { - RPCRequest::BeaconBlockHeaders(request) => request, - _ => panic!("Did not get block headers request"), - } - } - - pub fn get_block_bodies_request(&self) -> BeaconBlockBodiesRequest { - let request = self.recv_rpc_request().expect("No block bodies request"); - - match request { - RPCRequest::BeaconBlockBodies(request) => request, - _ => panic!("Did not get block bodies request"), - } - } - - fn _recv_rpc_response(&self) -> Result { - let network_message = self.recv()?; - Ok(match network_message { - NetworkMessage::Send( - _peer_id, - OutgoingMessage::RPC(RPCEvent::Response { - id: _, - method_id: _, - result, - }), - ) => result, - _ => panic!("get_rpc_response failed! got {:?}", network_message), - }) - } - - fn recv_rpc_request(&self) -> Result { - let network_message = self.recv()?; - Ok(match network_message { - NetworkMessage::Send( - _peer_id, - OutgoingMessage::RPC(RPCEvent::Request { - id: _, - method_id: _, - body, - }), - ) => body, - _ => panic!("get_rpc_request failed! got {:?}", network_message), - }) - } -} - -fn get_logger() -> slog::Logger { - let mut builder = TerminalLoggerBuilder::new(); - builder.level(Severity::Debug); - builder.destination(Destination::Stderr); - builder.build().unwrap() -} - -pub struct SyncMaster { - harness: BeaconChainHarness, - peer_id: PeerId, - response_ids: Vec, -} - -impl SyncMaster { - fn from_beacon_state_builder( - state_builder: TestingBeaconStateBuilder, - node_count: usize, - spec: &ChainSpec, - ) -> Self { - let harness = BeaconChainHarness::from_beacon_state_builder(state_builder, spec.clone()); - let peer_id = PeerId::random(); - let response_ids = vec![RequestId::from(0); node_count]; - - Self { - harness, - peer_id, - response_ids, - } - } - - pub fn response_id(&mut self, node: &SyncNode) -> RequestId { - let id = self.response_ids[node.id].clone(); - self.response_ids[node.id].increment(); - id - } - - pub fn do_hello_with(&mut self, node: &SyncNode) { - let message = HandlerMessage::PeerDialed(self.peer_id.clone()); - node.send(message); - - let request = node.recv_rpc_request().expect("No hello response"); - - match request { - RPCRequest::Hello(_hello) => { - let hello = self.harness.beacon_chain.hello_message(); - let response = self.rpc_response(node, RPCResponse::Hello(hello)); - node.send(response); - } - _ => panic!("Got message other than hello from node."), - } - } - - pub fn respond_to_block_roots_request( - &mut self, - node: &SyncNode, - request: BeaconBlockRootsRequest, - ) { - let roots = self - .harness - .beacon_chain - .get_block_roots(request.start_slot, request.count as usize, 0) - .expect("Beacon chain did not give block roots") - .iter() - .enumerate() - .map(|(i, root)| BlockRootSlot { - block_root: *root, - slot: Slot::from(i) + request.start_slot, - }) - .collect(); - - let response = RPCResponse::BeaconBlockRoots(BeaconBlockRootsResponse { roots }); - self.send_rpc_response(node, response) - } - - pub fn respond_to_block_headers_request( - &mut self, - node: &SyncNode, - request: BeaconBlockHeadersRequest, - ) { - let roots = self - .harness - .beacon_chain - .get_block_roots( - request.start_slot, - request.max_headers as usize, - request.skip_slots as usize, - ) - .expect("Beacon chain did not give blocks"); - - if roots.is_empty() { - panic!("Roots was empty when trying to get headers.") - } - - assert_eq!( - roots[0], request.start_root, - "Got the wrong start root when getting headers" - ); - - let headers: Vec = roots - .iter() - .map(|root| { - let block = self - .harness - .beacon_chain - .get_block(root) - .expect("Failed to load block") - .expect("Block did not exist"); - block.block_header() - }) - .collect(); - - let response = RPCResponse::BeaconBlockHeaders(BeaconBlockHeadersResponse { headers }); - self.send_rpc_response(node, response) - } - - pub fn respond_to_block_bodies_request( - &mut self, - node: &SyncNode, - request: BeaconBlockBodiesRequest, - ) { - let block_bodies: Vec = request - .block_roots - .iter() - .map(|root| { - let block = self - .harness - .beacon_chain - .get_block(root) - .expect("Failed to load block") - .expect("Block did not exist"); - block.body - }) - .collect(); - - let response = RPCResponse::BeaconBlockBodies(BeaconBlockBodiesResponse { block_bodies }); - self.send_rpc_response(node, response) - } - - fn send_rpc_response(&mut self, node: &SyncNode, rpc_response: RPCResponse) { - node.send(self.rpc_response(node, rpc_response)); - } - - fn rpc_response(&mut self, node: &SyncNode, rpc_response: RPCResponse) -> HandlerMessage { - HandlerMessage::RPC( - self.peer_id.clone(), - RPCEvent::Response { - id: self.response_id(node), - method_id: RPCMethod::Hello.into(), - result: rpc_response, - }, - ) - } -} - -fn test_setup( - state_builder: TestingBeaconStateBuilder, - node_count: usize, - spec: &ChainSpec, - logger: slog::Logger, -) -> (tokio::runtime::Runtime, SyncMaster, Vec) { - let runtime = tokio::runtime::Runtime::new().unwrap(); - - let mut nodes = Vec::with_capacity(node_count); - for id in 0..node_count { - let node = SyncNode::from_beacon_state_builder( - id, - &runtime.executor(), - state_builder.clone(), - &spec, - logger.clone(), - ); - - nodes.push(node); - } - - let master = SyncMaster::from_beacon_state_builder(state_builder, node_count, &spec); - - (runtime, master, nodes) -} - -pub fn build_blocks(blocks: usize, master: &mut SyncMaster, nodes: &mut Vec) { - for _ in 0..blocks { - master.harness.advance_chain_with_block(); - for i in 0..nodes.len() { - nodes[i].increment_beacon_chain_slot(); - } - } - master.harness.run_fork_choice(); - - for i in 0..nodes.len() { - nodes[i].harness.run_fork_choice(); - } -} - -#[test] -#[ignore] -fn sync_node_with_master() { - let logger = get_logger(); - let spec = ChainSpec::few_validators(); - let validator_count = 8; - let node_count = 1; - - let state_builder = - TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, &spec); - - let (runtime, mut master, mut nodes) = - test_setup(state_builder, node_count, &spec, logger.clone()); - - let original_node_slot = nodes[0].hello_message().best_slot; - - build_blocks(2, &mut master, &mut nodes); - - master.do_hello_with(&nodes[0]); - - let roots_request = nodes[0].get_block_root_request(); - assert_eq!(roots_request.start_slot, original_node_slot + 1); - assert_eq!(roots_request.count, 2); - - master.respond_to_block_roots_request(&nodes[0], roots_request); - - let headers_request = nodes[0].get_block_headers_request(); - assert_eq!(headers_request.start_slot, original_node_slot + 1); - assert_eq!(headers_request.max_headers, 2); - assert_eq!(headers_request.skip_slots, 0); - - master.respond_to_block_headers_request(&nodes[0], headers_request); - - let bodies_request = nodes[0].get_block_bodies_request(); - assert_eq!(bodies_request.block_roots.len(), 2); - - master.respond_to_block_bodies_request(&nodes[0], bodies_request); - - std::thread::sleep(Duration::from_millis(10000)); - runtime.shutdown_now(); -} - -#[test] -#[ignore] -fn sync_two_nodes() { - let logger = get_logger(); - let spec = ChainSpec::few_validators(); - let validator_count = 8; - let node_count = 2; - - let state_builder = - TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, &spec); - - let (runtime, _master, mut nodes) = - test_setup(state_builder, node_count, &spec, logger.clone()); - - // let original_node_slot = nodes[0].hello_message().best_slot; - let mut node_a = nodes.remove(0); - let mut node_b = nodes.remove(0); - - let blocks = 2; - - // Node A builds out a longer, better chain. - for _ in 0..blocks { - // Node A should build a block. - node_a.harness.advance_chain_with_block(); - // Node B should just increment it's slot without a block. - node_b.harness.increment_beacon_chain_slot(); - } - node_a.harness.run_fork_choice(); - - // A connects to B. - node_a.connect_to(&node_b); - - // B says hello to A. - node_b.tee_hello_request(&node_a); - // A says hello back. - node_a.tee_hello_response(&node_b); - - // B requests block roots from A. - node_b.tee_block_root_request(&node_a); - // A provides block roots to A. - node_a.tee_block_root_response(&node_b); - - // B requests block headers from A. - node_b.tee_block_header_request(&node_a); - // A provides block headers to B. - node_a.tee_block_header_response(&node_b); - - // B requests block bodies from A. - node_b.tee_block_body_request(&node_a); - // A provides block bodies to B. - node_a.tee_block_body_response(&node_b); - - std::thread::sleep(Duration::from_secs(20)); - - node_b.harness.run_fork_choice(); - - let node_a_chain = node_a - .harness - .beacon_chain - .chain_dump() - .expect("Can't dump node a chain"); - - let node_b_chain = node_b - .harness - .beacon_chain - .chain_dump() - .expect("Can't dump node b chain"); - - assert_eq!( - node_a_chain.len(), - node_b_chain.len(), - "Chains should be equal length" - ); - assert_eq!(node_a_chain, node_b_chain, "Chains should be identical"); - - runtime.shutdown_now(); -} diff --git a/eth2/attester/Cargo.toml b/eth2/attester/Cargo.toml deleted file mode 100644 index 41824274d..000000000 --- a/eth2/attester/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "attester" -version = "0.1.0" -authors = ["Paul Hauner "] -edition = "2018" - -[dependencies] -slot_clock = { path = "../../eth2/utils/slot_clock" } -ssz = { path = "../../eth2/utils/ssz" } -tree_hash = { path = "../../eth2/utils/tree_hash" } -types = { path = "../../eth2/types" } diff --git a/eth2/attester/src/lib.rs b/eth2/attester/src/lib.rs deleted file mode 100644 index 1bbbd6b43..000000000 --- a/eth2/attester/src/lib.rs +++ /dev/null @@ -1,257 +0,0 @@ -pub mod test_utils; -mod traits; - -use slot_clock::SlotClock; -use std::sync::Arc; -use tree_hash::TreeHash; -use types::{AttestationData, AttestationDataAndCustodyBit, FreeAttestation, Signature, Slot}; - -pub use self::traits::{ - BeaconNode, BeaconNodeError, DutiesReader, DutiesReaderError, PublishOutcome, Signer, -}; - -const PHASE_0_CUSTODY_BIT: bool = false; -const DOMAIN_ATTESTATION: u64 = 1; - -#[derive(Debug, PartialEq)] -pub enum PollOutcome { - AttestationProduced(Slot), - AttestationNotRequired(Slot), - SlashableAttestationNotProduced(Slot), - BeaconNodeUnableToProduceAttestation(Slot), - ProducerDutiesUnknown(Slot), - SlotAlreadyProcessed(Slot), - SignerRejection(Slot), - ValidatorIsUnknown(Slot), -} - -#[derive(Debug, PartialEq)] -pub enum Error { - SlotClockError, - SlotUnknowable, - EpochMapPoisoned, - SlotClockPoisoned, - EpochLengthIsZero, - BeaconNodeError(BeaconNodeError), -} - -/// A polling state machine which performs block production duties, based upon some epoch duties -/// (`EpochDutiesMap`) and a concept of time (`SlotClock`). -/// -/// Ensures that messages are not slashable. -/// -/// Relies upon an external service to keep the `EpochDutiesMap` updated. -pub struct Attester { - pub last_processed_slot: Option, - duties: Arc, - slot_clock: Arc, - beacon_node: Arc, - signer: Arc, -} - -impl Attester { - /// Returns a new instance where `last_processed_slot == 0`. - pub fn new(duties: Arc, slot_clock: Arc, beacon_node: Arc, signer: Arc) -> Self { - Self { - last_processed_slot: None, - duties, - slot_clock, - beacon_node, - signer, - } - } -} - -impl Attester { - /// Poll the `BeaconNode` and produce an attestation if required. - pub fn poll(&mut self) -> Result { - let slot = self - .slot_clock - .present_slot() - .map_err(|_| Error::SlotClockError)? - .ok_or(Error::SlotUnknowable)?; - - if !self.is_processed_slot(slot) { - self.last_processed_slot = Some(slot); - - let shard = match self.duties.attestation_shard(slot) { - Ok(Some(result)) => result, - Ok(None) => return Ok(PollOutcome::AttestationNotRequired(slot)), - Err(DutiesReaderError::UnknownEpoch) => { - return Ok(PollOutcome::ProducerDutiesUnknown(slot)); - } - Err(DutiesReaderError::UnknownValidator) => { - return Ok(PollOutcome::ValidatorIsUnknown(slot)); - } - Err(DutiesReaderError::EpochLengthIsZero) => return Err(Error::EpochLengthIsZero), - Err(DutiesReaderError::Poisoned) => return Err(Error::EpochMapPoisoned), - }; - - self.produce_attestation(slot, shard) - } else { - Ok(PollOutcome::SlotAlreadyProcessed(slot)) - } - } - - fn produce_attestation(&mut self, slot: Slot, shard: u64) -> Result { - let attestation_data = match self.beacon_node.produce_attestation_data(slot, shard)? { - Some(attestation_data) => attestation_data, - None => return Ok(PollOutcome::BeaconNodeUnableToProduceAttestation(slot)), - }; - - if !self.safe_to_produce(&attestation_data) { - return Ok(PollOutcome::SlashableAttestationNotProduced(slot)); - } - - let signature = match self.sign_attestation_data(&attestation_data) { - Some(signature) => signature, - None => return Ok(PollOutcome::SignerRejection(slot)), - }; - - let validator_index = match self.duties.validator_index() { - Some(validator_index) => validator_index, - None => return Ok(PollOutcome::ValidatorIsUnknown(slot)), - }; - - let free_attestation = FreeAttestation { - data: attestation_data, - signature, - validator_index, - }; - - self.beacon_node.publish_attestation(free_attestation)?; - Ok(PollOutcome::AttestationProduced(slot)) - } - - fn is_processed_slot(&self, slot: Slot) -> bool { - match self.last_processed_slot { - Some(processed_slot) if slot <= processed_slot => true, - _ => false, - } - } - - /// Consumes a block, returning that block signed by the validators private key. - /// - /// Important: this function will not check to ensure the block is not slashable. This must be - /// done upstream. - fn sign_attestation_data(&mut self, attestation_data: &AttestationData) -> Option { - self.store_produce(attestation_data); - - let message = AttestationDataAndCustodyBit { - data: attestation_data.clone(), - custody_bit: PHASE_0_CUSTODY_BIT, - } - .tree_hash_root(); - - self.signer - .sign_attestation_message(&message[..], DOMAIN_ATTESTATION) - } - - /// Returns `true` if signing some attestation_data is safe (non-slashable). - /// - /// !!! UNSAFE !!! - /// - /// Important: this function is presently stubbed-out. It provides ZERO SAFETY. - fn safe_to_produce(&self, _attestation_data: &AttestationData) -> bool { - // TODO: ensure the producer doesn't produce slashable blocks. - // https://github.com/sigp/lighthouse/issues/160 - true - } - - /// Record that a block was produced so that slashable votes may not be made in the future. - /// - /// !!! UNSAFE !!! - /// - /// Important: this function is presently stubbed-out. It provides ZERO SAFETY. - fn store_produce(&mut self, _block: &AttestationData) { - // TODO: record this block production to prevent future slashings. - // https://github.com/sigp/lighthouse/issues/160 - } -} - -impl From for Error { - fn from(e: BeaconNodeError) -> Error { - Error::BeaconNodeError(e) - } -} - -#[cfg(test)] -mod tests { - use super::test_utils::{EpochMap, LocalSigner, SimulatedBeaconNode}; - use super::*; - use slot_clock::TestingSlotClock; - use types::{ - test_utils::{SeedableRng, TestRandom, XorShiftRng}, - ChainSpec, Keypair, - }; - - // TODO: implement more thorough testing. - // https://github.com/sigp/lighthouse/issues/160 - // - // These tests should serve as a good example for future tests. - - #[test] - pub fn polling() { - let mut rng = XorShiftRng::from_seed([42; 16]); - - let spec = Arc::new(ChainSpec::foundation()); - let slot_clock = Arc::new(TestingSlotClock::new(0)); - let beacon_node = Arc::new(SimulatedBeaconNode::default()); - let signer = Arc::new(LocalSigner::new(Keypair::random())); - - let mut duties = EpochMap::new(spec.slots_per_epoch); - let attest_slot = Slot::new(100); - let attest_epoch = attest_slot / spec.slots_per_epoch; - let attest_shard = 12; - duties.insert_attestation_shard(attest_slot, attest_shard); - duties.set_validator_index(Some(2)); - let duties = Arc::new(duties); - - let mut attester = Attester::new( - duties.clone(), - slot_clock.clone(), - beacon_node.clone(), - signer.clone(), - ); - - // Configure responses from the BeaconNode. - beacon_node.set_next_produce_result(Ok(Some(AttestationData::random_for_test(&mut rng)))); - beacon_node.set_next_publish_result(Ok(PublishOutcome::ValidAttestation)); - - // One slot before attestation slot... - slot_clock.set_slot(attest_slot.as_u64() - 1); - assert_eq!( - attester.poll(), - Ok(PollOutcome::AttestationNotRequired(attest_slot - 1)) - ); - - // On the attest slot... - slot_clock.set_slot(attest_slot.as_u64()); - assert_eq!( - attester.poll(), - Ok(PollOutcome::AttestationProduced(attest_slot)) - ); - - // Trying the same attest slot again... - slot_clock.set_slot(attest_slot.as_u64()); - assert_eq!( - attester.poll(), - Ok(PollOutcome::SlotAlreadyProcessed(attest_slot)) - ); - - // One slot after the attest slot... - slot_clock.set_slot(attest_slot.as_u64() + 1); - assert_eq!( - attester.poll(), - Ok(PollOutcome::AttestationNotRequired(attest_slot + 1)) - ); - - // In an epoch without known duties... - let slot = (attest_epoch + 1) * spec.slots_per_epoch; - slot_clock.set_slot(slot.into()); - assert_eq!( - attester.poll(), - Ok(PollOutcome::ProducerDutiesUnknown(slot)) - ); - } -} diff --git a/eth2/attester/src/test_utils/epoch_map.rs b/eth2/attester/src/test_utils/epoch_map.rs deleted file mode 100644 index 0b5827d64..000000000 --- a/eth2/attester/src/test_utils/epoch_map.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::{DutiesReader, DutiesReaderError}; -use std::collections::HashMap; -use types::{Epoch, Slot}; - -pub struct EpochMap { - slots_per_epoch: u64, - validator_index: Option, - map: HashMap, -} - -impl EpochMap { - pub fn new(slots_per_epoch: u64) -> Self { - Self { - slots_per_epoch, - validator_index: None, - map: HashMap::new(), - } - } - - pub fn insert_attestation_shard(&mut self, slot: Slot, shard: u64) { - let epoch = slot.epoch(self.slots_per_epoch); - self.map.insert(epoch, (slot, shard)); - } - - pub fn set_validator_index(&mut self, index: Option) { - self.validator_index = index; - } -} - -impl DutiesReader for EpochMap { - fn attestation_shard(&self, slot: Slot) -> Result, DutiesReaderError> { - let epoch = slot.epoch(self.slots_per_epoch); - - match self.map.get(&epoch) { - Some((attest_slot, attest_shard)) if *attest_slot == slot => Ok(Some(*attest_shard)), - Some((attest_slot, _attest_shard)) if *attest_slot != slot => Ok(None), - _ => Err(DutiesReaderError::UnknownEpoch), - } - } - - fn validator_index(&self) -> Option { - self.validator_index - } -} diff --git a/eth2/attester/src/test_utils/local_signer.rs b/eth2/attester/src/test_utils/local_signer.rs deleted file mode 100644 index 896d90775..000000000 --- a/eth2/attester/src/test_utils/local_signer.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::traits::Signer; -use std::sync::RwLock; -use types::{Keypair, Signature}; - -/// A test-only struct used to simulate a Beacon Node. -pub struct LocalSigner { - keypair: Keypair, - should_sign: RwLock, -} - -impl LocalSigner { - /// Produce a new LocalSigner with signing enabled by default. - pub fn new(keypair: Keypair) -> Self { - Self { - keypair, - should_sign: RwLock::new(true), - } - } - - /// If set to `false`, the service will refuse to sign all messages. Otherwise, all messages - /// will be signed. - pub fn enable_signing(&self, enabled: bool) { - *self.should_sign.write().unwrap() = enabled; - } -} - -impl Signer for LocalSigner { - fn sign_attestation_message(&self, message: &[u8], domain: u64) -> Option { - Some(Signature::new(message, domain, &self.keypair.sk)) - } -} diff --git a/eth2/attester/src/test_utils/mod.rs b/eth2/attester/src/test_utils/mod.rs deleted file mode 100644 index 481247dd0..000000000 --- a/eth2/attester/src/test_utils/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod epoch_map; -mod local_signer; -mod simulated_beacon_node; - -pub use self::epoch_map::EpochMap; -pub use self::local_signer::LocalSigner; -pub use self::simulated_beacon_node::SimulatedBeaconNode; diff --git a/eth2/attester/src/test_utils/simulated_beacon_node.rs b/eth2/attester/src/test_utils/simulated_beacon_node.rs deleted file mode 100644 index d19f43422..000000000 --- a/eth2/attester/src/test_utils/simulated_beacon_node.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::traits::{BeaconNode, BeaconNodeError, PublishOutcome}; -use std::sync::RwLock; -use types::{AttestationData, FreeAttestation, Slot}; - -type ProduceResult = Result, BeaconNodeError>; -type PublishResult = Result; - -/// A test-only struct used to simulate a Beacon Node. -#[derive(Default)] -pub struct SimulatedBeaconNode { - pub produce_input: RwLock>, - pub produce_result: RwLock>, - - pub publish_input: RwLock>, - pub publish_result: RwLock>, -} - -impl SimulatedBeaconNode { - pub fn set_next_produce_result(&self, result: ProduceResult) { - *self.produce_result.write().unwrap() = Some(result); - } - - pub fn set_next_publish_result(&self, result: PublishResult) { - *self.publish_result.write().unwrap() = Some(result); - } -} - -impl BeaconNode for SimulatedBeaconNode { - fn produce_attestation_data(&self, slot: Slot, shard: u64) -> ProduceResult { - *self.produce_input.write().unwrap() = Some((slot, shard)); - match *self.produce_result.read().unwrap() { - Some(ref r) => r.clone(), - None => panic!("TestBeaconNode: produce_result == None"), - } - } - - fn publish_attestation(&self, free_attestation: FreeAttestation) -> PublishResult { - *self.publish_input.write().unwrap() = Some(free_attestation.clone()); - match *self.publish_result.read().unwrap() { - Some(ref r) => r.clone(), - None => panic!("TestBeaconNode: publish_result == None"), - } - } -} diff --git a/eth2/attester/src/traits.rs b/eth2/attester/src/traits.rs deleted file mode 100644 index 2fd6940af..000000000 --- a/eth2/attester/src/traits.rs +++ /dev/null @@ -1,49 +0,0 @@ -use types::{AttestationData, FreeAttestation, Signature, Slot}; - -#[derive(Debug, PartialEq, Clone)] -pub enum BeaconNodeError { - RemoteFailure(String), - DecodeFailure, -} - -#[derive(Debug, PartialEq, Clone)] -pub enum PublishOutcome { - ValidAttestation, - InvalidAttestation(String), -} - -/// Defines the methods required to produce and publish blocks on a Beacon Node. -pub trait BeaconNode: Send + Sync { - fn produce_attestation_data( - &self, - slot: Slot, - shard: u64, - ) -> Result, BeaconNodeError>; - - fn publish_attestation( - &self, - free_attestation: FreeAttestation, - ) -> Result; -} - -#[derive(Debug, PartialEq, Clone)] -pub enum DutiesReaderError { - UnknownValidator, - UnknownEpoch, - EpochLengthIsZero, - Poisoned, -} - -/// Informs a validator of their duties (e.g., block production). -pub trait DutiesReader: Send + Sync { - /// Returns `Some(shard)` if this slot is an attestation slot. Otherwise, returns `None.` - fn attestation_shard(&self, slot: Slot) -> Result, DutiesReaderError>; - - /// Returns `Some(shard)` if this slot is an attestation slot. Otherwise, returns `None.` - fn validator_index(&self) -> Option; -} - -/// Signs message using an internally-maintained private key. -pub trait Signer { - fn sign_attestation_message(&self, message: &[u8], domain: u64) -> Option; -} diff --git a/eth2/block_proposer/Cargo.toml b/eth2/block_proposer/Cargo.toml deleted file mode 100644 index b5e60d383..000000000 --- a/eth2/block_proposer/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "block_proposer" -version = "0.1.0" -authors = ["Paul Hauner "] -edition = "2018" - -[dependencies] -int_to_bytes = { path = "../utils/int_to_bytes" } -slot_clock = { path = "../utils/slot_clock" } -ssz = { path = "../utils/ssz" } -tree_hash = { path = "../../eth2/utils/tree_hash" } -types = { path = "../types" } diff --git a/eth2/block_proposer/src/lib.rs b/eth2/block_proposer/src/lib.rs deleted file mode 100644 index f38278e53..000000000 --- a/eth2/block_proposer/src/lib.rs +++ /dev/null @@ -1,303 +0,0 @@ -pub mod test_utils; -mod traits; - -use slot_clock::SlotClock; -use std::sync::Arc; -use tree_hash::{SignedRoot, TreeHash}; -use types::{BeaconBlock, ChainSpec, Domain, Slot}; - -pub use self::traits::{ - BeaconNode, BeaconNodeError, DutiesReader, DutiesReaderError, PublishOutcome, Signer, -}; - -#[derive(Debug, PartialEq)] -pub enum PollOutcome { - /// A new block was produced. - BlockProduced(Slot), - /// A block was not produced as it would have been slashable. - SlashableBlockNotProduced(Slot), - /// The validator duties did not require a block to be produced. - BlockProductionNotRequired(Slot), - /// The duties for the present epoch were not found. - ProducerDutiesUnknown(Slot), - /// The slot has already been processed, execution was skipped. - SlotAlreadyProcessed(Slot), - /// The Beacon Node was unable to produce a block at that slot. - BeaconNodeUnableToProduceBlock(Slot), - /// The signer failed to sign the message. - SignerRejection(Slot), - /// The public key for this validator is not an active validator. - ValidatorIsUnknown(Slot), - /// Unable to determine a `Fork` for signature domain generation. - UnableToGetFork(Slot), -} - -#[derive(Debug, PartialEq)] -pub enum Error { - SlotClockError, - SlotUnknowable, - EpochMapPoisoned, - SlotClockPoisoned, - EpochLengthIsZero, - BeaconNodeError(BeaconNodeError), -} - -/// A polling state machine which performs block production duties, based upon some epoch duties -/// (`EpochDutiesMap`) and a concept of time (`SlotClock`). -/// -/// Ensures that messages are not slashable. -/// -/// Relies upon an external service to keep the `EpochDutiesMap` updated. -pub struct BlockProducer { - pub last_processed_slot: Option, - spec: Arc, - epoch_map: Arc, - slot_clock: Arc, - beacon_node: Arc, - signer: Arc, -} - -impl BlockProducer { - /// Returns a new instance where `last_processed_slot == 0`. - pub fn new( - spec: Arc, - epoch_map: Arc, - slot_clock: Arc, - beacon_node: Arc, - signer: Arc, - ) -> Self { - Self { - last_processed_slot: None, - spec, - epoch_map, - slot_clock, - beacon_node, - signer, - } - } -} - -impl BlockProducer { - /// "Poll" to see if the validator is required to take any action. - /// - /// The slot clock will be read and any new actions undertaken. - pub fn poll(&mut self) -> Result { - let slot = self - .slot_clock - .present_slot() - .map_err(|_| Error::SlotClockError)? - .ok_or(Error::SlotUnknowable)?; - - // If this is a new slot. - if !self.is_processed_slot(slot) { - let is_block_production_slot = match self.epoch_map.is_block_production_slot(slot) { - Ok(result) => result, - Err(DutiesReaderError::UnknownEpoch) => { - return Ok(PollOutcome::ProducerDutiesUnknown(slot)); - } - Err(DutiesReaderError::UnknownValidator) => { - return Ok(PollOutcome::ValidatorIsUnknown(slot)); - } - Err(DutiesReaderError::EpochLengthIsZero) => return Err(Error::EpochLengthIsZero), - Err(DutiesReaderError::Poisoned) => return Err(Error::EpochMapPoisoned), - }; - - if is_block_production_slot { - self.last_processed_slot = Some(slot); - - self.produce_block(slot) - } else { - Ok(PollOutcome::BlockProductionNotRequired(slot)) - } - } else { - Ok(PollOutcome::SlotAlreadyProcessed(slot)) - } - } - - fn is_processed_slot(&self, slot: Slot) -> bool { - match self.last_processed_slot { - Some(processed_slot) if processed_slot >= slot => true, - _ => false, - } - } - - /// Produce a block at some slot. - /// - /// Assumes that a block is required at this slot (does not check the duties). - /// - /// Ensures the message is not slashable. - /// - /// !!! UNSAFE !!! - /// - /// The slash-protection code is not yet implemented. There is zero protection against - /// slashing. - fn produce_block(&mut self, slot: Slot) -> Result { - let fork = match self.epoch_map.fork() { - Ok(fork) => fork, - Err(_) => return Ok(PollOutcome::UnableToGetFork(slot)), - }; - - let randao_reveal = { - // TODO: add domain, etc to this message. Also ensure result matches `into_to_bytes32`. - let message = slot.epoch(self.spec.slots_per_epoch).tree_hash_root(); - - match self.signer.sign_randao_reveal( - &message, - self.spec - .get_domain(slot.epoch(self.spec.slots_per_epoch), Domain::Randao, &fork), - ) { - None => return Ok(PollOutcome::SignerRejection(slot)), - Some(signature) => signature, - } - }; - - if let Some(block) = self - .beacon_node - .produce_beacon_block(slot, &randao_reveal)? - { - if self.safe_to_produce(&block) { - let domain = self.spec.get_domain( - slot.epoch(self.spec.slots_per_epoch), - Domain::BeaconBlock, - &fork, - ); - if let Some(block) = self.sign_block(block, domain) { - self.beacon_node.publish_beacon_block(block)?; - Ok(PollOutcome::BlockProduced(slot)) - } else { - Ok(PollOutcome::SignerRejection(slot)) - } - } else { - Ok(PollOutcome::SlashableBlockNotProduced(slot)) - } - } else { - Ok(PollOutcome::BeaconNodeUnableToProduceBlock(slot)) - } - } - - /// Consumes a block, returning that block signed by the validators private key. - /// - /// Important: this function will not check to ensure the block is not slashable. This must be - /// done upstream. - fn sign_block(&mut self, mut block: BeaconBlock, domain: u64) -> Option { - self.store_produce(&block); - - match self - .signer - .sign_block_proposal(&block.signed_root()[..], domain) - { - None => None, - Some(signature) => { - block.signature = signature; - Some(block) - } - } - } - - /// Returns `true` if signing a block is safe (non-slashable). - /// - /// !!! UNSAFE !!! - /// - /// Important: this function is presently stubbed-out. It provides ZERO SAFETY. - fn safe_to_produce(&self, _block: &BeaconBlock) -> bool { - // TODO: ensure the producer doesn't produce slashable blocks. - // https://github.com/sigp/lighthouse/issues/160 - true - } - - /// Record that a block was produced so that slashable votes may not be made in the future. - /// - /// !!! UNSAFE !!! - /// - /// Important: this function is presently stubbed-out. It provides ZERO SAFETY. - fn store_produce(&mut self, _block: &BeaconBlock) { - // TODO: record this block production to prevent future slashings. - // https://github.com/sigp/lighthouse/issues/160 - } -} - -impl From for Error { - fn from(e: BeaconNodeError) -> Error { - Error::BeaconNodeError(e) - } -} - -#[cfg(test)] -mod tests { - use super::test_utils::{EpochMap, LocalSigner, SimulatedBeaconNode}; - use super::*; - use slot_clock::TestingSlotClock; - use types::{ - test_utils::{SeedableRng, TestRandom, XorShiftRng}, - Keypair, - }; - - // TODO: implement more thorough testing. - // https://github.com/sigp/lighthouse/issues/160 - // - // These tests should serve as a good example for future tests. - - #[test] - pub fn polling() { - let mut rng = XorShiftRng::from_seed([42; 16]); - - let spec = Arc::new(ChainSpec::foundation()); - let slot_clock = Arc::new(TestingSlotClock::new(0)); - let beacon_node = Arc::new(SimulatedBeaconNode::default()); - let signer = Arc::new(LocalSigner::new(Keypair::random())); - - let mut epoch_map = EpochMap::new(spec.slots_per_epoch); - let produce_slot = Slot::new(100); - let produce_epoch = produce_slot.epoch(spec.slots_per_epoch); - epoch_map.map.insert(produce_epoch, produce_slot); - let epoch_map = Arc::new(epoch_map); - - let mut block_proposer = BlockProducer::new( - spec.clone(), - epoch_map.clone(), - slot_clock.clone(), - beacon_node.clone(), - signer.clone(), - ); - - // Configure responses from the BeaconNode. - beacon_node.set_next_produce_result(Ok(Some(BeaconBlock::random_for_test(&mut rng)))); - beacon_node.set_next_publish_result(Ok(PublishOutcome::ValidBlock)); - - // One slot before production slot... - slot_clock.set_slot(produce_slot.as_u64() - 1); - assert_eq!( - block_proposer.poll(), - Ok(PollOutcome::BlockProductionNotRequired(produce_slot - 1)) - ); - - // On the produce slot... - slot_clock.set_slot(produce_slot.as_u64()); - assert_eq!( - block_proposer.poll(), - Ok(PollOutcome::BlockProduced(produce_slot.into())) - ); - - // Trying the same produce slot again... - slot_clock.set_slot(produce_slot.as_u64()); - assert_eq!( - block_proposer.poll(), - Ok(PollOutcome::SlotAlreadyProcessed(produce_slot)) - ); - - // One slot after the produce slot... - slot_clock.set_slot(produce_slot.as_u64() + 1); - assert_eq!( - block_proposer.poll(), - Ok(PollOutcome::BlockProductionNotRequired(produce_slot + 1)) - ); - - // In an epoch without known duties... - let slot = (produce_epoch.as_u64() + 1) * spec.slots_per_epoch; - slot_clock.set_slot(slot); - assert_eq!( - block_proposer.poll(), - Ok(PollOutcome::ProducerDutiesUnknown(Slot::new(slot))) - ); - } -} diff --git a/eth2/block_proposer/src/test_utils/epoch_map.rs b/eth2/block_proposer/src/test_utils/epoch_map.rs deleted file mode 100644 index c06c376c6..000000000 --- a/eth2/block_proposer/src/test_utils/epoch_map.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::{DutiesReader, DutiesReaderError}; -use std::collections::HashMap; -use types::{Epoch, Fork, Slot}; - -pub struct EpochMap { - slots_per_epoch: u64, - pub map: HashMap, -} - -impl EpochMap { - pub fn new(slots_per_epoch: u64) -> Self { - Self { - slots_per_epoch, - map: HashMap::new(), - } - } -} - -impl DutiesReader for EpochMap { - fn is_block_production_slot(&self, slot: Slot) -> Result { - let epoch = slot.epoch(self.slots_per_epoch); - match self.map.get(&epoch) { - Some(s) if *s == slot => Ok(true), - Some(s) if *s != slot => Ok(false), - _ => Err(DutiesReaderError::UnknownEpoch), - } - } - - fn fork(&self) -> Result { - Ok(Fork { - previous_version: [0; 4], - current_version: [0; 4], - epoch: Epoch::new(0), - }) - } -} diff --git a/eth2/block_proposer/src/test_utils/local_signer.rs b/eth2/block_proposer/src/test_utils/local_signer.rs deleted file mode 100644 index d7f490c30..000000000 --- a/eth2/block_proposer/src/test_utils/local_signer.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::traits::Signer; -use std::sync::RwLock; -use types::{Keypair, Signature}; - -/// A test-only struct used to simulate a Beacon Node. -pub struct LocalSigner { - keypair: Keypair, - should_sign: RwLock, -} - -impl LocalSigner { - /// Produce a new LocalSigner with signing enabled by default. - pub fn new(keypair: Keypair) -> Self { - Self { - keypair, - should_sign: RwLock::new(true), - } - } - - /// If set to `false`, the service will refuse to sign all messages. Otherwise, all messages - /// will be signed. - pub fn enable_signing(&self, enabled: bool) { - *self.should_sign.write().unwrap() = enabled; - } -} - -impl Signer for LocalSigner { - fn sign_block_proposal(&self, message: &[u8], domain: u64) -> Option { - Some(Signature::new(message, domain, &self.keypair.sk)) - } - - fn sign_randao_reveal(&self, message: &[u8], domain: u64) -> Option { - Some(Signature::new(message, domain, &self.keypair.sk)) - } -} diff --git a/eth2/block_proposer/src/test_utils/mod.rs b/eth2/block_proposer/src/test_utils/mod.rs deleted file mode 100644 index 481247dd0..000000000 --- a/eth2/block_proposer/src/test_utils/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod epoch_map; -mod local_signer; -mod simulated_beacon_node; - -pub use self::epoch_map::EpochMap; -pub use self::local_signer::LocalSigner; -pub use self::simulated_beacon_node::SimulatedBeaconNode; diff --git a/eth2/block_proposer/src/test_utils/simulated_beacon_node.rs b/eth2/block_proposer/src/test_utils/simulated_beacon_node.rs deleted file mode 100644 index c0a12c1ac..000000000 --- a/eth2/block_proposer/src/test_utils/simulated_beacon_node.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::traits::{BeaconNode, BeaconNodeError, PublishOutcome}; -use std::sync::RwLock; -use types::{BeaconBlock, Signature, Slot}; - -type ProduceResult = Result, BeaconNodeError>; -type PublishResult = Result; - -/// A test-only struct used to simulate a Beacon Node. -#[derive(Default)] -pub struct SimulatedBeaconNode { - pub produce_input: RwLock>, - pub produce_result: RwLock>, - - pub publish_input: RwLock>, - pub publish_result: RwLock>, -} - -impl SimulatedBeaconNode { - /// Set the result to be returned when `produce_beacon_block` is called. - pub fn set_next_produce_result(&self, result: ProduceResult) { - *self.produce_result.write().unwrap() = Some(result); - } - - /// Set the result to be returned when `publish_beacon_block` is called. - pub fn set_next_publish_result(&self, result: PublishResult) { - *self.publish_result.write().unwrap() = Some(result); - } -} - -impl BeaconNode for SimulatedBeaconNode { - /// Returns the value specified by the `set_next_produce_result`. - fn produce_beacon_block(&self, slot: Slot, randao_reveal: &Signature) -> ProduceResult { - *self.produce_input.write().unwrap() = Some((slot, randao_reveal.clone())); - match *self.produce_result.read().unwrap() { - Some(ref r) => r.clone(), - None => panic!("SimulatedBeaconNode: produce_result == None"), - } - } - - /// Returns the value specified by the `set_next_publish_result`. - fn publish_beacon_block(&self, block: BeaconBlock) -> PublishResult { - *self.publish_input.write().unwrap() = Some(block); - match *self.publish_result.read().unwrap() { - Some(ref r) => r.clone(), - None => panic!("SimulatedBeaconNode: publish_result == None"), - } - } -} diff --git a/eth2/block_proposer/src/traits.rs b/eth2/block_proposer/src/traits.rs deleted file mode 100644 index 1c0da9acf..000000000 --- a/eth2/block_proposer/src/traits.rs +++ /dev/null @@ -1,50 +0,0 @@ -use types::{BeaconBlock, Fork, Signature, Slot}; - -#[derive(Debug, PartialEq, Clone)] -pub enum BeaconNodeError { - RemoteFailure(String), - DecodeFailure, -} - -#[derive(Debug, PartialEq, Clone)] -pub enum PublishOutcome { - ValidBlock, - InvalidBlock(String), -} - -/// Defines the methods required to produce and publish blocks on a Beacon Node. -pub trait BeaconNode: Send + Sync { - /// Request that the node produces a block. - /// - /// Returns Ok(None) if the Beacon Node is unable to produce at the given slot. - fn produce_beacon_block( - &self, - slot: Slot, - randao_reveal: &Signature, - ) -> Result, BeaconNodeError>; - - /// Request that the node publishes a block. - /// - /// Returns `true` if the publish was sucessful. - fn publish_beacon_block(&self, block: BeaconBlock) -> Result; -} - -#[derive(Debug, PartialEq, Clone)] -pub enum DutiesReaderError { - UnknownValidator, - UnknownEpoch, - EpochLengthIsZero, - Poisoned, -} - -/// Informs a validator of their duties (e.g., block production). -pub trait DutiesReader: Send + Sync { - fn is_block_production_slot(&self, slot: Slot) -> Result; - fn fork(&self) -> Result; -} - -/// Signs message using an internally-maintained private key. -pub trait Signer { - fn sign_block_proposal(&self, message: &[u8], domain: u64) -> Option; - fn sign_randao_reveal(&self, message: &[u8], domain: u64) -> Option; -} diff --git a/validator_client/Cargo.toml b/validator_client/Cargo.toml index 7f6b0cee9..559460c8b 100644 --- a/validator_client/Cargo.toml +++ b/validator_client/Cargo.toml @@ -13,8 +13,6 @@ name = "validator_client" path = "src/lib.rs" [dependencies] -block_proposer = { path = "../eth2/block_proposer" } -attester = { path = "../eth2/attester" } bls = { path = "../eth2/utils/bls" } ssz = { path = "../eth2/utils/ssz" } tree_hash = { path = "../eth2/utils/tree_hash" } From 0ac278f44db91b1467a275a28e10e1da2b4d86e4 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 9 May 2019 12:19:52 +1000 Subject: [PATCH 13/22] Update `validator_client` for `BeaconStateTypes` --- beacon_node/eth2-libp2p/src/behaviour.rs | 2 +- validator_client/src/config.rs | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/beacon_node/eth2-libp2p/src/behaviour.rs b/beacon_node/eth2-libp2p/src/behaviour.rs index e1112e6ff..f8a0a7249 100644 --- a/beacon_node/eth2-libp2p/src/behaviour.rs +++ b/beacon_node/eth2-libp2p/src/behaviour.rs @@ -236,7 +236,7 @@ mod test { #[test] fn ssz_encoding() { - let original = PubsubMessage::Block(BeaconBlock::empty(&ChainSpec::foundation())); + let original = PubsubMessage::Block(BeaconBlock::empty(&FoundationStateTypes::spec())); let encoded = ssz_encode(&original); diff --git a/validator_client/src/config.rs b/validator_client/src/config.rs index 903da047e..66e9f2391 100644 --- a/validator_client/src/config.rs +++ b/validator_client/src/config.rs @@ -6,7 +6,10 @@ use std::fs; use std::fs::File; use std::io::{Error, ErrorKind}; use std::path::PathBuf; -use types::ChainSpec; +use types::{ + BeaconStateTypes, ChainSpec, FewValidatorsStateTypes, FoundationStateTypes, + LighthouseTestnetStateTypes, +}; /// Stores the core configuration for this validator instance. #[derive(Clone)] @@ -31,7 +34,7 @@ impl Default for Config { let server = "localhost:5051".to_string(); - let spec = ChainSpec::foundation(); + let spec = FoundationStateTypes::spec(); Self { data_dir, @@ -65,9 +68,9 @@ impl Config { if let Some(spec_str) = args.value_of("spec") { info!(log, "Using custom spec: {:?}", spec_str); config.spec = match spec_str { - "foundation" => ChainSpec::foundation(), - "few_validators" => ChainSpec::few_validators(), - "lighthouse_testnet" => ChainSpec::lighthouse_testnet(), + "foundation" => FoundationStateTypes::spec(), + "few_validators" => FewValidatorsStateTypes::spec(), + "lighthouse_testnet" => LighthouseTestnetStateTypes::spec(), // Should be impossible due to clap's `possible_values(..)` function. _ => unreachable!(), }; From 2a938f2fd5fc932513f4c27af74a3cc9828f0d25 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 9 May 2019 13:35:00 +1000 Subject: [PATCH 14/22] Fix clippy lints --- beacon_node/beacon_chain/src/beacon_chain.rs | 1 - beacon_node/client/src/client_types.rs | 11 ++++------- beacon_node/client/src/lib.rs | 4 +++- beacon_node/db/src/disk_db.rs | 2 +- beacon_node/db/src/stores/beacon_state_store.rs | 4 ++-- beacon_node/network/src/message_handler.rs | 2 +- eth2/operation_pool/src/lib.rs | 6 +----- eth2/types/src/beacon_state.rs | 2 +- eth2/utils/boolean-bitfield/src/lib.rs | 2 +- eth2/utils/fixed_len_vec/src/lib.rs | 4 ++++ eth2/utils/hashing/src/lib.rs | 2 +- validator_client/src/duties/mod.rs | 2 +- validator_client/src/service.rs | 1 - 13 files changed, 20 insertions(+), 23 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 2bbb6901c..2b2d5f015 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -191,7 +191,6 @@ where count: usize, skip: usize, ) -> Result, Error> { - let spec = &self.spec; let step_by = Slot::from(skip + 1); let mut roots: Vec = vec![]; diff --git a/beacon_node/client/src/client_types.rs b/beacon_node/client/src/client_types.rs index b934b508e..ba8fc47de 100644 --- a/beacon_node/client/src/client_types.rs +++ b/beacon_node/client/src/client_types.rs @@ -1,16 +1,13 @@ -use crate::ClientConfig; +use crate::{ArcBeaconChain, ClientConfig}; use beacon_chain::{ db::{ClientDB, DiskDB, MemoryDB}, fork_choice::BitwiseLMDGhost, initialise, slot_clock::{SlotClock, SystemTimeSlotClock}, - BeaconChain, }; use fork_choice::ForkChoice; use types::{BeaconStateTypes, FewValidatorsStateTypes, FoundationStateTypes}; -use std::sync::Arc; - pub trait ClientTypes { type DB: ClientDB + 'static; type SlotClock: SlotClock + 'static; @@ -19,7 +16,7 @@ pub trait ClientTypes { fn initialise_beacon_chain( config: &ClientConfig, - ) -> Arc>; + ) -> ArcBeaconChain; } pub struct StandardClientType; @@ -32,7 +29,7 @@ impl ClientTypes for StandardClientType { fn initialise_beacon_chain( config: &ClientConfig, - ) -> Arc> { + ) -> ArcBeaconChain { initialise::initialise_beacon_chain(&config.spec, Some(&config.db_name)) } } @@ -47,7 +44,7 @@ impl ClientTypes for TestingClientType { fn initialise_beacon_chain( config: &ClientConfig, - ) -> Arc> { + ) -> ArcBeaconChain { initialise::initialise_test_beacon_chain(&config.spec, None) } } diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index 466256735..c3dd5cbd8 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -22,13 +22,15 @@ use tokio::runtime::TaskExecutor; use tokio::timer::Interval; use types::BeaconStateTypes; +type ArcBeaconChain = Arc>; + /// Main beacon node client service. This provides the connection and initialisation of the clients /// sub-services in multiple threads. pub struct Client { /// Configuration for the lighthouse client. _config: ClientConfig, /// The beacon chain for the running client. - _beacon_chain: Arc>, + _beacon_chain: ArcBeaconChain, /// Reference to the network service. pub network: Arc>, /// Signal to terminate the RPC server. diff --git a/beacon_node/db/src/disk_db.rs b/beacon_node/db/src/disk_db.rs index 9d8a71bc4..2d26315da 100644 --- a/beacon_node/db/src/disk_db.rs +++ b/beacon_node/db/src/disk_db.rs @@ -97,7 +97,7 @@ impl ClientDB for DiskDB { None => Err(DBError { message: "Unknown column".to_string(), }), - Some(handle) => self.db.put_cf(handle, key, val).map_err(|e| e.into()), + Some(handle) => self.db.put_cf(handle, key, val).map_err(Into::into), } } diff --git a/beacon_node/db/src/stores/beacon_state_store.rs b/beacon_node/db/src/stores/beacon_state_store.rs index 5a5af33d3..4c40d2287 100644 --- a/beacon_node/db/src/stores/beacon_state_store.rs +++ b/beacon_node/db/src/stores/beacon_state_store.rs @@ -2,7 +2,7 @@ use super::STATES_DB_COLUMN as DB_COLUMN; use super::{ClientDB, DBError}; use ssz::decode; use std::sync::Arc; -use types::{BeaconState, BeaconStateTypes, FoundationBeaconState, Hash256}; +use types::{BeaconState, BeaconStateTypes, Hash256}; pub struct BeaconStateStore where @@ -43,7 +43,7 @@ mod tests { use ssz::ssz_encode; use std::sync::Arc; use types::test_utils::{SeedableRng, TestRandom, XorShiftRng}; - use types::Hash256; + use types::{FoundationBeaconState, Hash256}; test_crud_for_store!(BeaconStateStore, DB_COLUMN); diff --git a/beacon_node/network/src/message_handler.rs b/beacon_node/network/src/message_handler.rs index 90aff0041..6d3348910 100644 --- a/beacon_node/network/src/message_handler.rs +++ b/beacon_node/network/src/message_handler.rs @@ -300,7 +300,7 @@ impl NetworkContext { let next_id = self .outgoing_request_ids .entry(peer_id.clone()) - .and_modify(|id| id.increment()) + .and_modify(RequestId::increment) .or_insert_with(|| RequestId::from(1)); next_id.previous() diff --git a/eth2/operation_pool/src/lib.rs b/eth2/operation_pool/src/lib.rs index eed46196a..66f0f0df8 100644 --- a/eth2/operation_pool/src/lib.rs +++ b/eth2/operation_pool/src/lib.rs @@ -175,11 +175,7 @@ impl OperationPool { /// Total number of attestations in the pool, including attestations for the same data. pub fn num_attestations(&self) -> usize { - self.attestations - .read() - .values() - .map(|atts| atts.len()) - .sum() + self.attestations.read().values().map(Vec::len).sum() } /// Get a list of attestations for inclusion in a block. diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index 3dc5358c8..03c39db61 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -817,7 +817,7 @@ impl BeaconState { self.tree_hash_cache .tree_hash_root() .and_then(|b| Ok(Hash256::from_slice(b))) - .map_err(|e| e.into()) + .map_err(Into::into) } } diff --git a/eth2/utils/boolean-bitfield/src/lib.rs b/eth2/utils/boolean-bitfield/src/lib.rs index d49da0d10..875da855c 100644 --- a/eth2/utils/boolean-bitfield/src/lib.rs +++ b/eth2/utils/boolean-bitfield/src/lib.rs @@ -226,7 +226,7 @@ impl Decodable for BooleanBitfield { // as the BitVec library and the hex-parser use opposing bit orders. fn reverse_bit_order(mut bytes: Vec) -> Vec { bytes.reverse(); - bytes.into_iter().map(|b| b.swap_bits()).collect() + bytes.into_iter().map(LookupReverse::swap_bits).collect() } impl Serialize for BooleanBitfield { diff --git a/eth2/utils/fixed_len_vec/src/lib.rs b/eth2/utils/fixed_len_vec/src/lib.rs index 0d811566b..085b1835b 100644 --- a/eth2/utils/fixed_len_vec/src/lib.rs +++ b/eth2/utils/fixed_len_vec/src/lib.rs @@ -22,6 +22,10 @@ impl FixedLenVec { self.vec.len() } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn capacity() -> usize { N::to_usize() } diff --git a/eth2/utils/hashing/src/lib.rs b/eth2/utils/hashing/src/lib.rs index 68e29fc9b..d1d2c28d9 100644 --- a/eth2/utils/hashing/src/lib.rs +++ b/eth2/utils/hashing/src/lib.rs @@ -35,7 +35,7 @@ pub fn merkle_root(values: &[Vec]) -> Option> { } // the root hash will be at index 1 - return Some(o[1].clone()); + Some(o[1].clone()) } #[cfg(test)] diff --git a/validator_client/src/duties/mod.rs b/validator_client/src/duties/mod.rs index 7db4672e3..b2ddfd0b0 100644 --- a/validator_client/src/duties/mod.rs +++ b/validator_client/src/duties/mod.rs @@ -51,7 +51,7 @@ impl DutiesManager { /// /// be a wall-clock (e.g., system time, remote server time, etc.). fn update(&self, epoch: Epoch) -> Result { - let public_keys: Vec = self.signers.iter().map(|s| s.to_public()).collect(); + let public_keys: Vec = self.signers.iter().map(Signer::to_public).collect(); let duties = self.beacon_node.request_duties(epoch, &public_keys)?; { // If these duties were known, check to see if they're updates or identical. diff --git a/validator_client/src/service.rs b/validator_client/src/service.rs index fb5f32778..a340f99fc 100644 --- a/validator_client/src/service.rs +++ b/validator_client/src/service.rs @@ -31,7 +31,6 @@ use tokio::prelude::*; use tokio::runtime::Builder; use tokio::timer::Interval; use tokio_timer::clock::Clock; -use types::test_utils::generate_deterministic_keypairs; use types::{ChainSpec, Epoch, Fork, Slot}; /// A fixed amount of time after a slot to perform operations. This gives the node time to complete From 77c4b6eafeffcdd7facfb1e13630603b11812d6e Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 9 May 2019 18:56:41 +1000 Subject: [PATCH 15/22] Add progress on op pool test fixes --- eth2/operation_pool/src/lib.rs | 478 +++++++++--------- .../per_block_processing/verify_deposit.rs | 2 +- eth2/state_processing/tests/tests.rs | 153 ------ .../src/beacon_state/beacon_state_types.rs | 11 +- eth2/types/src/deposit.rs | 5 +- eth2/types/src/lib.rs | 4 +- 6 files changed, 259 insertions(+), 394 deletions(-) delete mode 100644 eth2/state_processing/tests/tests.rs diff --git a/eth2/operation_pool/src/lib.rs b/eth2/operation_pool/src/lib.rs index 66f0f0df8..961228d56 100644 --- a/eth2/operation_pool/src/lib.rs +++ b/eth2/operation_pool/src/lib.rs @@ -718,13 +718,16 @@ mod tests { /// Create a signed attestation for use in tests. /// Signed by all validators in `committee[signing_range]` and `committee[extra_signer]`. - #[cfg(not(debug_assertions))] - fn signed_attestation>( + // #[cfg(not(debug_assertions))] + fn signed_attestation< + R: std::slice::SliceIndex<[usize], Output = [usize]>, + B: BeaconStateTypes, + >( committee: &CrosslinkCommittee, keypairs: &[Keypair], signing_range: R, slot: Slot, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, extra_signer: Option, ) -> Attestation { @@ -750,259 +753,270 @@ mod tests { builder.build() } - /// Test state for attestation-related tests. #[cfg(not(debug_assertions))] - fn attestation_test_state( - spec: &ChainSpec, - num_committees: usize, - ) -> (BeaconState, Vec) { - let num_validators = - num_committees * (spec.slots_per_epoch * spec.target_committee_size) as usize; - let mut state_builder = - TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(num_validators, spec); - let slot_offset = 1000 * spec.slots_per_epoch + spec.slots_per_epoch / 2; - let slot = spec.genesis_slot + slot_offset; - state_builder.teleport_to_slot(slot, spec); - state_builder.build_caches(spec).unwrap(); - state_builder.build() - } + mod release_tests { + use super::*; - /// Set the latest crosslink in the state to match the attestation. - #[cfg(not(debug_assertions))] - fn fake_latest_crosslink(att: &Attestation, state: &mut BeaconState, spec: &ChainSpec) { - state.latest_crosslinks[att.data.shard as usize] = Crosslink { - crosslink_data_root: att.data.crosslink_data_root, - epoch: att.data.slot.epoch(spec.slots_per_epoch), - }; - } + /// Test state for attestation-related tests. + fn attestation_test_state( + num_committees: usize, + ) -> (BeaconState, Vec, ChainSpec) { + let spec = B::spec(); - #[test] - #[cfg(not(debug_assertions))] - fn test_attestation_score() { - let spec = &ChainSpec::foundation(); - let (ref mut state, ref keypairs) = attestation_test_state(spec, 1); - let slot = state.slot - 1; - let committees = state - .get_crosslink_committees_at_slot(slot, spec) - .unwrap() - .clone(); - - for committee in committees { - let att1 = signed_attestation(&committee, keypairs, ..2, slot, state, spec, None); - let att2 = signed_attestation(&committee, keypairs, .., slot, state, spec, None); - - assert_eq!( - att1.aggregation_bitfield.num_set_bits(), - attestation_score(&att1, state, spec) + let num_validators = + num_committees * (spec.slots_per_epoch * spec.target_committee_size) as usize; + let mut state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists( + num_validators, + &spec, ); + let slot_offset = 1000 * spec.slots_per_epoch + spec.slots_per_epoch / 2; + let slot = spec.genesis_slot + slot_offset; + state_builder.teleport_to_slot(slot, &spec); + state_builder.build_caches(&spec).unwrap(); + let (state, keypairs) = state_builder.build(); - state - .current_epoch_attestations - .push(PendingAttestation::from_attestation(&att1, state.slot)); - - assert_eq!( - committee.committee.len() - 2, - attestation_score(&att2, state, spec) - ); + (state, keypairs, FoundationStateTypes::spec()) } - } - /// End-to-end test of basic attestation handling. - #[test] - #[cfg(not(debug_assertions))] - fn attestation_aggregation_insert_get_prune() { - let spec = &ChainSpec::foundation(); - let (ref mut state, ref keypairs) = attestation_test_state(spec, 1); - let op_pool = OperationPool::new(); + /// Set the latest crosslink in the state to match the attestation. + fn fake_latest_crosslink( + att: &Attestation, + state: &mut BeaconState, + spec: &ChainSpec, + ) { + state.latest_crosslinks[att.data.shard as usize] = Crosslink { + crosslink_data_root: att.data.crosslink_data_root, + epoch: att.data.slot.epoch(spec.slots_per_epoch), + }; + } - let slot = state.slot - 1; - let committees = state - .get_crosslink_committees_at_slot(slot, spec) - .unwrap() - .clone(); + #[test] + fn test_attestation_score() { + let (ref mut state, ref keypairs, ref spec) = + attestation_test_state::(1); - assert_eq!( - committees.len(), - 1, - "we expect just one committee with this many validators" - ); + let slot = state.slot - 1; + let committees = state + .get_crosslink_committees_at_slot(slot, spec) + .unwrap() + .clone(); + + for committee in committees { + let att1 = signed_attestation(&committee, keypairs, ..2, slot, state, spec, None); + let att2 = signed_attestation(&committee, keypairs, .., slot, state, spec, None); + + assert_eq!( + att1.aggregation_bitfield.num_set_bits(), + attestation_score(&att1, state, spec) + ); + + state + .current_epoch_attestations + .push(PendingAttestation::from_attestation(&att1, state.slot)); + + assert_eq!( + committee.committee.len() - 2, + attestation_score(&att2, state, spec) + ); + } + } + + /// End-to-end test of basic attestation handling. + #[test] + fn attestation_aggregation_insert_get_prune() { + let (ref mut state, ref keypairs, ref spec) = + attestation_test_state::(1); + + let op_pool = OperationPool::new(); + + let slot = state.slot - 1; + let committees = state + .get_crosslink_committees_at_slot(slot, spec) + .unwrap() + .clone(); + + assert_eq!( + committees.len(), + 1, + "we expect just one committee with this many validators" + ); + + for committee in &committees { + let step_size = 2; + for i in (0..committee.committee.len()).step_by(step_size) { + let att = signed_attestation( + committee, + keypairs, + i..i + step_size, + slot, + state, + spec, + None, + ); + fake_latest_crosslink(&att, state, spec); + op_pool.insert_attestation(att, state, spec).unwrap(); + } + } + + assert_eq!(op_pool.attestations.read().len(), committees.len()); + assert_eq!(op_pool.num_attestations(), committees.len()); + + // Before the min attestation inclusion delay, get_attestations shouldn't return anything. + assert_eq!(op_pool.get_attestations(state, spec).len(), 0); + + // Then once the delay has elapsed, we should get a single aggregated attestation. + state.slot += spec.min_attestation_inclusion_delay; + + let block_attestations = op_pool.get_attestations(state, spec); + assert_eq!(block_attestations.len(), committees.len()); + + let agg_att = &block_attestations[0]; + assert_eq!( + agg_att.aggregation_bitfield.num_set_bits(), + spec.target_committee_size as usize + ); + + // Prune attestations shouldn't do anything at this point. + op_pool.prune_attestations(state, spec); + assert_eq!(op_pool.num_attestations(), committees.len()); + + // But once we advance to an epoch after the attestation, it should prune it out of + // existence. + state.slot = slot + spec.slots_per_epoch; + op_pool.prune_attestations(state, spec); + assert_eq!(op_pool.num_attestations(), 0); + } + + /// Adding an attestation already in the pool should not increase the size of the pool. + #[test] + fn attestation_duplicate() { + let (ref mut state, ref keypairs, ref spec) = + attestation_test_state::(1); + + let op_pool = OperationPool::new(); + + let slot = state.slot - 1; + let committees = state + .get_crosslink_committees_at_slot(slot, spec) + .unwrap() + .clone(); + + for committee in &committees { + let att = signed_attestation(committee, keypairs, .., slot, state, spec, None); + fake_latest_crosslink(&att, state, spec); + op_pool + .insert_attestation(att.clone(), state, spec) + .unwrap(); + op_pool.insert_attestation(att, state, spec).unwrap(); + } + + assert_eq!(op_pool.num_attestations(), committees.len()); + } + + /// Adding lots of attestations that only intersect pairwise should lead to two aggregate + /// attestations. + #[test] + fn attestation_pairwise_overlapping() { + let (ref mut state, ref keypairs, ref spec) = + attestation_test_state::(1); + + let op_pool = OperationPool::new(); + + let slot = state.slot - 1; + let committees = state + .get_crosslink_committees_at_slot(slot, spec) + .unwrap() + .clone(); - for committee in &committees { let step_size = 2; - for i in (0..committee.committee.len()).step_by(step_size) { - let att = signed_attestation( - committee, - keypairs, - i..i + step_size, - slot, - state, - spec, - None, - ); - fake_latest_crosslink(&att, state, spec); - op_pool.insert_attestation(att, state, spec).unwrap(); + for committee in &committees { + // Create attestations that overlap on `step_size` validators, like: + // {0,1,2,3}, {2,3,4,5}, {4,5,6,7}, ... + for i in (0..committee.committee.len() - step_size).step_by(step_size) { + let att = signed_attestation( + committee, + keypairs, + i..i + 2 * step_size, + slot, + state, + spec, + None, + ); + fake_latest_crosslink(&att, state, spec); + op_pool.insert_attestation(att, state, spec).unwrap(); + } } + + // The attestations should get aggregated into two attestations that comprise all + // validators. + assert_eq!(op_pool.attestations.read().len(), committees.len()); + assert_eq!(op_pool.num_attestations(), 2 * committees.len()); } - assert_eq!(op_pool.attestations.read().len(), committees.len()); - assert_eq!(op_pool.num_attestations(), committees.len()); + /// Create a bunch of attestations signed by a small number of validators, and another + /// bunch signed by a larger number, such that there are at least `max_attestations` + /// signed by the larger number. Then, check that `get_attestations` only returns the + /// high-quality attestations. To ensure that no aggregation occurs, ALL attestations + /// are also signed by the 0th member of the committee. + #[test] + fn attestation_get_max() { + let spec = &ChainSpec::foundation(); + let small_step_size = 2; + let big_step_size = 4; + let (ref mut state, ref keypairs) = attestation_test_state(spec, big_step_size); + let op_pool = OperationPool::new(); - // Before the min attestation inclusion delay, get_attestations shouldn't return anything. - assert_eq!(op_pool.get_attestations(state, spec).len(), 0); + let slot = state.slot - 1; + let committees = state + .get_crosslink_committees_at_slot(slot, spec) + .unwrap() + .clone(); - // Then once the delay has elapsed, we should get a single aggregated attestation. - state.slot += spec.min_attestation_inclusion_delay; + let max_attestations = spec.max_attestations as usize; + let target_committee_size = spec.target_committee_size as usize; - let block_attestations = op_pool.get_attestations(state, spec); - assert_eq!(block_attestations.len(), committees.len()); + let mut insert_attestations = |committee, step_size| { + for i in (0..target_committee_size).step_by(step_size) { + let att = signed_attestation( + committee, + keypairs, + i..i + step_size, + slot, + state, + spec, + if i == 0 { None } else { Some(0) }, + ); + fake_latest_crosslink(&att, state, spec); + op_pool.insert_attestation(att, state, spec).unwrap(); + } + }; - let agg_att = &block_attestations[0]; - assert_eq!( - agg_att.aggregation_bitfield.num_set_bits(), - spec.target_committee_size as usize - ); - - // Prune attestations shouldn't do anything at this point. - op_pool.prune_attestations(state, spec); - assert_eq!(op_pool.num_attestations(), committees.len()); - - // But once we advance to an epoch after the attestation, it should prune it out of - // existence. - state.slot = slot + spec.slots_per_epoch; - op_pool.prune_attestations(state, spec); - assert_eq!(op_pool.num_attestations(), 0); - } - - /// Adding an attestation already in the pool should not increase the size of the pool. - #[test] - #[cfg(not(debug_assertions))] - fn attestation_duplicate() { - let spec = &ChainSpec::foundation(); - let (ref mut state, ref keypairs) = attestation_test_state(spec, 1); - let op_pool = OperationPool::new(); - - let slot = state.slot - 1; - let committees = state - .get_crosslink_committees_at_slot(slot, spec) - .unwrap() - .clone(); - - for committee in &committees { - let att = signed_attestation(committee, keypairs, .., slot, state, spec, None); - fake_latest_crosslink(&att, state, spec); - op_pool - .insert_attestation(att.clone(), state, spec) - .unwrap(); - op_pool.insert_attestation(att, state, spec).unwrap(); - } - - assert_eq!(op_pool.num_attestations(), committees.len()); - } - - /// Adding lots of attestations that only intersect pairwise should lead to two aggregate - /// attestations. - #[test] - #[cfg(not(debug_assertions))] - fn attestation_pairwise_overlapping() { - let spec = &ChainSpec::foundation(); - let (ref mut state, ref keypairs) = attestation_test_state(spec, 1); - let op_pool = OperationPool::new(); - - let slot = state.slot - 1; - let committees = state - .get_crosslink_committees_at_slot(slot, spec) - .unwrap() - .clone(); - - let step_size = 2; - for committee in &committees { - // Create attestations that overlap on `step_size` validators, like: - // {0,1,2,3}, {2,3,4,5}, {4,5,6,7}, ... - for i in (0..committee.committee.len() - step_size).step_by(step_size) { - let att = signed_attestation( - committee, - keypairs, - i..i + 2 * step_size, - slot, - state, - spec, - None, - ); - fake_latest_crosslink(&att, state, spec); - op_pool.insert_attestation(att, state, spec).unwrap(); + for committee in &committees { + assert_eq!(committee.committee.len(), target_committee_size); + // Attestations signed by only 2-3 validators + insert_attestations(committee, small_step_size); + // Attestations signed by 4+ validators + insert_attestations(committee, big_step_size); } - } - // The attestations should get aggregated into two attestations that comprise all - // validators. - assert_eq!(op_pool.attestations.read().len(), committees.len()); - assert_eq!(op_pool.num_attestations(), 2 * committees.len()); - } + let num_small = target_committee_size / small_step_size; + let num_big = target_committee_size / big_step_size; - /// Create a bunch of attestations signed by a small number of validators, and another - /// bunch signed by a larger number, such that there are at least `max_attestations` - /// signed by the larger number. Then, check that `get_attestations` only returns the - /// high-quality attestations. To ensure that no aggregation occurs, ALL attestations - /// are also signed by the 0th member of the committee. - #[test] - #[cfg(not(debug_assertions))] - fn attestation_get_max() { - let spec = &ChainSpec::foundation(); - let small_step_size = 2; - let big_step_size = 4; - let (ref mut state, ref keypairs) = attestation_test_state(spec, big_step_size); - let op_pool = OperationPool::new(); + assert_eq!(op_pool.attestations.read().len(), committees.len()); + assert_eq!( + op_pool.num_attestations(), + (num_small + num_big) * committees.len() + ); + assert!(op_pool.num_attestations() > max_attestations); - let slot = state.slot - 1; - let committees = state - .get_crosslink_committees_at_slot(slot, spec) - .unwrap() - .clone(); + state.slot += spec.min_attestation_inclusion_delay; + let best_attestations = op_pool.get_attestations(state, spec); + assert_eq!(best_attestations.len(), max_attestations); - let max_attestations = spec.max_attestations as usize; - let target_committee_size = spec.target_committee_size as usize; - - let mut insert_attestations = |committee, step_size| { - for i in (0..target_committee_size).step_by(step_size) { - let att = signed_attestation( - committee, - keypairs, - i..i + step_size, - slot, - state, - spec, - if i == 0 { None } else { Some(0) }, - ); - fake_latest_crosslink(&att, state, spec); - op_pool.insert_attestation(att, state, spec).unwrap(); + // All the best attestations should be signed by at least `big_step_size` (4) validators. + for att in &best_attestations { + assert!(att.aggregation_bitfield.num_set_bits() >= big_step_size); } - }; - - for committee in &committees { - assert_eq!(committee.committee.len(), target_committee_size); - // Attestations signed by only 2-3 validators - insert_attestations(committee, small_step_size); - // Attestations signed by 4+ validators - insert_attestations(committee, big_step_size); - } - - let num_small = target_committee_size / small_step_size; - let num_big = target_committee_size / big_step_size; - - assert_eq!(op_pool.attestations.read().len(), committees.len()); - assert_eq!( - op_pool.num_attestations(), - (num_small + num_big) * committees.len() - ); - assert!(op_pool.num_attestations() > max_attestations); - - state.slot += spec.min_attestation_inclusion_delay; - let best_attestations = op_pool.get_attestations(state, spec); - assert_eq!(best_attestations.len(), max_attestations); - - // All the best attestations should be signed by at least `big_step_size` (4) validators. - for att in &best_attestations { - assert!(att.aggregation_bitfield.num_set_bits() >= big_step_size); } } diff --git a/eth2/state_processing/src/per_block_processing/verify_deposit.rs b/eth2/state_processing/src/per_block_processing/verify_deposit.rs index 6f810ba84..b99204e77 100644 --- a/eth2/state_processing/src/per_block_processing/verify_deposit.rs +++ b/eth2/state_processing/src/per_block_processing/verify_deposit.rs @@ -100,7 +100,7 @@ fn verify_deposit_merkle_proof( let leaf = hash(&get_serialized_deposit_data(deposit)); verify_merkle_proof( Hash256::from_slice(&leaf), - &deposit.proof, + &deposit.proof[..], spec.deposit_contract_tree_depth as usize, deposit.index as usize, state.latest_eth1_data.deposit_root, diff --git a/eth2/state_processing/tests/tests.rs b/eth2/state_processing/tests/tests.rs deleted file mode 100644 index e80340e9a..000000000 --- a/eth2/state_processing/tests/tests.rs +++ /dev/null @@ -1,153 +0,0 @@ -#![cfg(not(debug_assertions))] - -use serde_derive::Deserialize; -use serde_yaml; -use state_processing::{per_block_processing, per_slot_processing}; -use std::{fs::File, io::prelude::*, path::PathBuf}; -use types::*; - -#[derive(Debug, Deserialize)] -pub struct ExpectedState { - pub slot: Option, - pub genesis_time: Option, - pub fork: Option, - pub validator_registry: Option>, - pub validator_balances: Option>, - pub previous_epoch_attestations: Option>, - pub current_epoch_attestations: Option>, - pub historical_roots: Option>, - pub finalized_epoch: Option, - pub latest_block_roots: Option>, -} - -impl ExpectedState { - // Return a list of fields that differ, and a string representation of the beacon state's field. - fn check(&self, state: &BeaconState) -> Vec<(&str, String)> { - // Check field equality - macro_rules! cfe { - ($field_name:ident) => { - if self.$field_name.as_ref().map_or(true, |$field_name| { - println!(" > Checking {}", stringify!($field_name)); - $field_name == &state.$field_name - }) { - vec![] - } else { - vec![(stringify!($field_name), format!("{:#?}", state.$field_name))] - } - }; - } - - vec![ - cfe!(slot), - cfe!(genesis_time), - cfe!(fork), - cfe!(validator_registry), - cfe!(validator_balances), - cfe!(previous_epoch_attestations), - cfe!(current_epoch_attestations), - cfe!(historical_roots), - cfe!(finalized_epoch), - cfe!(latest_block_roots), - ] - .into_iter() - .flat_map(|x| x) - .collect() - } -} - -#[derive(Debug, Deserialize)] -pub struct TestCase { - pub name: String, - pub config: ChainSpec, - pub verify_signatures: bool, - pub initial_state: BeaconState, - pub blocks: Vec, - pub expected_state: ExpectedState, -} - -#[derive(Debug, Deserialize)] -pub struct TestDoc { - pub title: String, - pub summary: String, - pub fork: String, - pub test_cases: Vec, -} - -fn load_test_case(test_name: &str) -> TestDoc { - let mut file = { - let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - file_path_buf.push(format!("yaml_utils/specs/{}", test_name)); - - File::open(file_path_buf).unwrap() - }; - let mut yaml_str = String::new(); - file.read_to_string(&mut yaml_str).unwrap(); - yaml_str = yaml_str.to_lowercase(); - - serde_yaml::from_str(&yaml_str.as_str()).unwrap() -} - -fn run_state_transition_test(test_name: &str) { - let doc = load_test_case(test_name); - - // Run Tests - let mut ok = true; - for (i, test_case) in doc.test_cases.iter().enumerate() { - let fake_crypto = cfg!(feature = "fake_crypto"); - if !test_case.verify_signatures == fake_crypto { - println!("Running {}", test_case.name); - } else { - println!( - "Skipping {} (fake_crypto: {}, need fake: {})", - test_case.name, fake_crypto, !test_case.verify_signatures - ); - continue; - } - let mut state = test_case.initial_state.clone(); - for (j, block) in test_case.blocks.iter().enumerate() { - while block.slot > state.slot { - per_slot_processing(&mut state, &test_case.config).unwrap(); - } - let res = per_block_processing(&mut state, &block, &test_case.config); - if res.is_err() { - println!("Error in {} (#{}), on block {}", test_case.name, i, j); - println!("{:?}", res); - ok = false; - } - } - - let mismatched_fields = test_case.expected_state.check(&state); - if !mismatched_fields.is_empty() { - println!( - "Error in expected state, these fields didn't match: {:?}", - mismatched_fields.iter().map(|(f, _)| f).collect::>() - ); - for (field_name, state_val) in mismatched_fields { - println!("state.{} was: {}", field_name, state_val); - } - ok = false; - } - } - - assert!(ok, "one or more tests failed, see above"); -} - -#[test] -#[cfg(not(debug_assertions))] -fn test_read_yaml() { - load_test_case("sanity-check_small-config_32-vals.yaml"); - load_test_case("sanity-check_default-config_100-vals.yaml"); -} - -#[test] -#[cfg(not(debug_assertions))] -fn run_state_transition_tests_small() { - run_state_transition_test("sanity-check_small-config_32-vals.yaml"); -} - -// Run with --ignored to run this test -#[test] -#[ignore] -fn run_state_transition_tests_large() { - run_state_transition_test("sanity-check_default-config_100-vals.yaml"); -} diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index f66591669..a3eedc803 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -1,8 +1,11 @@ use crate::*; use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192}; +use serde_derive::{Deserialize, Serialize}; use std::fmt::Debug; -pub trait BeaconStateTypes: 'static + Default + Sync + Send + Clone + Debug + PartialEq { +pub trait BeaconStateTypes: + 'static + Default + Sync + Send + Clone + Debug + PartialEq + serde::de::DeserializeOwned +{ type ShardCount: Unsigned + Clone + Sync + Send + Debug + PartialEq; type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send + Debug + PartialEq; type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; @@ -13,7 +16,7 @@ pub trait BeaconStateTypes: 'static + Default + Sync + Send + Clone + Debug + Pa } /// Ethereum Foundation specifications. -#[derive(Clone, PartialEq, Debug, Default)] +#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] pub struct FoundationStateTypes; impl BeaconStateTypes for FoundationStateTypes { @@ -30,7 +33,7 @@ impl BeaconStateTypes for FoundationStateTypes { pub type FoundationBeaconState = BeaconState; -#[derive(Clone, PartialEq, Debug, Default)] +#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] pub struct FewValidatorsStateTypes; impl BeaconStateTypes for FewValidatorsStateTypes { @@ -47,7 +50,7 @@ impl BeaconStateTypes for FewValidatorsStateTypes { pub type FewValidatorsBeaconState = BeaconState; -#[derive(Clone, PartialEq, Debug, Default)] +#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] pub struct LighthouseTestnetStateTypes; impl BeaconStateTypes for LighthouseTestnetStateTypes { diff --git a/eth2/types/src/deposit.rs b/eth2/types/src/deposit.rs index 1f5d90fab..67ceea5be 100644 --- a/eth2/types/src/deposit.rs +++ b/eth2/types/src/deposit.rs @@ -1,5 +1,6 @@ -use super::{DepositData, Hash256, TreeHashVector}; use crate::test_utils::TestRandom; +use crate::*; +use fixed_len_vec::typenum::U32; use serde_derive::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; @@ -22,7 +23,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash}; TestRandom, )] pub struct Deposit { - pub proof: TreeHashVector, + pub proof: FixedLenVec, pub index: u64, pub deposit_data: DepositData, } diff --git a/eth2/types/src/lib.rs b/eth2/types/src/lib.rs index 99e64e823..c6109e166 100644 --- a/eth2/types/src/lib.rs +++ b/eth2/types/src/lib.rs @@ -27,7 +27,7 @@ pub mod pending_attestation; pub mod proposer_slashing; pub mod slashable_attestation; pub mod transfer; -pub mod tree_hash_vector; +// pub mod tree_hash_vector; pub mod voluntary_exit; #[macro_use] pub mod slot_epoch_macros; @@ -66,7 +66,7 @@ pub use crate::slashable_attestation::SlashableAttestation; pub use crate::slot_epoch::{Epoch, Slot}; pub use crate::slot_height::SlotHeight; pub use crate::transfer::Transfer; -pub use crate::tree_hash_vector::TreeHashVector; +// pub use crate::tree_hash_vector::TreeHashVector; pub use crate::validator::Validator; pub use crate::voluntary_exit::VoluntaryExit; From be9f8aa0bf001ca99e9b8638f5756488e651eee6 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Fri, 10 May 2019 09:45:08 +1000 Subject: [PATCH 16/22] Fix `fork_choice` release-only tests --- eth2/fork_choice/src/bitwise_lmd_ghost.rs | 2 +- eth2/fork_choice/src/optimized_lmd_ghost.rs | 2 +- eth2/fork_choice/src/slow_lmd_ghost.rs | 2 +- eth2/fork_choice/tests/tests.rs | 33 +++++++++++++-------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/eth2/fork_choice/src/bitwise_lmd_ghost.rs b/eth2/fork_choice/src/bitwise_lmd_ghost.rs index 66100dbc1..7667b28b7 100644 --- a/eth2/fork_choice/src/bitwise_lmd_ghost.rs +++ b/eth2/fork_choice/src/bitwise_lmd_ghost.rs @@ -34,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 { } /// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm. -pub struct BitwiseLMDGhost { +pub struct BitwiseLMDGhost { /// A cache of known ancestors at given heights for a specific block. //TODO: Consider FnvHashMap cache: HashMap, Hash256>, diff --git a/eth2/fork_choice/src/optimized_lmd_ghost.rs b/eth2/fork_choice/src/optimized_lmd_ghost.rs index 3e43e2153..d2663b2b6 100644 --- a/eth2/fork_choice/src/optimized_lmd_ghost.rs +++ b/eth2/fork_choice/src/optimized_lmd_ghost.rs @@ -34,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 { } /// Stores the necessary data structures to run the optimised lmd ghost algorithm. -pub struct OptimizedLMDGhost { +pub struct OptimizedLMDGhost { /// A cache of known ancestors at given heights for a specific block. //TODO: Consider FnvHashMap cache: HashMap, Hash256>, diff --git a/eth2/fork_choice/src/slow_lmd_ghost.rs b/eth2/fork_choice/src/slow_lmd_ghost.rs index c621870d1..68c4ac5a6 100644 --- a/eth2/fork_choice/src/slow_lmd_ghost.rs +++ b/eth2/fork_choice/src/slow_lmd_ghost.rs @@ -13,7 +13,7 @@ use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot //TODO: Pruning and syncing -pub struct SlowLMDGhost { +pub struct SlowLMDGhost { /// The latest attestation targets as a map of validator index to block hash. //TODO: Could this be a fixed size vec latest_attestation_targets: HashMap, diff --git a/eth2/fork_choice/tests/tests.rs b/eth2/fork_choice/tests/tests.rs index fb530ac43..3addb8c0a 100644 --- a/eth2/fork_choice/tests/tests.rs +++ b/eth2/fork_choice/tests/tests.rs @@ -25,7 +25,10 @@ use std::collections::HashMap; use std::sync::Arc; use std::{fs::File, io::prelude::*, path::PathBuf}; use types::test_utils::TestingBeaconStateBuilder; -use types::{BeaconBlock, BeaconBlockBody, ChainSpec, Eth1Data, Hash256, Keypair, Slot}; +use types::{ + BeaconBlock, BeaconBlockBody, BeaconStateTypes, Eth1Data, FoundationStateTypes, Hash256, + Keypair, Slot, +}; use yaml_rust::yaml; // Note: We Assume the block Id's are hex-encoded. @@ -82,7 +85,7 @@ fn test_yaml_vectors( let test_cases = load_test_cases_from_yaml(yaml_file_path); // default vars - let spec = ChainSpec::foundation(); + let spec = FoundationStateTypes::spec(); let zero_hash = Hash256::zero(); let eth1_data = Eth1Data { deposit_root: zero_hash.clone(), @@ -227,23 +230,27 @@ fn setup_inital_state( // the fork choice instantiation let fork_choice: Box = match fork_choice_algo { - ForkChoiceAlgorithm::OptimizedLMDGhost => Box::new(OptimizedLMDGhost::new( - block_store.clone(), - state_store.clone(), - )), - ForkChoiceAlgorithm::BitwiseLMDGhost => Box::new(BitwiseLMDGhost::new( - block_store.clone(), - state_store.clone(), - )), + ForkChoiceAlgorithm::OptimizedLMDGhost => { + let f: OptimizedLMDGhost = + OptimizedLMDGhost::new(block_store.clone(), state_store.clone()); + Box::new(f) + } + ForkChoiceAlgorithm::BitwiseLMDGhost => { + let f: BitwiseLMDGhost = + BitwiseLMDGhost::new(block_store.clone(), state_store.clone()); + Box::new(f) + } ForkChoiceAlgorithm::SlowLMDGhost => { - Box::new(SlowLMDGhost::new(block_store.clone(), state_store.clone())) + let f: SlowLMDGhost = + SlowLMDGhost::new(block_store.clone(), state_store.clone()); + Box::new(f) } ForkChoiceAlgorithm::LongestChain => Box::new(LongestChain::new(block_store.clone())), }; - let spec = ChainSpec::foundation(); + let spec = FoundationStateTypes::spec(); - let mut state_builder = + let mut state_builder: TestingBeaconStateBuilder = TestingBeaconStateBuilder::from_single_keypair(num_validators, &Keypair::random(), &spec); state_builder.build_caches(&spec).unwrap(); let (state, _keypairs) = state_builder.build(); From 3115bf7d367ed736215b397207fabffb60a67c09 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Fri, 10 May 2019 09:45:28 +1000 Subject: [PATCH 17/22] Fix `operation_pool` release-only tests --- eth2/operation_pool/src/lib.rs | 81 +++++++++++++++++----------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/eth2/operation_pool/src/lib.rs b/eth2/operation_pool/src/lib.rs index 961228d56..5a82fd3f1 100644 --- a/eth2/operation_pool/src/lib.rs +++ b/eth2/operation_pool/src/lib.rs @@ -716,47 +716,46 @@ mod tests { (spec, state) } - /// Create a signed attestation for use in tests. - /// Signed by all validators in `committee[signing_range]` and `committee[extra_signer]`. - // #[cfg(not(debug_assertions))] - fn signed_attestation< - R: std::slice::SliceIndex<[usize], Output = [usize]>, - B: BeaconStateTypes, - >( - committee: &CrosslinkCommittee, - keypairs: &[Keypair], - signing_range: R, - slot: Slot, - state: &BeaconState, - spec: &ChainSpec, - extra_signer: Option, - ) -> Attestation { - let mut builder = TestingAttestationBuilder::new( - state, - &committee.committee, - slot, - committee.shard, - spec, - ); - let signers = &committee.committee[signing_range]; - let committee_keys = signers.iter().map(|&i| &keypairs[i].sk).collect::>(); - builder.sign(signers, &committee_keys, &state.fork, spec); - extra_signer.map(|c_idx| { - let validator_index = committee.committee[c_idx]; - builder.sign( - &[validator_index], - &[&keypairs[validator_index].sk], - &state.fork, - spec, - ) - }); - builder.build() - } - #[cfg(not(debug_assertions))] mod release_tests { use super::*; + /// Create a signed attestation for use in tests. + /// Signed by all validators in `committee[signing_range]` and `committee[extra_signer]`. + fn signed_attestation< + R: std::slice::SliceIndex<[usize], Output = [usize]>, + B: BeaconStateTypes, + >( + committee: &CrosslinkCommittee, + keypairs: &[Keypair], + signing_range: R, + slot: Slot, + state: &BeaconState, + spec: &ChainSpec, + extra_signer: Option, + ) -> Attestation { + let mut builder = TestingAttestationBuilder::new( + state, + &committee.committee, + slot, + committee.shard, + spec, + ); + let signers = &committee.committee[signing_range]; + let committee_keys = signers.iter().map(|&i| &keypairs[i].sk).collect::>(); + builder.sign(signers, &committee_keys, &state.fork, spec); + extra_signer.map(|c_idx| { + let validator_index = committee.committee[c_idx]; + builder.sign( + &[validator_index], + &[&keypairs[validator_index].sk], + &state.fork, + spec, + ) + }); + builder.build() + } + /// Test state for attestation-related tests. fn attestation_test_state( num_committees: usize, @@ -779,7 +778,7 @@ mod tests { } /// Set the latest crosslink in the state to match the attestation. - fn fake_latest_crosslink( + fn fake_latest_crosslink( att: &Attestation, state: &mut BeaconState, spec: &ChainSpec, @@ -960,10 +959,12 @@ mod tests { /// are also signed by the 0th member of the committee. #[test] fn attestation_get_max() { - let spec = &ChainSpec::foundation(); let small_step_size = 2; let big_step_size = 4; - let (ref mut state, ref keypairs) = attestation_test_state(spec, big_step_size); + + let (ref mut state, ref keypairs, ref spec) = + attestation_test_state::(big_step_size); + let op_pool = OperationPool::new(); let slot = state.slot - 1; From 59883603ac3017a0e6d718f5494aa4c12acba1e5 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Fri, 10 May 2019 10:28:18 +1000 Subject: [PATCH 18/22] Remove `state_processing` tests, update travis --- .travis.yml | 28 +------------------ Cargo.toml | 1 - eth2/state_processing/Cargo.toml | 4 --- eth2/state_processing/build.rs | 1 - eth2/state_processing/yaml_utils/Cargo.toml | 14 ---------- eth2/state_processing/yaml_utils/build.rs | 27 ------------------ .../yaml_utils/expected_state_fields.py | 15 ---------- .../yaml_utils/specs/.gitignore | 1 - eth2/state_processing/yaml_utils/src/lib.rs | 1 - 9 files changed, 1 insertion(+), 91 deletions(-) delete mode 120000 eth2/state_processing/build.rs delete mode 100644 eth2/state_processing/yaml_utils/Cargo.toml delete mode 100644 eth2/state_processing/yaml_utils/build.rs delete mode 100755 eth2/state_processing/yaml_utils/expected_state_fields.py delete mode 100644 eth2/state_processing/yaml_utils/specs/.gitignore delete mode 100644 eth2/state_processing/yaml_utils/src/lib.rs diff --git a/.travis.yml b/.travis.yml index d0b2ee0e4..3662e17cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,6 @@ language: rust cache: directories: - /home/travis/.cargo -# Going to try caching the registry -#before_cache: -# - rm -rf /home/travis/.cargo/registry before_install: - curl -OL https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-linux-x86_64.zip - unzip protoc-3.4.0-linux-x86_64.zip -d protoc3 @@ -12,37 +9,14 @@ before_install: - sudo mv protoc3/include/* /usr/local/include/ - sudo chown $USER /usr/local/bin/protoc - sudo chown -R $USER /usr/local/include/google -env: - - BUILD=--all -# Not building --release on travis any more, only GitLab -# - BUILD=--release --all - - BUILD= --manifest-path eth2/state_processing/Cargo.toml --release --features fake_crypto script: - - cargo build --verbose $BUILD - - cargo test --verbose $BUILD - - cargo fmt --all -- --check - # No clippy until later... - #- cargo clippy + - cargo build --verbose --all --release rust: - - stable - beta - nightly matrix: allow_failures: - rust: nightly fast_finish: true - exclude: -# Not building --release on travis any more, only GitLab -# - rust: beta -# env: BUILD=--release --all - - rust: beta - env: BUILD= --manifest-path eth2/state_processing/Cargo.toml --release --features fake_crypto -# Not building --release on travis any more, only GitLab -# - rust: nightly -# env: BUILD=--release --all - - rust: nightly - env: BUILD= --manifest-path eth2/state_processing/Cargo.toml --release --features fake_crypto install: - rustup component add rustfmt -# No clippy for now -# - rustup component add clippy diff --git a/Cargo.toml b/Cargo.toml index eb472c346..893189941 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ members = [ "eth2/fork_choice", "eth2/operation_pool", "eth2/state_processing", - "eth2/state_processing/yaml_utils", "eth2/types", "eth2/utils/bls", "eth2/utils/boolean-bitfield", diff --git a/eth2/state_processing/Cargo.toml b/eth2/state_processing/Cargo.toml index a2ae11aa8..4b031022a 100644 --- a/eth2/state_processing/Cargo.toml +++ b/eth2/state_processing/Cargo.toml @@ -14,7 +14,6 @@ env_logger = "0.6.0" serde = "1.0" serde_derive = "1.0" serde_yaml = "0.8" -yaml-utils = { path = "yaml_utils" } [dependencies] bls = { path = "../utils/bls" } @@ -30,6 +29,3 @@ tree_hash = { path = "../utils/tree_hash" } tree_hash_derive = { path = "../utils/tree_hash_derive" } types = { path = "../types" } rayon = "1.0" - -[features] -fake_crypto = ["bls/fake_crypto"] diff --git a/eth2/state_processing/build.rs b/eth2/state_processing/build.rs deleted file mode 120000 index 70d6c75b9..000000000 --- a/eth2/state_processing/build.rs +++ /dev/null @@ -1 +0,0 @@ -../utils/bls/build.rs \ No newline at end of file diff --git a/eth2/state_processing/yaml_utils/Cargo.toml b/eth2/state_processing/yaml_utils/Cargo.toml deleted file mode 100644 index 5f216fe1a..000000000 --- a/eth2/state_processing/yaml_utils/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "yaml-utils" -version = "0.1.0" -authors = ["Kirk Baird "] -edition = "2018" - -[build-dependencies] -reqwest = "0.9" - -[dependencies] - -[lib] -name = "yaml_utils" -path = "src/lib.rs" diff --git a/eth2/state_processing/yaml_utils/build.rs b/eth2/state_processing/yaml_utils/build.rs deleted file mode 100644 index 7fb652cc1..000000000 --- a/eth2/state_processing/yaml_utils/build.rs +++ /dev/null @@ -1,27 +0,0 @@ -extern crate reqwest; - -use std::fs::File; -use std::io::copy; - -fn main() { - // These test files are not to be stored in the lighthouse repo as they are quite large (32MB). - // They will be downloaded at build time by yaml-utils crate (in build.rs) - let git_path = "https://raw.githubusercontent.com/ethereum/eth2.0-tests/master/state/"; - let test_names = vec![ - "sanity-check_default-config_100-vals.yaml", - "sanity-check_small-config_32-vals.yaml", - ]; - - for test in test_names { - let mut target = String::from(git_path); - target.push_str(test); - let mut response = reqwest::get(target.as_str()).unwrap(); - - let mut dest = { - let mut file_name = String::from("specs/"); - file_name.push_str(test); - File::create(file_name).unwrap() - }; - copy(&mut response, &mut dest).unwrap(); - } -} diff --git a/eth2/state_processing/yaml_utils/expected_state_fields.py b/eth2/state_processing/yaml_utils/expected_state_fields.py deleted file mode 100755 index df4cb83f7..000000000 --- a/eth2/state_processing/yaml_utils/expected_state_fields.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python3 - -# Script to extract all the fields of the state mentioned in `expected_state` fields of tests -# in the `spec` directory. These fields can then be added to the `ExpectedState` struct. -# Might take a while to run. - -import os, yaml - -if __name__ == "__main__": - yaml_files = (filename for filename in os.listdir("specs") if filename.endswith(".yaml")) - parsed_yaml = (yaml.load(open("specs/" + filename, "r")) for filename in yaml_files) - all_fields = set() - for y in parsed_yaml: - all_fields.update(*({key for key in case["expected_state"]} for case in y["test_cases"])) - print(all_fields) diff --git a/eth2/state_processing/yaml_utils/specs/.gitignore b/eth2/state_processing/yaml_utils/specs/.gitignore deleted file mode 100644 index 1e82fc7de..000000000 --- a/eth2/state_processing/yaml_utils/specs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.yaml diff --git a/eth2/state_processing/yaml_utils/src/lib.rs b/eth2/state_processing/yaml_utils/src/lib.rs deleted file mode 100644 index 644ea434b..000000000 --- a/eth2/state_processing/yaml_utils/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -// This is a place holder such that yaml-utils is now a crate hence build.rs will be run when 'cargo test' is called From 75b310a07894ce6e01e2f984850f40c7ef31b1cd Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Fri, 10 May 2019 11:23:19 +1000 Subject: [PATCH 19/22] Add convenience methods to `BeaconStateTypes` --- .../src/beacon_state/beacon_state_types.rs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index a3eedc803..8f0f6d524 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -13,9 +13,46 @@ pub trait BeaconStateTypes: type LatestSlashedExitLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; fn spec() -> ChainSpec; + + /// Returns the `SHARD_COUNT` constant for this specification. + /// + /// Spec v0.5.1 + fn shard_count() -> usize { + Self::ShardCount::to_usize() + } + + /// Returns the `SLOTS_PER_HISTORICAL_ROOT` constant for this specification. + /// + /// Spec v0.5.1 + fn slots_per_historical_root() -> usize { + Self::SlotsPerHistoricalRoot::to_usize() + } + + /// Returns the `LATEST_RANDAO_MIXES_LENGTH` constant for this specification. + /// + /// Spec v0.5.1 + fn latest_randao_mixes_length() -> usize { + Self::LatestRandaoMixesLength::to_usize() + } + + /// Returns the `LATEST_ACTIVE_INDEX_ROOTS` constant for this specification. + /// + /// Spec v0.5.1 + fn latest_active_index_roots() -> usize { + Self::LatestActiveIndexRootsLength::to_usize() + } + + /// Returns the `LATEST_SLASHED_EXIT_LENGTH` constant for this specification. + /// + /// Spec v0.5.1 + fn latest_slashed_exit_length() -> usize { + Self::LatestSlashedExitLength::to_usize() + } } /// Ethereum Foundation specifications. +/// +/// Spec v0.5.1 #[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] pub struct FoundationStateTypes; @@ -33,6 +70,9 @@ impl BeaconStateTypes for FoundationStateTypes { pub type FoundationBeaconState = BeaconState; +/// Ethereum Foundation specifications, modified to be suitable for < 1000 validators. +/// +/// Spec v0.5.1 #[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] pub struct FewValidatorsStateTypes; @@ -50,6 +90,9 @@ impl BeaconStateTypes for FewValidatorsStateTypes { pub type FewValidatorsBeaconState = BeaconState; +/// Specifications suitable for a small-scale (< 1000 validators) lighthouse testnet. +/// +/// Spec v0.5.1 #[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] pub struct LighthouseTestnetStateTypes; From ce8ebeccbc2091536725030fdd4dbafc576004c9 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Fri, 10 May 2019 14:47:09 +1000 Subject: [PATCH 20/22] Rename `BeaconStateTypes` to `EthSpec` --- beacon_node/beacon_chain/src/beacon_chain.rs | 4 +- beacon_node/beacon_chain/src/checkpoint.rs | 6 +-- beacon_node/beacon_chain/src/initialise.rs | 10 ++-- .../testing_beacon_chain_builder.rs | 10 ++-- beacon_node/client/src/client_config.rs | 4 +- beacon_node/client/src/client_types.rs | 18 +++---- beacon_node/client/src/lib.rs | 8 ++-- .../db/src/stores/beacon_state_store.rs | 4 +- beacon_node/eth2-libp2p/src/behaviour.rs | 2 +- beacon_node/network/src/beacon_chain.rs | 7 ++- beacon_node/network/src/message_handler.rs | 6 +-- beacon_node/network/src/service.rs | 6 +-- beacon_node/network/src/sync/import_queue.rs | 6 +-- beacon_node/network/src/sync/simple_sync.rs | 8 ++-- beacon_node/rpc/src/attestation.rs | 6 +-- beacon_node/rpc/src/beacon_block.rs | 6 +-- beacon_node/rpc/src/beacon_chain.rs | 6 +-- beacon_node/rpc/src/beacon_node.rs | 6 +-- beacon_node/rpc/src/lib.rs | 4 +- beacon_node/rpc/src/validator.rs | 6 +-- eth2/fork_choice/src/bitwise_lmd_ghost.rs | 6 +-- eth2/fork_choice/src/optimized_lmd_ghost.rs | 6 +-- eth2/fork_choice/src/slow_lmd_ghost.rs | 6 +-- eth2/fork_choice/tests/tests.rs | 15 +++--- eth2/operation_pool/src/lib.rs | 47 +++++++++---------- .../src/common/exit_validator.rs | 2 +- .../src/common/slash_validator.rs | 2 +- .../state_processing/src/get_genesis_state.rs | 2 +- .../src/per_block_processing.rs | 26 +++++----- .../validate_attestation.rs | 12 ++--- .../verify_attester_slashing.rs | 6 +-- .../per_block_processing/verify_deposit.rs | 8 ++-- .../src/per_block_processing/verify_exit.rs | 6 +-- .../verify_proposer_slashing.rs | 2 +- .../verify_slashable_attestation.rs | 2 +- .../per_block_processing/verify_transfer.rs | 8 ++-- .../src/per_epoch_processing.rs | 10 ++-- .../src/per_epoch_processing/apply_rewards.rs | 14 +++--- .../get_attestation_participants.rs | 2 +- .../inclusion_distance.rs | 6 +-- .../per_epoch_processing/process_ejections.rs | 2 +- .../process_exit_queue.rs | 4 +- .../per_epoch_processing/process_slashings.rs | 2 +- .../src/per_epoch_processing/tests.rs | 4 +- .../update_registry_and_shuffling_data.rs | 8 ++-- .../validator_statuses.rs | 10 ++-- .../src/per_epoch_processing/winning_root.rs | 6 +-- .../src/per_slot_processing.rs | 7 +-- eth2/types/src/beacon_state.rs | 4 +- .../src/beacon_state/beacon_state_types.rs | 20 ++++---- eth2/types/src/beacon_state/epoch_cache.rs | 8 ++-- .../src/beacon_state/epoch_cache/tests.rs | 21 ++++----- eth2/types/src/beacon_state/tests.rs | 8 ++-- eth2/types/src/historical_batch.rs | 4 +- .../test_utils/testing_attestation_builder.rs | 2 +- .../testing_attestation_data_builder.rs | 2 +- .../testing_beacon_block_builder.rs | 8 ++-- .../testing_beacon_state_builder.rs | 4 +- .../testing_pending_attestation_builder.rs | 2 +- validator_client/src/config.rs | 11 ++--- 60 files changed, 223 insertions(+), 235 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 2b2d5f015..b6eb1d2f7 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -83,7 +83,7 @@ impl BlockProcessingOutcome { } } -pub struct BeaconChain { +pub struct BeaconChain { pub block_store: Arc>, pub state_store: Arc>, pub slot_clock: U, @@ -100,7 +100,7 @@ where T: ClientDB, U: SlotClock, F: ForkChoice, - B: BeaconStateTypes, + B: EthSpec, { /// Instantiate a new Beacon Chain, from genesis. pub fn from_genesis( diff --git a/beacon_node/beacon_chain/src/checkpoint.rs b/beacon_node/beacon_chain/src/checkpoint.rs index c3757949f..7bed5b5ce 100644 --- a/beacon_node/beacon_chain/src/checkpoint.rs +++ b/beacon_node/beacon_chain/src/checkpoint.rs @@ -1,17 +1,17 @@ use serde_derive::Serialize; -use types::{BeaconBlock, BeaconState, BeaconStateTypes, Hash256}; +use types::{BeaconBlock, BeaconState, EthSpec, Hash256}; /// Represents some block and it's associated state. Generally, this will be used for tracking the /// head, justified head and finalized head. #[derive(Clone, Serialize, PartialEq, Debug)] -pub struct CheckPoint { +pub struct CheckPoint { pub beacon_block: BeaconBlock, pub beacon_block_root: Hash256, pub beacon_state: BeaconState, pub beacon_state_root: Hash256, } -impl CheckPoint { +impl CheckPoint { /// Create a new checkpoint. pub fn new( beacon_block: BeaconBlock, diff --git a/beacon_node/beacon_chain/src/initialise.rs b/beacon_node/beacon_chain/src/initialise.rs index 284393c02..83b60a4f7 100644 --- a/beacon_node/beacon_chain/src/initialise.rs +++ b/beacon_node/beacon_chain/src/initialise.rs @@ -11,7 +11,7 @@ use std::path::PathBuf; use std::sync::Arc; use tree_hash::TreeHash; use types::test_utils::TestingBeaconStateBuilder; -use types::{BeaconBlock, ChainSpec, FewValidatorsStateTypes, FoundationStateTypes, Hash256}; +use types::{BeaconBlock, ChainSpec, FewValidatorsEthSpec, FoundationEthSpec, Hash256}; //TODO: Correct this for prod //TODO: Account for historical db @@ -22,8 +22,8 @@ pub fn initialise_beacon_chain( BeaconChain< DiskDB, SystemTimeSlotClock, - BitwiseLMDGhost, - FoundationStateTypes, + BitwiseLMDGhost, + FoundationEthSpec, >, > { // set up the db @@ -75,8 +75,8 @@ pub fn initialise_test_beacon_chain( BeaconChain< MemoryDB, SystemTimeSlotClock, - BitwiseLMDGhost, - FewValidatorsStateTypes, + BitwiseLMDGhost, + FewValidatorsEthSpec, >, > { let db = Arc::new(MemoryDB::open()); diff --git a/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs b/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs index 9f9838ae7..b617ed0d7 100644 --- a/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs +++ b/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs @@ -8,16 +8,16 @@ use slot_clock::TestingSlotClock; use std::sync::Arc; use tree_hash::TreeHash; use types::*; -use types::{test_utils::TestingBeaconStateBuilder, BeaconStateTypes, FewValidatorsStateTypes}; +use types::{test_utils::TestingBeaconStateBuilder, EthSpec, FewValidatorsEthSpec}; type TestingBeaconChain = - BeaconChain, B>; + BeaconChain, B>; -pub struct TestingBeaconChainBuilder { +pub struct TestingBeaconChainBuilder { state_builder: TestingBeaconStateBuilder, } -impl TestingBeaconChainBuilder { +impl TestingBeaconChainBuilder { pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain { let db = Arc::new(MemoryDB::open()); let block_store = Arc::new(BeaconBlockStore::new(db.clone())); @@ -44,7 +44,7 @@ impl TestingBeaconChainBuilder { } } -impl From> for TestingBeaconChainBuilder { +impl From> for TestingBeaconChainBuilder { fn from(state_builder: TestingBeaconStateBuilder) -> TestingBeaconChainBuilder { TestingBeaconChainBuilder { state_builder } } diff --git a/beacon_node/client/src/client_config.rs b/beacon_node/client/src/client_config.rs index 74ef5f2e5..d84b63f4f 100644 --- a/beacon_node/client/src/client_config.rs +++ b/beacon_node/client/src/client_config.rs @@ -10,7 +10,7 @@ use std::path::PathBuf; use types::multiaddr::Protocol; use types::multiaddr::ToMultiaddr; use types::Multiaddr; -use types::{BeaconStateTypes, ChainSpec, LighthouseTestnetStateTypes}; +use types::{ChainSpec, EthSpec, LighthouseTestnetEthSpec}; /// Stores the client configuration for this Lighthouse instance. #[derive(Debug, Clone)] @@ -35,7 +35,7 @@ impl Default for ClientConfig { fs::create_dir_all(&data_dir) .unwrap_or_else(|_| panic!("Unable to create {:?}", &data_dir)); - let default_spec = LighthouseTestnetStateTypes::spec(); + let default_spec = LighthouseTestnetEthSpec::spec(); let default_net_conf = NetworkConfig::new(default_spec.boot_nodes.clone()); Self { diff --git a/beacon_node/client/src/client_types.rs b/beacon_node/client/src/client_types.rs index ba8fc47de..8c9352d7c 100644 --- a/beacon_node/client/src/client_types.rs +++ b/beacon_node/client/src/client_types.rs @@ -6,17 +6,17 @@ use beacon_chain::{ slot_clock::{SlotClock, SystemTimeSlotClock}, }; use fork_choice::ForkChoice; -use types::{BeaconStateTypes, FewValidatorsStateTypes, FoundationStateTypes}; +use types::{EthSpec, FewValidatorsEthSpec, FoundationEthSpec}; pub trait ClientTypes { type DB: ClientDB + 'static; type SlotClock: SlotClock + 'static; type ForkChoice: ForkChoice + 'static; - type BeaconStateTypes: BeaconStateTypes + 'static; + type EthSpec: EthSpec + 'static; fn initialise_beacon_chain( config: &ClientConfig, - ) -> ArcBeaconChain; + ) -> ArcBeaconChain; } pub struct StandardClientType; @@ -24,12 +24,12 @@ pub struct StandardClientType; impl ClientTypes for StandardClientType { type DB = DiskDB; type SlotClock = SystemTimeSlotClock; - type ForkChoice = BitwiseLMDGhost; - type BeaconStateTypes = FoundationStateTypes; + type ForkChoice = BitwiseLMDGhost; + type EthSpec = FoundationEthSpec; fn initialise_beacon_chain( config: &ClientConfig, - ) -> ArcBeaconChain { + ) -> ArcBeaconChain { initialise::initialise_beacon_chain(&config.spec, Some(&config.db_name)) } } @@ -39,12 +39,12 @@ pub struct TestingClientType; impl ClientTypes for TestingClientType { type DB = MemoryDB; type SlotClock = SystemTimeSlotClock; - type ForkChoice = BitwiseLMDGhost; - type BeaconStateTypes = FewValidatorsStateTypes; + type ForkChoice = BitwiseLMDGhost; + type EthSpec = FewValidatorsEthSpec; fn initialise_beacon_chain( config: &ClientConfig, - ) -> ArcBeaconChain { + ) -> ArcBeaconChain { initialise::initialise_test_beacon_chain(&config.spec, None) } } diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index c3dd5cbd8..166f1a948 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use tokio::runtime::TaskExecutor; use tokio::timer::Interval; -use types::BeaconStateTypes; +use types::EthSpec; type ArcBeaconChain = Arc>; @@ -30,9 +30,9 @@ pub struct Client { /// Configuration for the lighthouse client. _config: ClientConfig, /// The beacon chain for the running client. - _beacon_chain: ArcBeaconChain, + _beacon_chain: ArcBeaconChain, /// Reference to the network service. - pub network: Arc>, + pub network: Arc>, /// Signal to terminate the RPC server. pub rpc_exit_signal: Option, /// Signal to terminate the slot timer. @@ -149,7 +149,7 @@ where T: ClientDB, U: SlotClock, F: ForkChoice, - B: BeaconStateTypes, + B: EthSpec, { if let Some(genesis_height) = chain.slots_since_genesis() { let result = chain.catchup_state(); diff --git a/beacon_node/db/src/stores/beacon_state_store.rs b/beacon_node/db/src/stores/beacon_state_store.rs index 4c40d2287..c0d37edd9 100644 --- a/beacon_node/db/src/stores/beacon_state_store.rs +++ b/beacon_node/db/src/stores/beacon_state_store.rs @@ -2,7 +2,7 @@ use super::STATES_DB_COLUMN as DB_COLUMN; use super::{ClientDB, DBError}; use ssz::decode; use std::sync::Arc; -use types::{BeaconState, BeaconStateTypes, Hash256}; +use types::{BeaconState, EthSpec, Hash256}; pub struct BeaconStateStore where @@ -19,7 +19,7 @@ impl BeaconStateStore { Self { db } } - pub fn get_deserialized( + pub fn get_deserialized( &self, hash: &Hash256, ) -> Result>, DBError> { diff --git a/beacon_node/eth2-libp2p/src/behaviour.rs b/beacon_node/eth2-libp2p/src/behaviour.rs index f8a0a7249..00e6fc533 100644 --- a/beacon_node/eth2-libp2p/src/behaviour.rs +++ b/beacon_node/eth2-libp2p/src/behaviour.rs @@ -236,7 +236,7 @@ mod test { #[test] fn ssz_encoding() { - let original = PubsubMessage::Block(BeaconBlock::empty(&FoundationStateTypes::spec())); + let original = PubsubMessage::Block(BeaconBlock::empty(&FoundationEthSpec::spec())); let encoded = ssz_encode(&original); diff --git a/beacon_node/network/src/beacon_chain.rs b/beacon_node/network/src/beacon_chain.rs index 2ab446c52..db809086a 100644 --- a/beacon_node/network/src/beacon_chain.rs +++ b/beacon_node/network/src/beacon_chain.rs @@ -9,14 +9,13 @@ use beacon_chain::{ }; use eth2_libp2p::rpc::HelloMessage; use types::{ - Attestation, BeaconBlock, BeaconBlockBody, BeaconBlockHeader, BeaconStateTypes, Epoch, Hash256, - Slot, + Attestation, BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Epoch, EthSpec, Hash256, Slot, }; pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome, InvalidBlock}; /// The network's API to the beacon chain. -pub trait BeaconChain: Send + Sync { +pub trait BeaconChain: Send + Sync { fn get_spec(&self) -> &ChainSpec; fn get_state(&self) -> RwLockReadGuard>; @@ -70,7 +69,7 @@ where T: ClientDB + Sized, U: SlotClock, F: ForkChoice, - B: BeaconStateTypes, + B: EthSpec, { fn get_spec(&self) -> &ChainSpec { &self.spec diff --git a/beacon_node/network/src/message_handler.rs b/beacon_node/network/src/message_handler.rs index 6d3348910..35743fe15 100644 --- a/beacon_node/network/src/message_handler.rs +++ b/beacon_node/network/src/message_handler.rs @@ -13,7 +13,7 @@ use slog::{debug, warn}; use std::collections::HashMap; use std::sync::Arc; use std::time::Instant; -use types::BeaconStateTypes; +use types::EthSpec; /// Timeout for RPC requests. // const REQUEST_TIMEOUT: Duration = Duration::from_secs(30); @@ -21,7 +21,7 @@ use types::BeaconStateTypes; // const HELLO_TIMEOUT: Duration = Duration::from_secs(30); /// Handles messages received from the network and client and organises syncing. -pub struct MessageHandler { +pub struct MessageHandler { /// Currently loaded and initialised beacon chain. _chain: Arc>, /// The syncing framework. @@ -45,7 +45,7 @@ pub enum HandlerMessage { PubsubMessage(PeerId, Box), } -impl MessageHandler { +impl MessageHandler { /// Initializes and runs the MessageHandler. pub fn spawn( beacon_chain: Arc>, diff --git a/beacon_node/network/src/service.rs b/beacon_node/network/src/service.rs index b7c6e58ec..89d1e1526 100644 --- a/beacon_node/network/src/service.rs +++ b/beacon_node/network/src/service.rs @@ -13,10 +13,10 @@ use slog::{debug, info, o, trace}; use std::marker::PhantomData; use std::sync::Arc; use tokio::runtime::TaskExecutor; -use types::{BeaconStateTypes, Topic}; +use types::{EthSpec, Topic}; /// Service that handles communication between internal services and the eth2_libp2p network service. -pub struct Service { +pub struct Service { //libp2p_service: Arc>, _libp2p_exit: oneshot::Sender<()>, network_send: crossbeam_channel::Sender, @@ -24,7 +24,7 @@ pub struct Service { //message_handler_send: Sender } -impl Service { +impl Service { pub fn new( beacon_chain: Arc>, config: &NetworkConfig, diff --git a/beacon_node/network/src/sync/import_queue.rs b/beacon_node/network/src/sync/import_queue.rs index 418b5c1b0..1fffd8763 100644 --- a/beacon_node/network/src/sync/import_queue.rs +++ b/beacon_node/network/src/sync/import_queue.rs @@ -5,7 +5,7 @@ use slog::{debug, error}; use std::sync::Arc; use std::time::{Duration, Instant}; use tree_hash::TreeHash; -use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, BeaconStateTypes, Hash256, Slot}; +use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, EthSpec, Hash256, Slot}; /// Provides a queue for fully and partially built `BeaconBlock`s. /// @@ -19,7 +19,7 @@ use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, BeaconStateTypes, H /// `BeaconBlockBody` as the key. /// - It is possible for multiple distinct blocks to have identical `BeaconBlockBodies`. Therefore /// we cannot use a `HashMap` keyed by the root of `BeaconBlockBody`. -pub struct ImportQueue { +pub struct ImportQueue { pub chain: Arc>, /// Partially imported blocks, keyed by the root of `BeaconBlockBody`. pub partials: Vec, @@ -29,7 +29,7 @@ pub struct ImportQueue { log: slog::Logger, } -impl ImportQueue { +impl ImportQueue { /// Return a new, empty queue. pub fn new(chain: Arc>, stale_time: Duration, log: slog::Logger) -> Self { Self { diff --git a/beacon_node/network/src/sync/simple_sync.rs b/beacon_node/network/src/sync/simple_sync.rs index c54a24678..3f4fb7aae 100644 --- a/beacon_node/network/src/sync/simple_sync.rs +++ b/beacon_node/network/src/sync/simple_sync.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; use tree_hash::TreeHash; -use types::{Attestation, BeaconBlock, BeaconStateTypes, Epoch, Hash256, Slot}; +use types::{Attestation, BeaconBlock, Epoch, EthSpec, Hash256, Slot}; /// The number of slots that we can import blocks ahead of us, before going into full Sync mode. const SLOT_IMPORT_TOLERANCE: u64 = 100; @@ -88,7 +88,7 @@ impl From for PeerSyncInfo { } } -impl From<&Arc>> for PeerSyncInfo { +impl From<&Arc>> for PeerSyncInfo { fn from(chain: &Arc>) -> PeerSyncInfo { Self::from(chain.hello_message()) } @@ -103,7 +103,7 @@ pub enum SyncState { } /// Simple Syncing protocol. -pub struct SimpleSync { +pub struct SimpleSync { /// A reference to the underlying beacon chain. chain: Arc>, /// A mapping of Peers to their respective PeerSyncInfo. @@ -116,7 +116,7 @@ pub struct SimpleSync { log: slog::Logger, } -impl SimpleSync { +impl SimpleSync { /// Instantiate a `SimpleSync` instance, with no peers and an empty queue. pub fn new(beacon_chain: Arc>, log: &slog::Logger) -> Self { let sync_logger = log.new(o!("Service"=> "Sync")); diff --git a/beacon_node/rpc/src/attestation.rs b/beacon_node/rpc/src/attestation.rs index eab6a8cd1..30f04afba 100644 --- a/beacon_node/rpc/src/attestation.rs +++ b/beacon_node/rpc/src/attestation.rs @@ -9,15 +9,15 @@ use protos::services_grpc::AttestationService; use slog::{error, info, trace, warn}; use ssz::{ssz_encode, Decodable}; use std::sync::Arc; -use types::{Attestation, BeaconStateTypes}; +use types::{Attestation, EthSpec}; #[derive(Clone)] -pub struct AttestationServiceInstance { +pub struct AttestationServiceInstance { pub chain: Arc>, pub log: slog::Logger, } -impl AttestationService for AttestationServiceInstance { +impl AttestationService for AttestationServiceInstance { /// Produce the `AttestationData` for signing by a validator. fn produce_attestation_data( &mut self, diff --git a/beacon_node/rpc/src/beacon_block.rs b/beacon_node/rpc/src/beacon_block.rs index fb6a08acc..727da9542 100644 --- a/beacon_node/rpc/src/beacon_block.rs +++ b/beacon_node/rpc/src/beacon_block.rs @@ -13,16 +13,16 @@ use slog::Logger; use slog::{error, info, trace, warn}; use ssz::{ssz_encode, Decodable}; use std::sync::Arc; -use types::{BeaconBlock, BeaconStateTypes, Signature, Slot}; +use types::{BeaconBlock, EthSpec, Signature, Slot}; #[derive(Clone)] -pub struct BeaconBlockServiceInstance { +pub struct BeaconBlockServiceInstance { pub chain: Arc>, pub network_chan: crossbeam_channel::Sender, pub log: Logger, } -impl BeaconBlockService for BeaconBlockServiceInstance { +impl BeaconBlockService for BeaconBlockServiceInstance { /// Produce a `BeaconBlock` for signing by a validator. fn produce_beacon_block( &mut self, diff --git a/beacon_node/rpc/src/beacon_chain.rs b/beacon_node/rpc/src/beacon_chain.rs index 9456c8857..e10522d04 100644 --- a/beacon_node/rpc/src/beacon_chain.rs +++ b/beacon_node/rpc/src/beacon_chain.rs @@ -8,10 +8,10 @@ use beacon_chain::{ AttestationValidationError, BlockProductionError, }; pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome}; -use types::{Attestation, AttestationData, BeaconBlock, BeaconStateTypes}; +use types::{Attestation, AttestationData, BeaconBlock, EthSpec}; /// The RPC's API to the beacon chain. -pub trait BeaconChain: Send + Sync { +pub trait BeaconChain: Send + Sync { fn get_spec(&self) -> &ChainSpec; fn get_state(&self) -> RwLockReadGuard>; @@ -39,7 +39,7 @@ where T: ClientDB + Sized, U: SlotClock, F: ForkChoice, - B: BeaconStateTypes, + B: EthSpec, { fn get_spec(&self) -> &ChainSpec { &self.spec diff --git a/beacon_node/rpc/src/beacon_node.rs b/beacon_node/rpc/src/beacon_node.rs index ed36b3deb..873d1c478 100644 --- a/beacon_node/rpc/src/beacon_node.rs +++ b/beacon_node/rpc/src/beacon_node.rs @@ -5,15 +5,15 @@ use protos::services::{Empty, Fork, NodeInfoResponse}; use protos::services_grpc::BeaconNodeService; use slog::{trace, warn}; use std::sync::Arc; -use types::BeaconStateTypes; +use types::EthSpec; #[derive(Clone)] -pub struct BeaconNodeServiceInstance { +pub struct BeaconNodeServiceInstance { pub chain: Arc>, pub log: slog::Logger, } -impl BeaconNodeService for BeaconNodeServiceInstance { +impl BeaconNodeService for BeaconNodeServiceInstance { /// Provides basic node information. fn info(&mut self, ctx: RpcContext, _req: Empty, sink: UnarySink) { trace!(self.log, "Node info requested via RPC"); diff --git a/beacon_node/rpc/src/lib.rs b/beacon_node/rpc/src/lib.rs index ef1a6fc76..d46dee7b5 100644 --- a/beacon_node/rpc/src/lib.rs +++ b/beacon_node/rpc/src/lib.rs @@ -21,9 +21,9 @@ use protos::services_grpc::{ use slog::{info, o, warn}; use std::sync::Arc; use tokio::runtime::TaskExecutor; -use types::BeaconStateTypes; +use types::EthSpec; -pub fn start_server( +pub fn start_server( config: &RPCConfig, executor: &TaskExecutor, network_chan: crossbeam_channel::Sender, diff --git a/beacon_node/rpc/src/validator.rs b/beacon_node/rpc/src/validator.rs index 8bddcd91a..e2f8d098f 100644 --- a/beacon_node/rpc/src/validator.rs +++ b/beacon_node/rpc/src/validator.rs @@ -7,16 +7,16 @@ use protos::services_grpc::ValidatorService; use slog::{trace, warn}; use ssz::decode; use std::sync::Arc; -use types::{BeaconStateTypes, Epoch, RelativeEpoch}; +use types::{Epoch, EthSpec, RelativeEpoch}; #[derive(Clone)] -pub struct ValidatorServiceInstance { +pub struct ValidatorServiceInstance { pub chain: Arc>, pub log: slog::Logger, } //TODO: Refactor Errors -impl ValidatorService for ValidatorServiceInstance { +impl ValidatorService for ValidatorServiceInstance { /// For a list of validator public keys, this function returns the slot at which each /// validator must propose a block, attest to a shard, their shard committee and the shard they /// need to attest to. diff --git a/eth2/fork_choice/src/bitwise_lmd_ghost.rs b/eth2/fork_choice/src/bitwise_lmd_ghost.rs index 7667b28b7..3eb8bff8c 100644 --- a/eth2/fork_choice/src/bitwise_lmd_ghost.rs +++ b/eth2/fork_choice/src/bitwise_lmd_ghost.rs @@ -11,7 +11,7 @@ use log::{debug, trace}; use std::collections::HashMap; use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot, SlotHeight}; +use types::{BeaconBlock, BeaconState, ChainSpec, EthSpec, Hash256, Slot, SlotHeight}; //TODO: Pruning - Children //TODO: Handle Syncing @@ -54,7 +54,7 @@ pub struct BitwiseLMDGhost { _phantom: PhantomData, } -impl BitwiseLMDGhost +impl BitwiseLMDGhost where T: ClientDB + Sized, { @@ -243,7 +243,7 @@ where } } -impl ForkChoice for BitwiseLMDGhost { +impl ForkChoice for BitwiseLMDGhost { fn add_block( &mut self, block: &BeaconBlock, diff --git a/eth2/fork_choice/src/optimized_lmd_ghost.rs b/eth2/fork_choice/src/optimized_lmd_ghost.rs index d2663b2b6..a471452c8 100644 --- a/eth2/fork_choice/src/optimized_lmd_ghost.rs +++ b/eth2/fork_choice/src/optimized_lmd_ghost.rs @@ -11,7 +11,7 @@ use std::cmp::Ordering; use std::collections::HashMap; use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot, SlotHeight}; +use types::{BeaconBlock, BeaconState, ChainSpec, EthSpec, Hash256, Slot, SlotHeight}; //TODO: Pruning - Children //TODO: Handle Syncing @@ -54,7 +54,7 @@ pub struct OptimizedLMDGhost { _phantom: PhantomData, } -impl OptimizedLMDGhost +impl OptimizedLMDGhost where T: ClientDB + Sized, { @@ -214,7 +214,7 @@ where } } -impl ForkChoice for OptimizedLMDGhost { +impl ForkChoice for OptimizedLMDGhost { fn add_block( &mut self, block: &BeaconBlock, diff --git a/eth2/fork_choice/src/slow_lmd_ghost.rs b/eth2/fork_choice/src/slow_lmd_ghost.rs index 68c4ac5a6..c11ef3eec 100644 --- a/eth2/fork_choice/src/slow_lmd_ghost.rs +++ b/eth2/fork_choice/src/slow_lmd_ghost.rs @@ -9,7 +9,7 @@ use log::{debug, trace}; use std::collections::HashMap; use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot}; +use types::{BeaconBlock, BeaconState, ChainSpec, EthSpec, Hash256, Slot}; //TODO: Pruning and syncing @@ -26,7 +26,7 @@ pub struct SlowLMDGhost { _phantom: PhantomData, } -impl SlowLMDGhost +impl SlowLMDGhost where T: ClientDB + Sized, { @@ -108,7 +108,7 @@ where } } -impl ForkChoice for SlowLMDGhost { +impl ForkChoice for SlowLMDGhost { /// Process when a block is added fn add_block( &mut self, diff --git a/eth2/fork_choice/tests/tests.rs b/eth2/fork_choice/tests/tests.rs index 3addb8c0a..067d39da4 100644 --- a/eth2/fork_choice/tests/tests.rs +++ b/eth2/fork_choice/tests/tests.rs @@ -26,8 +26,7 @@ use std::sync::Arc; use std::{fs::File, io::prelude::*, path::PathBuf}; use types::test_utils::TestingBeaconStateBuilder; use types::{ - BeaconBlock, BeaconBlockBody, BeaconStateTypes, Eth1Data, FoundationStateTypes, Hash256, - Keypair, Slot, + BeaconBlock, BeaconBlockBody, Eth1Data, EthSpec, FoundationEthSpec, Hash256, Keypair, Slot, }; use yaml_rust::yaml; @@ -85,7 +84,7 @@ fn test_yaml_vectors( let test_cases = load_test_cases_from_yaml(yaml_file_path); // default vars - let spec = FoundationStateTypes::spec(); + let spec = FoundationEthSpec::spec(); let zero_hash = Hash256::zero(); let eth1_data = Eth1Data { deposit_root: zero_hash.clone(), @@ -231,26 +230,26 @@ fn setup_inital_state( // the fork choice instantiation let fork_choice: Box = match fork_choice_algo { ForkChoiceAlgorithm::OptimizedLMDGhost => { - let f: OptimizedLMDGhost = + let f: OptimizedLMDGhost = OptimizedLMDGhost::new(block_store.clone(), state_store.clone()); Box::new(f) } ForkChoiceAlgorithm::BitwiseLMDGhost => { - let f: BitwiseLMDGhost = + let f: BitwiseLMDGhost = BitwiseLMDGhost::new(block_store.clone(), state_store.clone()); Box::new(f) } ForkChoiceAlgorithm::SlowLMDGhost => { - let f: SlowLMDGhost = + let f: SlowLMDGhost = SlowLMDGhost::new(block_store.clone(), state_store.clone()); Box::new(f) } ForkChoiceAlgorithm::LongestChain => Box::new(LongestChain::new(block_store.clone())), }; - let spec = FoundationStateTypes::spec(); + let spec = FoundationEthSpec::spec(); - let mut state_builder: TestingBeaconStateBuilder = + let mut state_builder: TestingBeaconStateBuilder = TestingBeaconStateBuilder::from_single_keypair(num_validators, &Keypair::random(), &spec); state_builder.build_caches(&spec).unwrap(); let (state, _keypairs) = state_builder.build(); diff --git a/eth2/operation_pool/src/lib.rs b/eth2/operation_pool/src/lib.rs index 5a82fd3f1..cbaabe0cd 100644 --- a/eth2/operation_pool/src/lib.rs +++ b/eth2/operation_pool/src/lib.rs @@ -16,8 +16,8 @@ use std::collections::{btree_map::Entry, hash_map, BTreeMap, HashMap, HashSet}; use std::marker::PhantomData; use types::chain_spec::Domain; use types::{ - Attestation, AttestationData, AttesterSlashing, BeaconState, BeaconStateTypes, ChainSpec, - Deposit, Epoch, ProposerSlashing, Transfer, Validator, VoluntaryExit, + Attestation, AttestationData, AttesterSlashing, BeaconState, ChainSpec, Deposit, Epoch, + EthSpec, ProposerSlashing, Transfer, Validator, VoluntaryExit, }; #[cfg(test)] @@ -26,7 +26,7 @@ const VERIFY_DEPOSIT_PROOFS: bool = false; const VERIFY_DEPOSIT_PROOFS: bool = false; // TODO: enable this #[derive(Default)] -pub struct OperationPool { +pub struct OperationPool { /// Map from attestation ID (see below) to vectors of attestations. attestations: RwLock>>, /// Map from deposit index to deposit data. @@ -54,7 +54,7 @@ struct AttestationId(Vec); const DOMAIN_BYTES_LEN: usize = 8; impl AttestationId { - fn from_data( + fn from_data( attestation: &AttestationData, state: &BeaconState, spec: &ChainSpec, @@ -65,7 +65,7 @@ impl AttestationId { AttestationId(bytes) } - fn compute_domain_bytes( + fn compute_domain_bytes( epoch: Epoch, state: &BeaconState, spec: &ChainSpec, @@ -85,7 +85,7 @@ impl AttestationId { /// receive for including it in a block. // TODO: this could be optimised with a map from validator index to whether that validator has // attested in each of the current and previous epochs. Currently quadractic in number of validators. -fn attestation_score( +fn attestation_score( attestation: &Attestation, state: &BeaconState, spec: &ChainSpec, @@ -127,7 +127,7 @@ pub enum DepositInsertStatus { Replaced(Box), } -impl OperationPool { +impl OperationPool { /// Create a new operation pool. pub fn new() -> Self { Self::default() @@ -501,7 +501,7 @@ impl OperationPool { /// /// - Their `AttestationData` is equal. /// - `attestation` does not contain any signatures that `PendingAttestation` does not have. -fn superior_attestation_exists_in_state( +fn superior_attestation_exists_in_state( state: &BeaconState, attestation: &Attestation, ) -> bool { @@ -539,7 +539,7 @@ where /// The keys in the map should be validator indices, which will be looked up /// in the state's validator registry and then passed to `prune_if`. /// Entries for unknown validators will be kept. -fn prune_validator_hash_map( +fn prune_validator_hash_map( map: &mut HashMap, prune_if: F, finalized_state: &BeaconState, @@ -666,7 +666,7 @@ mod tests { } // Create a random deposit (with a valid proof of posession) - fn make_deposit( + fn make_deposit( rng: &mut XorShiftRng, state: &BeaconState, spec: &ChainSpec, @@ -689,7 +689,7 @@ mod tests { } // Create `count` dummy deposits with sequential deposit IDs beginning from `start`. - fn dummy_deposits( + fn dummy_deposits( rng: &mut XorShiftRng, state: &BeaconState, spec: &ChainSpec, @@ -706,8 +706,8 @@ mod tests { .collect() } - fn test_state(rng: &mut XorShiftRng) -> (ChainSpec, BeaconState) { - let spec = FoundationStateTypes::spec(); + fn test_state(rng: &mut XorShiftRng) -> (ChainSpec, BeaconState) { + let spec = FoundationEthSpec::spec(); let mut state = BeaconState::random_for_test(rng); @@ -722,10 +722,7 @@ mod tests { /// Create a signed attestation for use in tests. /// Signed by all validators in `committee[signing_range]` and `committee[extra_signer]`. - fn signed_attestation< - R: std::slice::SliceIndex<[usize], Output = [usize]>, - B: BeaconStateTypes, - >( + fn signed_attestation, B: EthSpec>( committee: &CrosslinkCommittee, keypairs: &[Keypair], signing_range: R, @@ -757,7 +754,7 @@ mod tests { } /// Test state for attestation-related tests. - fn attestation_test_state( + fn attestation_test_state( num_committees: usize, ) -> (BeaconState, Vec, ChainSpec) { let spec = B::spec(); @@ -774,11 +771,11 @@ mod tests { state_builder.build_caches(&spec).unwrap(); let (state, keypairs) = state_builder.build(); - (state, keypairs, FoundationStateTypes::spec()) + (state, keypairs, FoundationEthSpec::spec()) } /// Set the latest crosslink in the state to match the attestation. - fn fake_latest_crosslink( + fn fake_latest_crosslink( att: &Attestation, state: &mut BeaconState, spec: &ChainSpec, @@ -792,7 +789,7 @@ mod tests { #[test] fn test_attestation_score() { let (ref mut state, ref keypairs, ref spec) = - attestation_test_state::(1); + attestation_test_state::(1); let slot = state.slot - 1; let committees = state @@ -824,7 +821,7 @@ mod tests { #[test] fn attestation_aggregation_insert_get_prune() { let (ref mut state, ref keypairs, ref spec) = - attestation_test_state::(1); + attestation_test_state::(1); let op_pool = OperationPool::new(); @@ -890,7 +887,7 @@ mod tests { #[test] fn attestation_duplicate() { let (ref mut state, ref keypairs, ref spec) = - attestation_test_state::(1); + attestation_test_state::(1); let op_pool = OperationPool::new(); @@ -917,7 +914,7 @@ mod tests { #[test] fn attestation_pairwise_overlapping() { let (ref mut state, ref keypairs, ref spec) = - attestation_test_state::(1); + attestation_test_state::(1); let op_pool = OperationPool::new(); @@ -963,7 +960,7 @@ mod tests { let big_step_size = 4; let (ref mut state, ref keypairs, ref spec) = - attestation_test_state::(big_step_size); + attestation_test_state::(big_step_size); let op_pool = OperationPool::new(); diff --git a/eth2/state_processing/src/common/exit_validator.rs b/eth2/state_processing/src/common/exit_validator.rs index e71a31b65..529f5e161 100644 --- a/eth2/state_processing/src/common/exit_validator.rs +++ b/eth2/state_processing/src/common/exit_validator.rs @@ -3,7 +3,7 @@ use types::{BeaconStateError as Error, *}; /// Exit the validator of the given `index`. /// /// Spec v0.5.1 -pub fn exit_validator( +pub fn exit_validator( state: &mut BeaconState, validator_index: usize, spec: &ChainSpec, diff --git a/eth2/state_processing/src/common/slash_validator.rs b/eth2/state_processing/src/common/slash_validator.rs index bb77e914c..63c1e89ad 100644 --- a/eth2/state_processing/src/common/slash_validator.rs +++ b/eth2/state_processing/src/common/slash_validator.rs @@ -4,7 +4,7 @@ use types::{BeaconStateError as Error, *}; /// Slash the validator with index ``index``. /// /// Spec v0.5.1 -pub fn slash_validator( +pub fn slash_validator( state: &mut BeaconState, validator_index: usize, spec: &ChainSpec, diff --git a/eth2/state_processing/src/get_genesis_state.rs b/eth2/state_processing/src/get_genesis_state.rs index 0960187df..6638b5246 100644 --- a/eth2/state_processing/src/get_genesis_state.rs +++ b/eth2/state_processing/src/get_genesis_state.rs @@ -10,7 +10,7 @@ pub enum GenesisError { /// Returns the genesis `BeaconState` /// /// Spec v0.5.1 -pub fn get_genesis_state( +pub fn get_genesis_state( genesis_validator_deposits: &[Deposit], genesis_time: u64, genesis_eth1_data: Eth1Data, diff --git a/eth2/state_processing/src/per_block_processing.rs b/eth2/state_processing/src/per_block_processing.rs index e8cf7d957..5bb40e25b 100644 --- a/eth2/state_processing/src/per_block_processing.rs +++ b/eth2/state_processing/src/per_block_processing.rs @@ -40,7 +40,7 @@ const VERIFY_DEPOSIT_MERKLE_PROOFS: bool = false; /// returns an error describing why the block was invalid or how the function failed to execute. /// /// Spec v0.5.1 -pub fn per_block_processing( +pub fn per_block_processing( state: &mut BeaconState, block: &BeaconBlock, spec: &ChainSpec, @@ -55,7 +55,7 @@ pub fn per_block_processing( /// returns an error describing why the block was invalid or how the function failed to execute. /// /// Spec v0.5.1 -pub fn per_block_processing_without_verifying_block_signature( +pub fn per_block_processing_without_verifying_block_signature( state: &mut BeaconState, block: &BeaconBlock, spec: &ChainSpec, @@ -70,7 +70,7 @@ pub fn per_block_processing_without_verifying_block_signature( +fn per_block_processing_signature_optional( mut state: &mut BeaconState, block: &BeaconBlock, should_verify_block_signature: bool, @@ -100,7 +100,7 @@ fn per_block_processing_signature_optional( /// Processes the block header. /// /// Spec v0.5.1 -pub fn process_block_header( +pub fn process_block_header( state: &mut BeaconState, block: &BeaconBlock, spec: &ChainSpec, @@ -125,7 +125,7 @@ pub fn process_block_header( /// Verifies the signature of a block. /// /// Spec v0.5.1 -pub fn verify_block_signature( +pub fn verify_block_signature( state: &BeaconState, block: &BeaconBlock, spec: &ChainSpec, @@ -153,7 +153,7 @@ pub fn verify_block_signature( /// `state.latest_randao_mixes`. /// /// Spec v0.5.1 -pub fn process_randao( +pub fn process_randao( state: &mut BeaconState, block: &BeaconBlock, spec: &ChainSpec, @@ -184,7 +184,7 @@ pub fn process_randao( /// Update the `state.eth1_data_votes` based upon the `eth1_data` provided. /// /// Spec v0.5.1 -pub fn process_eth1_data( +pub fn process_eth1_data( state: &mut BeaconState, eth1_data: &Eth1Data, ) -> Result<(), Error> { @@ -213,7 +213,7 @@ pub fn process_eth1_data( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_proposer_slashings( +pub fn process_proposer_slashings( state: &mut BeaconState, proposer_slashings: &[ProposerSlashing], spec: &ChainSpec, @@ -246,7 +246,7 @@ pub fn process_proposer_slashings( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_attester_slashings( +pub fn process_attester_slashings( state: &mut BeaconState, attester_slashings: &[AttesterSlashing], spec: &ChainSpec, @@ -304,7 +304,7 @@ pub fn process_attester_slashings( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_attestations( +pub fn process_attestations( state: &mut BeaconState, attestations: &[Attestation], spec: &ChainSpec, @@ -346,7 +346,7 @@ pub fn process_attestations( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_deposits( +pub fn process_deposits( state: &mut BeaconState, deposits: &[Deposit], spec: &ChainSpec, @@ -416,7 +416,7 @@ pub fn process_deposits( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_exits( +pub fn process_exits( state: &mut BeaconState, voluntary_exits: &[VoluntaryExit], spec: &ChainSpec, @@ -448,7 +448,7 @@ pub fn process_exits( /// an `Err` describing the invalid object or cause of failure. /// /// Spec v0.5.1 -pub fn process_transfers( +pub fn process_transfers( state: &mut BeaconState, transfers: &[Transfer], spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_block_processing/validate_attestation.rs b/eth2/state_processing/src/per_block_processing/validate_attestation.rs index f0ec1b861..cb26389df 100644 --- a/eth2/state_processing/src/per_block_processing/validate_attestation.rs +++ b/eth2/state_processing/src/per_block_processing/validate_attestation.rs @@ -9,7 +9,7 @@ use types::*; /// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn validate_attestation( +pub fn validate_attestation( state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, @@ -18,7 +18,7 @@ pub fn validate_attestation( } /// Like `validate_attestation` but doesn't run checks which may become true in future states. -pub fn validate_attestation_time_independent_only( +pub fn validate_attestation_time_independent_only( state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, @@ -32,7 +32,7 @@ pub fn validate_attestation_time_independent_only( /// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn validate_attestation_without_signature( +pub fn validate_attestation_without_signature( state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, @@ -45,7 +45,7 @@ pub fn validate_attestation_without_signature( /// /// /// Spec v0.5.1 -fn validate_attestation_parametric( +fn validate_attestation_parametric( state: &BeaconState, attestation: &Attestation, spec: &ChainSpec, @@ -168,7 +168,7 @@ fn validate_attestation_parametric( /// match the current (or previous) justified epoch and root from the state. /// /// Spec v0.5.1 -fn verify_justified_epoch_and_root( +fn verify_justified_epoch_and_root( attestation: &Attestation, state: &BeaconState, spec: &ChainSpec, @@ -223,7 +223,7 @@ fn verify_justified_epoch_and_root( /// - A `validator_index` in `committee` is not in `state.validator_registry`. /// /// Spec v0.5.1 -fn verify_attestation_signature( +fn verify_attestation_signature( state: &BeaconState, committee: &[usize], a: &Attestation, diff --git a/eth2/state_processing/src/per_block_processing/verify_attester_slashing.rs b/eth2/state_processing/src/per_block_processing/verify_attester_slashing.rs index 804ebd517..5ac62221a 100644 --- a/eth2/state_processing/src/per_block_processing/verify_attester_slashing.rs +++ b/eth2/state_processing/src/per_block_processing/verify_attester_slashing.rs @@ -8,7 +8,7 @@ use types::*; /// Returns `Ok(())` if the `AttesterSlashing` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn verify_attester_slashing( +pub fn verify_attester_slashing( state: &BeaconState, attester_slashing: &AttesterSlashing, should_verify_slashable_attestations: bool, @@ -42,7 +42,7 @@ pub fn verify_attester_slashing( /// Returns Ok(indices) if `indices.len() > 0`. /// /// Spec v0.5.1 -pub fn gather_attester_slashing_indices( +pub fn gather_attester_slashing_indices( state: &BeaconState, attester_slashing: &AttesterSlashing, spec: &ChainSpec, @@ -57,7 +57,7 @@ pub fn gather_attester_slashing_indices( /// Same as `gather_attester_slashing_indices` but allows the caller to specify the criteria /// for determining whether a given validator should be considered slashed. -pub fn gather_attester_slashing_indices_modular( +pub fn gather_attester_slashing_indices_modular( state: &BeaconState, attester_slashing: &AttesterSlashing, is_slashed: F, diff --git a/eth2/state_processing/src/per_block_processing/verify_deposit.rs b/eth2/state_processing/src/per_block_processing/verify_deposit.rs index b99204e77..e2868a1b6 100644 --- a/eth2/state_processing/src/per_block_processing/verify_deposit.rs +++ b/eth2/state_processing/src/per_block_processing/verify_deposit.rs @@ -16,7 +16,7 @@ use types::*; /// Note: this function is incomplete. /// /// Spec v0.5.1 -pub fn verify_deposit( +pub fn verify_deposit( state: &BeaconState, deposit: &Deposit, verify_merkle_branch: bool, @@ -47,7 +47,7 @@ pub fn verify_deposit( /// Verify that the `Deposit` index is correct. /// /// Spec v0.5.1 -pub fn verify_deposit_index( +pub fn verify_deposit_index( state: &BeaconState, deposit: &Deposit, ) -> Result<(), Error> { @@ -68,7 +68,7 @@ pub fn verify_deposit_index( /// ## Errors /// /// Errors if the state's `pubkey_cache` is not current. -pub fn get_existing_validator_index( +pub fn get_existing_validator_index( state: &BeaconState, deposit: &Deposit, ) -> Result, Error> { @@ -92,7 +92,7 @@ pub fn get_existing_validator_index( /// Verify that a deposit is included in the state's eth1 deposit root. /// /// Spec v0.5.1 -fn verify_deposit_merkle_proof( +fn verify_deposit_merkle_proof( state: &BeaconState, deposit: &Deposit, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_block_processing/verify_exit.rs b/eth2/state_processing/src/per_block_processing/verify_exit.rs index deaf9379a..333638a8d 100644 --- a/eth2/state_processing/src/per_block_processing/verify_exit.rs +++ b/eth2/state_processing/src/per_block_processing/verify_exit.rs @@ -8,7 +8,7 @@ use types::*; /// Returns `Ok(())` if the `Exit` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn verify_exit( +pub fn verify_exit( state: &BeaconState, exit: &VoluntaryExit, spec: &ChainSpec, @@ -17,7 +17,7 @@ pub fn verify_exit( } /// Like `verify_exit` but doesn't run checks which may become true in future states. -pub fn verify_exit_time_independent_only( +pub fn verify_exit_time_independent_only( state: &BeaconState, exit: &VoluntaryExit, spec: &ChainSpec, @@ -26,7 +26,7 @@ pub fn verify_exit_time_independent_only( } /// Parametric version of `verify_exit` that skips some checks if `time_independent_only` is true. -fn verify_exit_parametric( +fn verify_exit_parametric( state: &BeaconState, exit: &VoluntaryExit, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_block_processing/verify_proposer_slashing.rs b/eth2/state_processing/src/per_block_processing/verify_proposer_slashing.rs index 73fffcd64..0c66a9b15 100644 --- a/eth2/state_processing/src/per_block_processing/verify_proposer_slashing.rs +++ b/eth2/state_processing/src/per_block_processing/verify_proposer_slashing.rs @@ -8,7 +8,7 @@ use types::*; /// Returns `Ok(())` if the `ProposerSlashing` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn verify_proposer_slashing( +pub fn verify_proposer_slashing( proposer_slashing: &ProposerSlashing, state: &BeaconState, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_block_processing/verify_slashable_attestation.rs b/eth2/state_processing/src/per_block_processing/verify_slashable_attestation.rs index 1e52c6a41..4d440332a 100644 --- a/eth2/state_processing/src/per_block_processing/verify_slashable_attestation.rs +++ b/eth2/state_processing/src/per_block_processing/verify_slashable_attestation.rs @@ -11,7 +11,7 @@ use types::*; /// Returns `Ok(())` if the `SlashableAttestation` is valid, otherwise indicates the reason for invalidity. /// /// Spec v0.5.1 -pub fn verify_slashable_attestation( +pub fn verify_slashable_attestation( state: &BeaconState, slashable_attestation: &SlashableAttestation, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_block_processing/verify_transfer.rs b/eth2/state_processing/src/per_block_processing/verify_transfer.rs index 771d350a5..c6388bebe 100644 --- a/eth2/state_processing/src/per_block_processing/verify_transfer.rs +++ b/eth2/state_processing/src/per_block_processing/verify_transfer.rs @@ -11,7 +11,7 @@ use types::*; /// Note: this function is incomplete. /// /// Spec v0.5.1 -pub fn verify_transfer( +pub fn verify_transfer( state: &BeaconState, transfer: &Transfer, spec: &ChainSpec, @@ -20,7 +20,7 @@ pub fn verify_transfer( } /// Like `verify_transfer` but doesn't run checks which may become true in future states. -pub fn verify_transfer_time_independent_only( +pub fn verify_transfer_time_independent_only( state: &BeaconState, transfer: &Transfer, spec: &ChainSpec, @@ -29,7 +29,7 @@ pub fn verify_transfer_time_independent_only( } /// Parametric version of `verify_transfer` that allows some checks to be skipped. -fn verify_transfer_parametric( +fn verify_transfer_parametric( state: &BeaconState, transfer: &Transfer, spec: &ChainSpec, @@ -123,7 +123,7 @@ fn verify_transfer_parametric( /// Does not check that the transfer is valid, however checks for overflow in all actions. /// /// Spec v0.5.1 -pub fn execute_transfer( +pub fn execute_transfer( state: &mut BeaconState, transfer: &Transfer, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_epoch_processing.rs b/eth2/state_processing/src/per_epoch_processing.rs index e2ecd47d6..3f8eb5112 100644 --- a/eth2/state_processing/src/per_epoch_processing.rs +++ b/eth2/state_processing/src/per_epoch_processing.rs @@ -33,7 +33,7 @@ pub type WinningRootHashSet = HashMap; /// returned, a state might be "half-processed" and therefore in an invalid state. /// /// Spec v0.5.1 -pub fn per_epoch_processing( +pub fn per_epoch_processing( state: &mut BeaconState, spec: &ChainSpec, ) -> Result<(), Error> { @@ -90,7 +90,7 @@ pub fn per_epoch_processing( /// Maybe resets the eth1 period. /// /// Spec v0.5.1 -pub fn maybe_reset_eth1_period(state: &mut BeaconState, spec: &ChainSpec) { +pub fn maybe_reset_eth1_period(state: &mut BeaconState, spec: &ChainSpec) { let next_epoch = state.next_epoch(spec); let voting_period = spec.epochs_per_eth1_voting_period; @@ -112,7 +112,7 @@ pub fn maybe_reset_eth1_period(state: &mut BeaconState, /// - `previous_justified_epoch` /// /// Spec v0.5.1 -pub fn update_justification_and_finalization( +pub fn update_justification_and_finalization( state: &mut BeaconState, total_balances: &TotalBalances, spec: &ChainSpec, @@ -182,7 +182,7 @@ pub fn update_justification_and_finalization( /// Also returns a `WinningRootHashSet` for later use during epoch processing. /// /// Spec v0.5.1 -pub fn process_crosslinks( +pub fn process_crosslinks( state: &mut BeaconState, spec: &ChainSpec, ) -> Result { @@ -225,7 +225,7 @@ pub fn process_crosslinks( /// Finish up an epoch update. /// /// Spec v0.5.1 -pub fn finish_epoch_update( +pub fn finish_epoch_update( state: &mut BeaconState, spec: &ChainSpec, ) -> Result<(), Error> { diff --git a/eth2/state_processing/src/per_epoch_processing/apply_rewards.rs b/eth2/state_processing/src/per_epoch_processing/apply_rewards.rs index fe31ef244..f529523fb 100644 --- a/eth2/state_processing/src/per_epoch_processing/apply_rewards.rs +++ b/eth2/state_processing/src/per_epoch_processing/apply_rewards.rs @@ -33,7 +33,7 @@ impl std::ops::AddAssign for Delta { /// Apply attester and proposer rewards. /// /// Spec v0.5.1 -pub fn apply_rewards( +pub fn apply_rewards( state: &mut BeaconState, validator_statuses: &mut ValidatorStatuses, winning_root_for_shards: &WinningRootHashSet, @@ -80,7 +80,7 @@ pub fn apply_rewards( /// attestation in the previous epoch. /// /// Spec v0.5.1 -fn get_proposer_deltas( +fn get_proposer_deltas( deltas: &mut Vec, state: &mut BeaconState, validator_statuses: &mut ValidatorStatuses, @@ -121,7 +121,7 @@ fn get_proposer_deltas( /// Apply rewards for participation in attestations during the previous epoch. /// /// Spec v0.5.1 -fn get_justification_and_finalization_deltas( +fn get_justification_and_finalization_deltas( deltas: &mut Vec, state: &BeaconState, validator_statuses: &ValidatorStatuses, @@ -262,7 +262,7 @@ fn compute_inactivity_leak_delta( /// Calculate the deltas based upon the winning roots for attestations during the previous epoch. /// /// Spec v0.5.1 -fn get_crosslink_deltas( +fn get_crosslink_deltas( deltas: &mut Vec, state: &BeaconState, validator_statuses: &ValidatorStatuses, @@ -296,7 +296,7 @@ fn get_crosslink_deltas( /// Returns the base reward for some validator. /// /// Spec v0.5.1 -fn get_base_reward( +fn get_base_reward( state: &BeaconState, index: usize, previous_total_balance: u64, @@ -313,7 +313,7 @@ fn get_base_reward( /// Returns the inactivity penalty for some validator. /// /// Spec v0.5.1 -fn get_inactivity_penalty( +fn get_inactivity_penalty( state: &BeaconState, index: usize, epochs_since_finality: u64, @@ -329,6 +329,6 @@ fn get_inactivity_penalty( /// Returns the epochs since the last finalized epoch. /// /// Spec v0.5.1 -fn epochs_since_finality(state: &BeaconState, spec: &ChainSpec) -> Epoch { +fn epochs_since_finality(state: &BeaconState, spec: &ChainSpec) -> Epoch { state.current_epoch(spec) + 1 - state.finalized_epoch } diff --git a/eth2/state_processing/src/per_epoch_processing/get_attestation_participants.rs b/eth2/state_processing/src/per_epoch_processing/get_attestation_participants.rs index ddf0d680f..7f5504c56 100644 --- a/eth2/state_processing/src/per_epoch_processing/get_attestation_participants.rs +++ b/eth2/state_processing/src/per_epoch_processing/get_attestation_participants.rs @@ -4,7 +4,7 @@ use types::*; /// Returns validator indices which participated in the attestation. /// /// Spec v0.5.1 -pub fn get_attestation_participants( +pub fn get_attestation_participants( state: &BeaconState, attestation_data: &AttestationData, bitfield: &Bitfield, diff --git a/eth2/state_processing/src/per_epoch_processing/inclusion_distance.rs b/eth2/state_processing/src/per_epoch_processing/inclusion_distance.rs index 9d4b36876..e82d810ba 100644 --- a/eth2/state_processing/src/per_epoch_processing/inclusion_distance.rs +++ b/eth2/state_processing/src/per_epoch_processing/inclusion_distance.rs @@ -6,7 +6,7 @@ use types::*; /// slot. /// /// Spec v0.5.1 -pub fn inclusion_distance( +pub fn inclusion_distance( state: &BeaconState, attestations: &[&PendingAttestation], validator_index: usize, @@ -19,7 +19,7 @@ pub fn inclusion_distance( /// Returns the slot of the earliest included attestation for some validator. /// /// Spec v0.5.1 -pub fn inclusion_slot( +pub fn inclusion_slot( state: &BeaconState, attestations: &[&PendingAttestation], validator_index: usize, @@ -32,7 +32,7 @@ pub fn inclusion_slot( /// Finds the earliest included attestation for some validator. /// /// Spec v0.5.1 -fn earliest_included_attestation( +fn earliest_included_attestation( state: &BeaconState, attestations: &[&PendingAttestation], validator_index: usize, diff --git a/eth2/state_processing/src/per_epoch_processing/process_ejections.rs b/eth2/state_processing/src/per_epoch_processing/process_ejections.rs index 5a18d77be..e32241e24 100644 --- a/eth2/state_processing/src/per_epoch_processing/process_ejections.rs +++ b/eth2/state_processing/src/per_epoch_processing/process_ejections.rs @@ -5,7 +5,7 @@ use types::{BeaconStateError as Error, *}; /// ``EJECTION_BALANCE``. /// /// Spec v0.5.1 -pub fn process_ejections( +pub fn process_ejections( state: &mut BeaconState, spec: &ChainSpec, ) -> Result<(), Error> { diff --git a/eth2/state_processing/src/per_epoch_processing/process_exit_queue.rs b/eth2/state_processing/src/per_epoch_processing/process_exit_queue.rs index 082a64775..eafe4541e 100644 --- a/eth2/state_processing/src/per_epoch_processing/process_exit_queue.rs +++ b/eth2/state_processing/src/per_epoch_processing/process_exit_queue.rs @@ -3,7 +3,7 @@ use types::*; /// Process the exit queue. /// /// Spec v0.5.1 -pub fn process_exit_queue(state: &mut BeaconState, spec: &ChainSpec) { +pub fn process_exit_queue(state: &mut BeaconState, spec: &ChainSpec) { let current_epoch = state.current_epoch(spec); let eligible = |index: usize| { @@ -32,7 +32,7 @@ pub fn process_exit_queue(state: &mut BeaconState, spec: /// Initiate an exit for the validator of the given `index`. /// /// Spec v0.5.1 -fn prepare_validator_for_withdrawal( +fn prepare_validator_for_withdrawal( state: &mut BeaconState, validator_index: usize, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_epoch_processing/process_slashings.rs b/eth2/state_processing/src/per_epoch_processing/process_slashings.rs index e3a038bd7..a70720cce 100644 --- a/eth2/state_processing/src/per_epoch_processing/process_slashings.rs +++ b/eth2/state_processing/src/per_epoch_processing/process_slashings.rs @@ -3,7 +3,7 @@ use types::{BeaconStateError as Error, *}; /// Process slashings. /// /// Spec v0.5.1 -pub fn process_slashings( +pub fn process_slashings( state: &mut BeaconState, current_total_balance: u64, spec: &ChainSpec, diff --git a/eth2/state_processing/src/per_epoch_processing/tests.rs b/eth2/state_processing/src/per_epoch_processing/tests.rs index bbbd7d7c5..b075c5cd4 100644 --- a/eth2/state_processing/src/per_epoch_processing/tests.rs +++ b/eth2/state_processing/src/per_epoch_processing/tests.rs @@ -8,9 +8,9 @@ use types::*; fn runs_without_error() { Builder::from_env(Env::default().default_filter_or("error")).init(); - let spec = FewValidatorsStateTypes::spec(); + let spec = FewValidatorsEthSpec::spec(); - let mut builder: TestingBeaconStateBuilder = + let mut builder: TestingBeaconStateBuilder = TestingBeaconStateBuilder::from_deterministic_keypairs(8, &spec); let target_slot = (spec.genesis_epoch + 4).end_slot(spec.slots_per_epoch); diff --git a/eth2/state_processing/src/per_epoch_processing/update_registry_and_shuffling_data.rs b/eth2/state_processing/src/per_epoch_processing/update_registry_and_shuffling_data.rs index b1e326225..f6548fb67 100644 --- a/eth2/state_processing/src/per_epoch_processing/update_registry_and_shuffling_data.rs +++ b/eth2/state_processing/src/per_epoch_processing/update_registry_and_shuffling_data.rs @@ -5,7 +5,7 @@ use types::*; /// Peforms a validator registry update, if required. /// /// Spec v0.5.1 -pub fn update_registry_and_shuffling_data( +pub fn update_registry_and_shuffling_data( state: &mut BeaconState, current_total_balance: u64, spec: &ChainSpec, @@ -50,7 +50,7 @@ pub fn update_registry_and_shuffling_data( /// Returns `true` if the validator registry should be updated during an epoch processing. /// /// Spec v0.5.1 -pub fn should_update_validator_registry( +pub fn should_update_validator_registry( state: &BeaconState, spec: &ChainSpec, ) -> Result { @@ -79,7 +79,7 @@ pub fn should_update_validator_registry( /// Note: Utilizes the cache and will fail if the appropriate cache is not initialized. /// /// Spec v0.5.1 -pub fn update_validator_registry( +pub fn update_validator_registry( state: &mut BeaconState, current_total_balance: u64, spec: &ChainSpec, @@ -134,7 +134,7 @@ pub fn update_validator_registry( /// Activate the validator of the given ``index``. /// /// Spec v0.5.1 -pub fn activate_validator( +pub fn activate_validator( state: &mut BeaconState, validator_index: usize, is_genesis: bool, diff --git a/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs b/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs index 038737fd9..ee0079eee 100644 --- a/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs +++ b/eth2/state_processing/src/per_epoch_processing/validator_statuses.rs @@ -161,7 +161,7 @@ impl ValidatorStatuses { /// - Total balances for the current and previous epochs. /// /// Spec v0.5.1 - pub fn new( + pub fn new( state: &BeaconState, spec: &ChainSpec, ) -> Result { @@ -199,7 +199,7 @@ impl ValidatorStatuses { /// `total_balances` fields. /// /// Spec v0.5.1 - pub fn process_attestations( + pub fn process_attestations( &mut self, state: &BeaconState, spec: &ChainSpec, @@ -265,7 +265,7 @@ impl ValidatorStatuses { /// "winning" shard block root for the previous epoch. /// /// Spec v0.5.1 - pub fn process_winning_roots( + pub fn process_winning_roots( &mut self, state: &BeaconState, winning_roots: &WinningRootHashSet, @@ -316,7 +316,7 @@ fn is_from_epoch(a: &PendingAttestation, epoch: Epoch, spec: &ChainSpec) -> bool /// the first slot of the given epoch. /// /// Spec v0.5.1 -fn has_common_epoch_boundary_root( +fn has_common_epoch_boundary_root( a: &PendingAttestation, state: &BeaconState, epoch: Epoch, @@ -332,7 +332,7 @@ fn has_common_epoch_boundary_root( /// the current slot of the `PendingAttestation`. /// /// Spec v0.5.1 -fn has_common_beacon_block_root( +fn has_common_beacon_block_root( a: &PendingAttestation, state: &BeaconState, ) -> Result { diff --git a/eth2/state_processing/src/per_epoch_processing/winning_root.rs b/eth2/state_processing/src/per_epoch_processing/winning_root.rs index 246043b05..8ffa717e8 100644 --- a/eth2/state_processing/src/per_epoch_processing/winning_root.rs +++ b/eth2/state_processing/src/per_epoch_processing/winning_root.rs @@ -35,7 +35,7 @@ impl WinningRoot { /// per-epoch processing. /// /// Spec v0.5.1 -pub fn winning_root( +pub fn winning_root( state: &BeaconState, shard: u64, spec: &ChainSpec, @@ -90,7 +90,7 @@ pub fn winning_root( /// Returns `true` if pending attestation `a` is eligible to become a winning root. /// /// Spec v0.5.1 -fn is_eligible_for_winning_root( +fn is_eligible_for_winning_root( state: &BeaconState, a: &PendingAttestation, shard: Shard, @@ -105,7 +105,7 @@ fn is_eligible_for_winning_root( /// Returns all indices which voted for a given crosslink. Does not contain duplicates. /// /// Spec v0.5.1 -fn get_attesting_validator_indices( +fn get_attesting_validator_indices( state: &BeaconState, shard: u64, crosslink_data_root: &Hash256, diff --git a/eth2/state_processing/src/per_slot_processing.rs b/eth2/state_processing/src/per_slot_processing.rs index 08875cf4d..ebab36ff7 100644 --- a/eth2/state_processing/src/per_slot_processing.rs +++ b/eth2/state_processing/src/per_slot_processing.rs @@ -11,7 +11,7 @@ pub enum Error { /// Advances a state forward by one slot, performing per-epoch processing if required. /// /// Spec v0.5.1 -pub fn per_slot_processing( +pub fn per_slot_processing( state: &mut BeaconState, spec: &ChainSpec, ) -> Result<(), Error> { @@ -26,10 +26,7 @@ pub fn per_slot_processing( Ok(()) } -fn cache_state( - state: &mut BeaconState, - spec: &ChainSpec, -) -> Result<(), Error> { +fn cache_state(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> { let previous_slot_state_root = state.update_tree_hash_cache()?; // Note: increment the state slot here to allow use of our `state_root` and `block_root` diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index 03c39db61..cb68c4c40 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -67,7 +67,7 @@ pub enum Error { )] pub struct BeaconState where - T: BeaconStateTypes, + T: EthSpec, { // Misc pub slot: Slot, @@ -140,7 +140,7 @@ where pub tree_hash_cache: TreeHashCache, } -impl BeaconState { +impl BeaconState { /// Produce the first state of the Beacon Chain. /// /// This does not fully build a genesis beacon state, it omits processing of initial validator diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index 8f0f6d524..b6c943a36 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -3,7 +3,7 @@ use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192}; use serde_derive::{Deserialize, Serialize}; use std::fmt::Debug; -pub trait BeaconStateTypes: +pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + serde::de::DeserializeOwned { type ShardCount: Unsigned + Clone + Sync + Send + Debug + PartialEq; @@ -54,9 +54,9 @@ pub trait BeaconStateTypes: /// /// Spec v0.5.1 #[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] -pub struct FoundationStateTypes; +pub struct FoundationEthSpec; -impl BeaconStateTypes for FoundationStateTypes { +impl EthSpec for FoundationEthSpec { type ShardCount = U1024; type SlotsPerHistoricalRoot = U8192; type LatestRandaoMixesLength = U8192; @@ -68,15 +68,15 @@ impl BeaconStateTypes for FoundationStateTypes { } } -pub type FoundationBeaconState = BeaconState; +pub type FoundationBeaconState = BeaconState; /// Ethereum Foundation specifications, modified to be suitable for < 1000 validators. /// /// Spec v0.5.1 #[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] -pub struct FewValidatorsStateTypes; +pub struct FewValidatorsEthSpec; -impl BeaconStateTypes for FewValidatorsStateTypes { +impl EthSpec for FewValidatorsEthSpec { type ShardCount = U8; type SlotsPerHistoricalRoot = U8192; type LatestRandaoMixesLength = U8192; @@ -88,15 +88,15 @@ impl BeaconStateTypes for FewValidatorsStateTypes { } } -pub type FewValidatorsBeaconState = BeaconState; +pub type FewValidatorsBeaconState = BeaconState; /// Specifications suitable for a small-scale (< 1000 validators) lighthouse testnet. /// /// Spec v0.5.1 #[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)] -pub struct LighthouseTestnetStateTypes; +pub struct LighthouseTestnetEthSpec; -impl BeaconStateTypes for LighthouseTestnetStateTypes { +impl EthSpec for LighthouseTestnetEthSpec { type ShardCount = U8; type SlotsPerHistoricalRoot = U8192; type LatestRandaoMixesLength = U8192; @@ -108,4 +108,4 @@ impl BeaconStateTypes for LighthouseTestnetStateTypes { } } -pub type LighthouseTestnetBeaconState = BeaconState; +pub type LighthouseTestnetBeaconState = BeaconState; diff --git a/eth2/types/src/beacon_state/epoch_cache.rs b/eth2/types/src/beacon_state/epoch_cache.rs index 31becc5d3..c76c71684 100644 --- a/eth2/types/src/beacon_state/epoch_cache.rs +++ b/eth2/types/src/beacon_state/epoch_cache.rs @@ -28,7 +28,7 @@ pub struct EpochCache { impl EpochCache { /// Return a new, fully initialized cache. - pub fn initialized( + pub fn initialized( state: &BeaconState, relative_epoch: RelativeEpoch, spec: &ChainSpec, @@ -200,7 +200,7 @@ pub struct EpochCrosslinkCommitteesBuilder { impl EpochCrosslinkCommitteesBuilder { /// Instantiates a builder that will build for the `state`'s previous epoch. - pub fn for_previous_epoch( + pub fn for_previous_epoch( state: &BeaconState, active_validator_indices: Vec, spec: &ChainSpec, @@ -215,7 +215,7 @@ impl EpochCrosslinkCommitteesBuilder { } /// Instantiates a builder that will build for the `state`'s next epoch. - pub fn for_current_epoch( + pub fn for_current_epoch( state: &BeaconState, active_validator_indices: Vec, spec: &ChainSpec, @@ -233,7 +233,7 @@ impl EpochCrosslinkCommitteesBuilder { /// /// Note: there are two possible epoch builds for the next epoch, one where there is a registry /// change and one where there is not. - pub fn for_next_epoch( + pub fn for_next_epoch( state: &BeaconState, active_validator_indices: Vec, registry_change: bool, diff --git a/eth2/types/src/beacon_state/epoch_cache/tests.rs b/eth2/types/src/beacon_state/epoch_cache/tests.rs index 6ba7c9086..2a3034192 100644 --- a/eth2/types/src/beacon_state/epoch_cache/tests.rs +++ b/eth2/types/src/beacon_state/epoch_cache/tests.rs @@ -1,11 +1,11 @@ #![cfg(test)] use super::*; -use crate::beacon_state::FewValidatorsStateTypes; +use crate::beacon_state::FewValidatorsEthSpec; use crate::test_utils::*; use swap_or_not_shuffle::shuffle_list; -fn do_sane_cache_test( +fn do_sane_cache_test( state: BeaconState, epoch: Epoch, relative_epoch: RelativeEpoch, @@ -65,10 +65,7 @@ fn do_sane_cache_test( } } -fn setup_sane_cache_test( - validator_count: usize, - spec: &ChainSpec, -) -> BeaconState { +fn setup_sane_cache_test(validator_count: usize, spec: &ChainSpec) -> BeaconState { let mut builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, spec); @@ -102,11 +99,11 @@ fn setup_sane_cache_test( #[test] fn builds_sane_current_epoch_cache() { - let mut spec = FewValidatorsStateTypes::spec(); + let mut spec = FewValidatorsEthSpec::spec(); spec.shard_count = 4; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let state: BeaconState = + let state: BeaconState = setup_sane_cache_test(validator_count as usize, &spec); do_sane_cache_test( @@ -122,11 +119,11 @@ fn builds_sane_current_epoch_cache() { #[test] fn builds_sane_previous_epoch_cache() { - let mut spec = FewValidatorsStateTypes::spec(); + let mut spec = FewValidatorsEthSpec::spec(); spec.shard_count = 2; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let state: BeaconState = + let state: BeaconState = setup_sane_cache_test(validator_count as usize, &spec); do_sane_cache_test( @@ -142,11 +139,11 @@ fn builds_sane_previous_epoch_cache() { #[test] fn builds_sane_next_without_update_epoch_cache() { - let mut spec = FewValidatorsStateTypes::spec(); + let mut spec = FewValidatorsEthSpec::spec(); spec.shard_count = 2; let validator_count = (spec.shard_count * spec.target_committee_size) + 1; - let mut state: BeaconState = + let mut state: BeaconState = setup_sane_cache_test(validator_count as usize, &spec); state.validator_registry_update_epoch = state.slot.epoch(spec.slots_per_epoch); diff --git a/eth2/types/src/beacon_state/tests.rs b/eth2/types/src/beacon_state/tests.rs index 8948a94f6..aa3c0b98a 100644 --- a/eth2/types/src/beacon_state/tests.rs +++ b/eth2/types/src/beacon_state/tests.rs @@ -1,6 +1,6 @@ #![cfg(test)] use super::*; -use crate::beacon_state::FewValidatorsStateTypes; +use crate::beacon_state::FewValidatorsEthSpec; use crate::test_utils::*; ssz_tests!(FoundationBeaconState); @@ -11,7 +11,7 @@ cached_tree_hash_tests!(FoundationBeaconState); /// 1. Using the cache before it's built fails. /// 2. Using the cache after it's build passes. /// 3. Using the cache after it's dropped fails. -fn test_cache_initialization<'a, T: BeaconStateTypes>( +fn test_cache_initialization<'a, T: EthSpec>( state: &'a mut BeaconState, relative_epoch: RelativeEpoch, spec: &ChainSpec, @@ -46,9 +46,9 @@ fn test_cache_initialization<'a, T: BeaconStateTypes>( #[test] fn cache_initialization() { - let spec = FewValidatorsStateTypes::spec(); + let spec = FewValidatorsEthSpec::spec(); - let builder: TestingBeaconStateBuilder = + let builder: TestingBeaconStateBuilder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec); let (mut state, _keypairs) = builder.build(); diff --git a/eth2/types/src/historical_batch.rs b/eth2/types/src/historical_batch.rs index ecd7aad89..d80838221 100644 --- a/eth2/types/src/historical_batch.rs +++ b/eth2/types/src/historical_batch.rs @@ -22,7 +22,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash}; CachedTreeHash, TestRandom, )] -pub struct HistoricalBatch { +pub struct HistoricalBatch { pub block_roots: FixedLenVec, pub state_roots: FixedLenVec, } @@ -31,7 +31,7 @@ pub struct HistoricalBatch { mod tests { use super::*; - pub type FoundationHistoricalBatch = HistoricalBatch; + pub type FoundationHistoricalBatch = HistoricalBatch; ssz_tests!(FoundationHistoricalBatch); cached_tree_hash_tests!(FoundationHistoricalBatch); diff --git a/eth2/types/src/test_utils/testing_attestation_builder.rs b/eth2/types/src/test_utils/testing_attestation_builder.rs index 2d9b5ac6f..0df1c01b8 100644 --- a/eth2/types/src/test_utils/testing_attestation_builder.rs +++ b/eth2/types/src/test_utils/testing_attestation_builder.rs @@ -12,7 +12,7 @@ pub struct TestingAttestationBuilder { impl TestingAttestationBuilder { /// Create a new attestation builder. - pub fn new( + pub fn new( state: &BeaconState, committee: &[usize], slot: Slot, diff --git a/eth2/types/src/test_utils/testing_attestation_data_builder.rs b/eth2/types/src/test_utils/testing_attestation_data_builder.rs index 9d6bc5ec6..fbe79df1e 100644 --- a/eth2/types/src/test_utils/testing_attestation_data_builder.rs +++ b/eth2/types/src/test_utils/testing_attestation_data_builder.rs @@ -10,7 +10,7 @@ pub struct TestingAttestationDataBuilder { impl TestingAttestationDataBuilder { /// Configures a new `AttestationData` which attests to all of the same parameters as the /// state. - pub fn new( + pub fn new( state: &BeaconState, shard: u64, slot: Slot, diff --git a/eth2/types/src/test_utils/testing_beacon_block_builder.rs b/eth2/types/src/test_utils/testing_beacon_block_builder.rs index a2ea65949..18f57c589 100644 --- a/eth2/types/src/test_utils/testing_beacon_block_builder.rs +++ b/eth2/types/src/test_utils/testing_beacon_block_builder.rs @@ -82,7 +82,7 @@ impl TestingBeaconBlockBuilder { /// /// Note: the signed messages of the split committees will be identical -- it would be possible /// to aggregate these split attestations. - pub fn insert_attestations( + pub fn insert_attestations( &mut self, state: &BeaconState, secret_keys: &[&SecretKey], @@ -171,7 +171,7 @@ impl TestingBeaconBlockBuilder { } /// Insert a `Valid` deposit into the state. - pub fn insert_deposit( + pub fn insert_deposit( &mut self, amount: u64, index: u64, @@ -193,7 +193,7 @@ impl TestingBeaconBlockBuilder { } /// Insert a `Valid` exit into the state. - pub fn insert_exit( + pub fn insert_exit( &mut self, state: &BeaconState, validator_index: u64, @@ -214,7 +214,7 @@ impl TestingBeaconBlockBuilder { /// /// Note: this will set the validator to be withdrawable by directly modifying the state /// validator registry. This _may_ cause problems historic hashes, etc. - pub fn insert_transfer( + pub fn insert_transfer( &mut self, state: &BeaconState, from: u64, diff --git a/eth2/types/src/test_utils/testing_beacon_state_builder.rs b/eth2/types/src/test_utils/testing_beacon_state_builder.rs index 67f23a44c..727b70d93 100644 --- a/eth2/types/src/test_utils/testing_beacon_state_builder.rs +++ b/eth2/types/src/test_utils/testing_beacon_state_builder.rs @@ -25,12 +25,12 @@ pub fn keypairs_path() -> PathBuf { /// /// This struct should **never be used for production purposes.** #[derive(Clone)] -pub struct TestingBeaconStateBuilder { +pub struct TestingBeaconStateBuilder { state: BeaconState, keypairs: Vec, } -impl TestingBeaconStateBuilder { +impl TestingBeaconStateBuilder { /// Attempts to load validators from a file in `$HOME/.lighthouse/keypairs.raw_keypairs`. If /// the file is unavailable, it generates the keys at runtime. /// diff --git a/eth2/types/src/test_utils/testing_pending_attestation_builder.rs b/eth2/types/src/test_utils/testing_pending_attestation_builder.rs index 330203448..023b039b0 100644 --- a/eth2/types/src/test_utils/testing_pending_attestation_builder.rs +++ b/eth2/types/src/test_utils/testing_pending_attestation_builder.rs @@ -16,7 +16,7 @@ impl TestingPendingAttestationBuilder { /// /// * The aggregation and custody bitfields will all be empty, they need to be set with /// `Self::add_committee_participation`. - pub fn new( + pub fn new( state: &BeaconState, shard: u64, slot: Slot, diff --git a/validator_client/src/config.rs b/validator_client/src/config.rs index 66e9f2391..1e9450d59 100644 --- a/validator_client/src/config.rs +++ b/validator_client/src/config.rs @@ -7,8 +7,7 @@ use std::fs::File; use std::io::{Error, ErrorKind}; use std::path::PathBuf; use types::{ - BeaconStateTypes, ChainSpec, FewValidatorsStateTypes, FoundationStateTypes, - LighthouseTestnetStateTypes, + ChainSpec, EthSpec, FewValidatorsEthSpec, FoundationEthSpec, LighthouseTestnetEthSpec, }; /// Stores the core configuration for this validator instance. @@ -34,7 +33,7 @@ impl Default for Config { let server = "localhost:5051".to_string(); - let spec = FoundationStateTypes::spec(); + let spec = FoundationEthSpec::spec(); Self { data_dir, @@ -68,9 +67,9 @@ impl Config { if let Some(spec_str) = args.value_of("spec") { info!(log, "Using custom spec: {:?}", spec_str); config.spec = match spec_str { - "foundation" => FoundationStateTypes::spec(), - "few_validators" => FewValidatorsStateTypes::spec(), - "lighthouse_testnet" => LighthouseTestnetStateTypes::spec(), + "foundation" => FoundationEthSpec::spec(), + "few_validators" => FewValidatorsEthSpec::spec(), + "lighthouse_testnet" => LighthouseTestnetEthSpec::spec(), // Should be impossible due to clap's `possible_values(..)` function. _ => unreachable!(), }; From afa8fff31ab1382a2326c8c7605552f1df2ab066 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Mon, 13 May 2019 14:14:40 +1000 Subject: [PATCH 21/22] Remove old `tree_hash_vector` file --- eth2/types/src/lib.rs | 2 - eth2/types/src/tree_hash_vector.rs | 142 ----------------------------- 2 files changed, 144 deletions(-) delete mode 100644 eth2/types/src/tree_hash_vector.rs diff --git a/eth2/types/src/lib.rs b/eth2/types/src/lib.rs index c6109e166..79981c890 100644 --- a/eth2/types/src/lib.rs +++ b/eth2/types/src/lib.rs @@ -27,7 +27,6 @@ pub mod pending_attestation; pub mod proposer_slashing; pub mod slashable_attestation; pub mod transfer; -// pub mod tree_hash_vector; pub mod voluntary_exit; #[macro_use] pub mod slot_epoch_macros; @@ -66,7 +65,6 @@ pub use crate::slashable_attestation::SlashableAttestation; pub use crate::slot_epoch::{Epoch, Slot}; pub use crate::slot_height::SlotHeight; pub use crate::transfer::Transfer; -// pub use crate::tree_hash_vector::TreeHashVector; pub use crate::validator::Validator; pub use crate::voluntary_exit::VoluntaryExit; diff --git a/eth2/types/src/tree_hash_vector.rs b/eth2/types/src/tree_hash_vector.rs deleted file mode 100644 index 2600ff62f..000000000 --- a/eth2/types/src/tree_hash_vector.rs +++ /dev/null @@ -1,142 +0,0 @@ -use crate::test_utils::{RngCore, TestRandom}; -use cached_tree_hash::CachedTreeHash; -use serde_derive::{Deserialize, Serialize}; -use ssz::{Decodable, DecodeError, Encodable, SszStream}; -use std::ops::{Deref, DerefMut}; -use tree_hash::TreeHash; - -#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] -pub struct TreeHashVector(Vec); - -impl From> for TreeHashVector { - fn from(vec: Vec) -> TreeHashVector { - TreeHashVector(vec) - } -} - -impl Into> for TreeHashVector { - fn into(self) -> Vec { - self.0 - } -} - -impl Deref for TreeHashVector { - type Target = Vec; - - fn deref(&self) -> &Vec { - &self.0 - } -} - -impl DerefMut for TreeHashVector { - fn deref_mut(&mut self) -> &mut Vec { - &mut self.0 - } -} - -impl tree_hash::TreeHash for TreeHashVector -where - T: TreeHash, -{ - fn tree_hash_type() -> tree_hash::TreeHashType { - tree_hash::TreeHashType::Vector - } - - fn tree_hash_packed_encoding(&self) -> Vec { - unreachable!("Vector should never be packed.") - } - - fn tree_hash_packing_factor() -> usize { - unreachable!("Vector should never be packed.") - } - - fn tree_hash_root(&self) -> Vec { - tree_hash::impls::vec_tree_hash_root(self) - } -} - -impl CachedTreeHash for TreeHashVector -where - T: CachedTreeHash + TreeHash, -{ - fn new_tree_hash_cache( - &self, - depth: usize, - ) -> Result { - let (cache, _overlay) = cached_tree_hash::vec::new_tree_hash_cache(self, depth)?; - - Ok(cache) - } - - fn tree_hash_cache_schema(&self, depth: usize) -> cached_tree_hash::BTreeSchema { - cached_tree_hash::vec::produce_schema(self, depth) - } - - fn update_tree_hash_cache( - &self, - cache: &mut cached_tree_hash::TreeHashCache, - ) -> Result<(), cached_tree_hash::Error> { - cached_tree_hash::vec::update_tree_hash_cache(self, cache)?; - - Ok(()) - } -} - -impl Encodable for TreeHashVector -where - T: Encodable, -{ - fn ssz_append(&self, s: &mut SszStream) { - s.append_vec(self) - } -} - -impl Decodable for TreeHashVector -where - T: Decodable, -{ - fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), DecodeError> { - ssz::decode_ssz_list(bytes, index).and_then(|(vec, i)| Ok((vec.into(), i))) - } -} - -impl TestRandom for TreeHashVector -where - U: TestRandom, -{ - fn random_for_test(rng: &mut impl RngCore) -> Self { - TreeHashVector::from(vec![ - U::random_for_test(rng), - U::random_for_test(rng), - U::random_for_test(rng), - ]) - } -} - -#[cfg(test)] -mod test { - use super::*; - use tree_hash::TreeHash; - - #[test] - pub fn test_cached_tree_hash() { - let original = TreeHashVector::from(vec![1_u64, 2, 3, 4]); - - let mut cache = cached_tree_hash::TreeHashCache::new(&original).unwrap(); - - assert_eq!( - cache.tree_hash_root().unwrap().to_vec(), - original.tree_hash_root() - ); - - let modified = TreeHashVector::from(vec![1_u64, 1, 1, 1]); - - cache.update(&modified).unwrap(); - - assert_eq!( - cache.tree_hash_root().unwrap().to_vec(), - modified.tree_hash_root() - ); - } - -} From fcabef91da13fe31478be4b5e76e39b9830adf2a Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Mon, 13 May 2019 14:44:43 +1000 Subject: [PATCH 22/22] Use `E` for `EthSpec` trait, instead of `B` --- beacon_node/beacon_chain/src/beacon_chain.rs | 32 +++++++++---------- beacon_node/beacon_chain/src/checkpoint.rs | 10 +++--- .../testing_beacon_chain_builder.rs | 16 +++++----- beacon_node/client/src/lib.rs | 4 +-- .../db/src/stores/beacon_state_store.rs | 6 ++-- beacon_node/network/src/beacon_chain.rs | 18 +++++------ beacon_node/network/src/message_handler.rs | 10 +++--- beacon_node/network/src/service.rs | 8 ++--- beacon_node/network/src/sync/import_queue.rs | 8 ++--- beacon_node/network/src/sync/simple_sync.rs | 14 ++++---- beacon_node/rpc/src/attestation.rs | 6 ++-- beacon_node/rpc/src/beacon_block.rs | 6 ++-- beacon_node/rpc/src/beacon_chain.rs | 18 +++++------ beacon_node/rpc/src/beacon_node.rs | 6 ++-- beacon_node/rpc/src/lib.rs | 4 +-- beacon_node/rpc/src/validator.rs | 6 ++-- eth2/fork_choice/src/bitwise_lmd_ghost.rs | 10 +++--- eth2/fork_choice/src/optimized_lmd_ghost.rs | 10 +++--- eth2/fork_choice/src/slow_lmd_ghost.rs | 10 +++--- eth2/operation_pool/src/lib.rs | 18 +++++------ 20 files changed, 110 insertions(+), 110 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index b6eb1d2f7..db5ea1cdb 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -83,31 +83,31 @@ impl BlockProcessingOutcome { } } -pub struct BeaconChain { +pub struct BeaconChain { pub block_store: Arc>, pub state_store: Arc>, pub slot_clock: U, - pub op_pool: OperationPool, - canonical_head: RwLock>, - finalized_head: RwLock>, - pub state: RwLock>, + pub op_pool: OperationPool, + canonical_head: RwLock>, + finalized_head: RwLock>, + pub state: RwLock>, pub spec: ChainSpec, pub fork_choice: RwLock, } -impl BeaconChain +impl BeaconChain where T: ClientDB, U: SlotClock, F: ForkChoice, - B: EthSpec, + E: EthSpec, { /// Instantiate a new Beacon Chain, from genesis. pub fn from_genesis( state_store: Arc>, block_store: Arc>, slot_clock: U, - mut genesis_state: BeaconState, + mut genesis_state: BeaconState, genesis_block: BeaconBlock, spec: ChainSpec, fork_choice: F, @@ -230,7 +230,7 @@ where Err(BeaconStateError::SlotOutOfBounds) => { // Read the earliest historic state in the current slot. let earliest_historic_slot = - state.slot - Slot::from(B::SlotsPerHistoricalRoot::to_usize()); + state.slot - Slot::from(E::SlotsPerHistoricalRoot::to_usize()); // Load the earlier state from disk. let new_state_root = state.get_state_root(earliest_historic_slot)?; @@ -270,7 +270,7 @@ where &self, new_beacon_block: BeaconBlock, new_beacon_block_root: Hash256, - new_beacon_state: BeaconState, + new_beacon_state: BeaconState, new_beacon_state_root: Hash256, ) { debug!( @@ -292,7 +292,7 @@ where /// It is important to note that the `beacon_state` returned may not match the present slot. It /// is the state as it was when the head block was received, which could be some slots prior to /// now. - pub fn head(&self) -> RwLockReadGuard> { + pub fn head(&self) -> RwLockReadGuard> { self.canonical_head.read() } @@ -302,7 +302,7 @@ where /// state and calling `catchup_state` as it will not result in an old state being installed and /// then having it iteratively updated -- in such a case it's possible for another thread to /// find the state at an old slot. - pub fn update_state(&self, mut state: BeaconState) -> Result<(), Error> { + pub fn update_state(&self, mut state: BeaconState) -> Result<(), Error> { let present_slot = match self.slot_clock.present_slot() { Ok(Some(slot)) => slot, _ => return Err(Error::UnableToReadSlot), @@ -357,7 +357,7 @@ where &self, new_beacon_block: BeaconBlock, new_beacon_block_root: Hash256, - new_beacon_state: BeaconState, + new_beacon_state: BeaconState, new_beacon_state_root: Hash256, ) { let mut finalized_head = self.finalized_head.write(); @@ -371,7 +371,7 @@ where /// Returns a read-lock guarded `CheckPoint` struct for reading the justified head (as chosen, /// indirectly, by the fork-choice rule). - pub fn finalized_head(&self) -> RwLockReadGuard> { + pub fn finalized_head(&self) -> RwLockReadGuard> { self.finalized_head.read() } @@ -664,7 +664,7 @@ where pub fn produce_block( &self, randao_reveal: Signature, - ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { + ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { debug!("Producing block at slot {}...", self.state.read().slot); let mut state = self.state.read().clone(); @@ -759,7 +759,7 @@ where /// /// This could be a very expensive operation and should only be done in testing/analysis /// activities. - pub fn chain_dump(&self) -> Result>, Error> { + pub fn chain_dump(&self) -> Result>, Error> { let mut dump = vec![]; let mut last_slot = CheckPoint { diff --git a/beacon_node/beacon_chain/src/checkpoint.rs b/beacon_node/beacon_chain/src/checkpoint.rs index 7bed5b5ce..c069ac104 100644 --- a/beacon_node/beacon_chain/src/checkpoint.rs +++ b/beacon_node/beacon_chain/src/checkpoint.rs @@ -4,19 +4,19 @@ use types::{BeaconBlock, BeaconState, EthSpec, Hash256}; /// Represents some block and it's associated state. Generally, this will be used for tracking the /// head, justified head and finalized head. #[derive(Clone, Serialize, PartialEq, Debug)] -pub struct CheckPoint { +pub struct CheckPoint { pub beacon_block: BeaconBlock, pub beacon_block_root: Hash256, - pub beacon_state: BeaconState, + pub beacon_state: BeaconState, pub beacon_state_root: Hash256, } -impl CheckPoint { +impl CheckPoint { /// Create a new checkpoint. pub fn new( beacon_block: BeaconBlock, beacon_block_root: Hash256, - beacon_state: BeaconState, + beacon_state: BeaconState, beacon_state_root: Hash256, ) -> Self { Self { @@ -32,7 +32,7 @@ impl CheckPoint { &mut self, beacon_block: BeaconBlock, beacon_block_root: Hash256, - beacon_state: BeaconState, + beacon_state: BeaconState, beacon_state_root: Hash256, ) { self.beacon_block = beacon_block; diff --git a/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs b/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs index b617ed0d7..f7ff3cdae 100644 --- a/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs +++ b/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs @@ -10,15 +10,15 @@ use tree_hash::TreeHash; use types::*; use types::{test_utils::TestingBeaconStateBuilder, EthSpec, FewValidatorsEthSpec}; -type TestingBeaconChain = - BeaconChain, B>; +type TestingBeaconChain = + BeaconChain, E>; -pub struct TestingBeaconChainBuilder { - state_builder: TestingBeaconStateBuilder, +pub struct TestingBeaconChainBuilder { + state_builder: TestingBeaconStateBuilder, } -impl TestingBeaconChainBuilder { - pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain { +impl TestingBeaconChainBuilder { + pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain { let db = Arc::new(MemoryDB::open()); let block_store = Arc::new(BeaconBlockStore::new(db.clone())); let state_store = Arc::new(BeaconStateStore::new(db.clone())); @@ -44,8 +44,8 @@ impl TestingBeaconChainBuilder { } } -impl From> for TestingBeaconChainBuilder { - fn from(state_builder: TestingBeaconStateBuilder) -> TestingBeaconChainBuilder { +impl From> for TestingBeaconChainBuilder { + fn from(state_builder: TestingBeaconStateBuilder) -> TestingBeaconChainBuilder { TestingBeaconChainBuilder { state_builder } } } diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index 166f1a948..5d7c221ef 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -144,12 +144,12 @@ impl Client { } } -fn do_state_catchup(chain: &Arc>, log: &slog::Logger) +fn do_state_catchup(chain: &Arc>, log: &slog::Logger) where T: ClientDB, U: SlotClock, F: ForkChoice, - B: EthSpec, + E: EthSpec, { if let Some(genesis_height) = chain.slots_since_genesis() { let result = chain.catchup_state(); diff --git a/beacon_node/db/src/stores/beacon_state_store.rs b/beacon_node/db/src/stores/beacon_state_store.rs index c0d37edd9..1b088e4a9 100644 --- a/beacon_node/db/src/stores/beacon_state_store.rs +++ b/beacon_node/db/src/stores/beacon_state_store.rs @@ -19,14 +19,14 @@ impl BeaconStateStore { Self { db } } - pub fn get_deserialized( + pub fn get_deserialized( &self, hash: &Hash256, - ) -> Result>, DBError> { + ) -> Result>, DBError> { match self.get(&hash)? { None => Ok(None), Some(ssz) => { - let state = decode::>(&ssz).map_err(|_| DBError { + let state = decode::>(&ssz).map_err(|_| DBError { message: "Bad State SSZ.".to_string(), })?; Ok(Some(state)) diff --git a/beacon_node/network/src/beacon_chain.rs b/beacon_node/network/src/beacon_chain.rs index db809086a..a98aa73de 100644 --- a/beacon_node/network/src/beacon_chain.rs +++ b/beacon_node/network/src/beacon_chain.rs @@ -15,14 +15,14 @@ use types::{ pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome, InvalidBlock}; /// The network's API to the beacon chain. -pub trait BeaconChain: Send + Sync { +pub trait BeaconChain: Send + Sync { fn get_spec(&self) -> &ChainSpec; - fn get_state(&self) -> RwLockReadGuard>; + fn get_state(&self) -> RwLockReadGuard>; fn slot(&self) -> Slot; - fn head(&self) -> RwLockReadGuard>; + fn head(&self) -> RwLockReadGuard>; fn get_block(&self, block_root: &Hash256) -> Result, BeaconChainError>; @@ -30,7 +30,7 @@ pub trait BeaconChain: Send + Sync { fn best_block_root(&self) -> Hash256; - fn finalized_head(&self) -> RwLockReadGuard>; + fn finalized_head(&self) -> RwLockReadGuard>; fn finalized_epoch(&self) -> Epoch; @@ -64,18 +64,18 @@ pub trait BeaconChain: Send + Sync { fn is_new_block_root(&self, beacon_block_root: &Hash256) -> Result; } -impl BeaconChain for RawBeaconChain +impl BeaconChain for RawBeaconChain where T: ClientDB + Sized, U: SlotClock, F: ForkChoice, - B: EthSpec, + E: EthSpec, { fn get_spec(&self) -> &ChainSpec { &self.spec } - fn get_state(&self) -> RwLockReadGuard> { + fn get_state(&self) -> RwLockReadGuard> { self.state.read() } @@ -83,7 +83,7 @@ where self.get_state().slot } - fn head(&self) -> RwLockReadGuard> { + fn head(&self) -> RwLockReadGuard> { self.head() } @@ -95,7 +95,7 @@ where self.get_state().finalized_epoch } - fn finalized_head(&self) -> RwLockReadGuard> { + fn finalized_head(&self) -> RwLockReadGuard> { self.finalized_head() } diff --git a/beacon_node/network/src/message_handler.rs b/beacon_node/network/src/message_handler.rs index 35743fe15..a7d0ff2a1 100644 --- a/beacon_node/network/src/message_handler.rs +++ b/beacon_node/network/src/message_handler.rs @@ -21,11 +21,11 @@ use types::EthSpec; // const HELLO_TIMEOUT: Duration = Duration::from_secs(30); /// Handles messages received from the network and client and organises syncing. -pub struct MessageHandler { +pub struct MessageHandler { /// Currently loaded and initialised beacon chain. - _chain: Arc>, + _chain: Arc>, /// The syncing framework. - sync: SimpleSync, + sync: SimpleSync, /// The context required to send messages to, and process messages from peers. network_context: NetworkContext, /// The `MessageHandler` logger. @@ -45,10 +45,10 @@ pub enum HandlerMessage { PubsubMessage(PeerId, Box), } -impl MessageHandler { +impl MessageHandler { /// Initializes and runs the MessageHandler. pub fn spawn( - beacon_chain: Arc>, + beacon_chain: Arc>, network_send: crossbeam_channel::Sender, executor: &tokio::runtime::TaskExecutor, log: slog::Logger, diff --git a/beacon_node/network/src/service.rs b/beacon_node/network/src/service.rs index 89d1e1526..50454a875 100644 --- a/beacon_node/network/src/service.rs +++ b/beacon_node/network/src/service.rs @@ -16,17 +16,17 @@ use tokio::runtime::TaskExecutor; use types::{EthSpec, Topic}; /// Service that handles communication between internal services and the eth2_libp2p network service. -pub struct Service { +pub struct Service { //libp2p_service: Arc>, _libp2p_exit: oneshot::Sender<()>, network_send: crossbeam_channel::Sender, - _phantom: PhantomData, //message_handler: MessageHandler, + _phantom: PhantomData, //message_handler: MessageHandler, //message_handler_send: Sender } -impl Service { +impl Service { pub fn new( - beacon_chain: Arc>, + beacon_chain: Arc>, config: &NetworkConfig, executor: &TaskExecutor, log: slog::Logger, diff --git a/beacon_node/network/src/sync/import_queue.rs b/beacon_node/network/src/sync/import_queue.rs index 1fffd8763..6c2fc33ee 100644 --- a/beacon_node/network/src/sync/import_queue.rs +++ b/beacon_node/network/src/sync/import_queue.rs @@ -19,8 +19,8 @@ use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, EthSpec, Hash256, S /// `BeaconBlockBody` as the key. /// - It is possible for multiple distinct blocks to have identical `BeaconBlockBodies`. Therefore /// we cannot use a `HashMap` keyed by the root of `BeaconBlockBody`. -pub struct ImportQueue { - pub chain: Arc>, +pub struct ImportQueue { + pub chain: Arc>, /// Partially imported blocks, keyed by the root of `BeaconBlockBody`. pub partials: Vec, /// Time before a queue entry is considered state. @@ -29,9 +29,9 @@ pub struct ImportQueue { log: slog::Logger, } -impl ImportQueue { +impl ImportQueue { /// Return a new, empty queue. - pub fn new(chain: Arc>, stale_time: Duration, log: slog::Logger) -> Self { + pub fn new(chain: Arc>, stale_time: Duration, log: slog::Logger) -> Self { Self { chain, partials: vec![], diff --git a/beacon_node/network/src/sync/simple_sync.rs b/beacon_node/network/src/sync/simple_sync.rs index 3f4fb7aae..d44ffd4b7 100644 --- a/beacon_node/network/src/sync/simple_sync.rs +++ b/beacon_node/network/src/sync/simple_sync.rs @@ -88,8 +88,8 @@ impl From for PeerSyncInfo { } } -impl From<&Arc>> for PeerSyncInfo { - fn from(chain: &Arc>) -> PeerSyncInfo { +impl From<&Arc>> for PeerSyncInfo { + fn from(chain: &Arc>) -> PeerSyncInfo { Self::from(chain.hello_message()) } } @@ -103,22 +103,22 @@ pub enum SyncState { } /// Simple Syncing protocol. -pub struct SimpleSync { +pub struct SimpleSync { /// A reference to the underlying beacon chain. - chain: Arc>, + chain: Arc>, /// A mapping of Peers to their respective PeerSyncInfo. known_peers: HashMap, /// A queue to allow importing of blocks - import_queue: ImportQueue, + import_queue: ImportQueue, /// The current state of the syncing protocol. state: SyncState, /// Sync logger. log: slog::Logger, } -impl SimpleSync { +impl SimpleSync { /// Instantiate a `SimpleSync` instance, with no peers and an empty queue. - pub fn new(beacon_chain: Arc>, log: &slog::Logger) -> Self { + pub fn new(beacon_chain: Arc>, log: &slog::Logger) -> Self { let sync_logger = log.new(o!("Service"=> "Sync")); let queue_item_stale_time = Duration::from_secs(QUEUE_STALE_SECS); diff --git a/beacon_node/rpc/src/attestation.rs b/beacon_node/rpc/src/attestation.rs index 30f04afba..5b6d93a95 100644 --- a/beacon_node/rpc/src/attestation.rs +++ b/beacon_node/rpc/src/attestation.rs @@ -12,12 +12,12 @@ use std::sync::Arc; use types::{Attestation, EthSpec}; #[derive(Clone)] -pub struct AttestationServiceInstance { - pub chain: Arc>, +pub struct AttestationServiceInstance { + pub chain: Arc>, pub log: slog::Logger, } -impl AttestationService for AttestationServiceInstance { +impl AttestationService for AttestationServiceInstance { /// Produce the `AttestationData` for signing by a validator. fn produce_attestation_data( &mut self, diff --git a/beacon_node/rpc/src/beacon_block.rs b/beacon_node/rpc/src/beacon_block.rs index 727da9542..370dce60d 100644 --- a/beacon_node/rpc/src/beacon_block.rs +++ b/beacon_node/rpc/src/beacon_block.rs @@ -16,13 +16,13 @@ use std::sync::Arc; use types::{BeaconBlock, EthSpec, Signature, Slot}; #[derive(Clone)] -pub struct BeaconBlockServiceInstance { - pub chain: Arc>, +pub struct BeaconBlockServiceInstance { + pub chain: Arc>, pub network_chan: crossbeam_channel::Sender, pub log: Logger, } -impl BeaconBlockService for BeaconBlockServiceInstance { +impl BeaconBlockService for BeaconBlockServiceInstance { /// Produce a `BeaconBlock` for signing by a validator. fn produce_beacon_block( &mut self, diff --git a/beacon_node/rpc/src/beacon_chain.rs b/beacon_node/rpc/src/beacon_chain.rs index e10522d04..7e75b32ce 100644 --- a/beacon_node/rpc/src/beacon_chain.rs +++ b/beacon_node/rpc/src/beacon_chain.rs @@ -11,12 +11,12 @@ pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome}; use types::{Attestation, AttestationData, BeaconBlock, EthSpec}; /// The RPC's API to the beacon chain. -pub trait BeaconChain: Send + Sync { +pub trait BeaconChain: Send + Sync { fn get_spec(&self) -> &ChainSpec; - fn get_state(&self) -> RwLockReadGuard>; + fn get_state(&self) -> RwLockReadGuard>; - fn get_mut_state(&self) -> RwLockWriteGuard>; + fn get_mut_state(&self) -> RwLockWriteGuard>; fn process_block(&self, block: BeaconBlock) -> Result; @@ -24,7 +24,7 @@ pub trait BeaconChain: Send + Sync { fn produce_block( &self, randao_reveal: Signature, - ) -> Result<(BeaconBlock, BeaconState), BlockProductionError>; + ) -> Result<(BeaconBlock, BeaconState), BlockProductionError>; fn produce_attestation_data(&self, shard: u64) -> Result; @@ -34,22 +34,22 @@ pub trait BeaconChain: Send + Sync { ) -> Result<(), AttestationValidationError>; } -impl BeaconChain for RawBeaconChain +impl BeaconChain for RawBeaconChain where T: ClientDB + Sized, U: SlotClock, F: ForkChoice, - B: EthSpec, + E: EthSpec, { fn get_spec(&self) -> &ChainSpec { &self.spec } - fn get_state(&self) -> RwLockReadGuard> { + fn get_state(&self) -> RwLockReadGuard> { self.state.read() } - fn get_mut_state(&self) -> RwLockWriteGuard> { + fn get_mut_state(&self) -> RwLockWriteGuard> { self.state.write() } @@ -63,7 +63,7 @@ where fn produce_block( &self, randao_reveal: Signature, - ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { + ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { self.produce_block(randao_reveal) } diff --git a/beacon_node/rpc/src/beacon_node.rs b/beacon_node/rpc/src/beacon_node.rs index 873d1c478..2ca39ae51 100644 --- a/beacon_node/rpc/src/beacon_node.rs +++ b/beacon_node/rpc/src/beacon_node.rs @@ -8,12 +8,12 @@ use std::sync::Arc; use types::EthSpec; #[derive(Clone)] -pub struct BeaconNodeServiceInstance { - pub chain: Arc>, +pub struct BeaconNodeServiceInstance { + pub chain: Arc>, pub log: slog::Logger, } -impl BeaconNodeService for BeaconNodeServiceInstance { +impl BeaconNodeService for BeaconNodeServiceInstance { /// Provides basic node information. fn info(&mut self, ctx: RpcContext, _req: Empty, sink: UnarySink) { trace!(self.log, "Node info requested via RPC"); diff --git a/beacon_node/rpc/src/lib.rs b/beacon_node/rpc/src/lib.rs index d46dee7b5..f1d5e9c88 100644 --- a/beacon_node/rpc/src/lib.rs +++ b/beacon_node/rpc/src/lib.rs @@ -23,11 +23,11 @@ use std::sync::Arc; use tokio::runtime::TaskExecutor; use types::EthSpec; -pub fn start_server( +pub fn start_server( config: &RPCConfig, executor: &TaskExecutor, network_chan: crossbeam_channel::Sender, - beacon_chain: Arc>, + beacon_chain: Arc>, log: &slog::Logger, ) -> exit_future::Signal { let log = log.new(o!("Service"=>"RPC")); diff --git a/beacon_node/rpc/src/validator.rs b/beacon_node/rpc/src/validator.rs index e2f8d098f..6a145d32d 100644 --- a/beacon_node/rpc/src/validator.rs +++ b/beacon_node/rpc/src/validator.rs @@ -10,13 +10,13 @@ use std::sync::Arc; use types::{Epoch, EthSpec, RelativeEpoch}; #[derive(Clone)] -pub struct ValidatorServiceInstance { - pub chain: Arc>, +pub struct ValidatorServiceInstance { + pub chain: Arc>, pub log: slog::Logger, } //TODO: Refactor Errors -impl ValidatorService for ValidatorServiceInstance { +impl ValidatorService for ValidatorServiceInstance { /// For a list of validator public keys, this function returns the slot at which each /// validator must propose a block, attest to a shard, their shard committee and the shard they /// need to attest to. diff --git a/eth2/fork_choice/src/bitwise_lmd_ghost.rs b/eth2/fork_choice/src/bitwise_lmd_ghost.rs index 3eb8bff8c..0bbac6bb6 100644 --- a/eth2/fork_choice/src/bitwise_lmd_ghost.rs +++ b/eth2/fork_choice/src/bitwise_lmd_ghost.rs @@ -34,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 { } /// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm. -pub struct BitwiseLMDGhost { +pub struct BitwiseLMDGhost { /// A cache of known ancestors at given heights for a specific block. //TODO: Consider FnvHashMap cache: HashMap, Hash256>, @@ -51,10 +51,10 @@ pub struct BitwiseLMDGhost { /// State storage access. state_store: Arc>, max_known_height: SlotHeight, - _phantom: PhantomData, + _phantom: PhantomData, } -impl BitwiseLMDGhost +impl BitwiseLMDGhost where T: ClientDB + Sized, { @@ -88,7 +88,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state: BeaconState = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -243,7 +243,7 @@ where } } -impl ForkChoice for BitwiseLMDGhost { +impl ForkChoice for BitwiseLMDGhost { fn add_block( &mut self, block: &BeaconBlock, diff --git a/eth2/fork_choice/src/optimized_lmd_ghost.rs b/eth2/fork_choice/src/optimized_lmd_ghost.rs index a471452c8..3f585e3c1 100644 --- a/eth2/fork_choice/src/optimized_lmd_ghost.rs +++ b/eth2/fork_choice/src/optimized_lmd_ghost.rs @@ -34,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 { } /// Stores the necessary data structures to run the optimised lmd ghost algorithm. -pub struct OptimizedLMDGhost { +pub struct OptimizedLMDGhost { /// A cache of known ancestors at given heights for a specific block. //TODO: Consider FnvHashMap cache: HashMap, Hash256>, @@ -51,10 +51,10 @@ pub struct OptimizedLMDGhost { /// State storage access. state_store: Arc>, max_known_height: SlotHeight, - _phantom: PhantomData, + _phantom: PhantomData, } -impl OptimizedLMDGhost +impl OptimizedLMDGhost where T: ClientDB + Sized, { @@ -88,7 +88,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state: BeaconState = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -214,7 +214,7 @@ where } } -impl ForkChoice for OptimizedLMDGhost { +impl ForkChoice for OptimizedLMDGhost { fn add_block( &mut self, block: &BeaconBlock, diff --git a/eth2/fork_choice/src/slow_lmd_ghost.rs b/eth2/fork_choice/src/slow_lmd_ghost.rs index c11ef3eec..c9aaa70d1 100644 --- a/eth2/fork_choice/src/slow_lmd_ghost.rs +++ b/eth2/fork_choice/src/slow_lmd_ghost.rs @@ -13,7 +13,7 @@ use types::{BeaconBlock, BeaconState, ChainSpec, EthSpec, Hash256, Slot}; //TODO: Pruning and syncing -pub struct SlowLMDGhost { +pub struct SlowLMDGhost { /// The latest attestation targets as a map of validator index to block hash. //TODO: Could this be a fixed size vec latest_attestation_targets: HashMap, @@ -23,10 +23,10 @@ pub struct SlowLMDGhost { block_store: Arc>, /// State storage access. state_store: Arc>, - _phantom: PhantomData, + _phantom: PhantomData, } -impl SlowLMDGhost +impl SlowLMDGhost where T: ClientDB + Sized, { @@ -57,7 +57,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state: BeaconState = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -108,7 +108,7 @@ where } } -impl ForkChoice for SlowLMDGhost { +impl ForkChoice for SlowLMDGhost { /// Process when a block is added fn add_block( &mut self, diff --git a/eth2/operation_pool/src/lib.rs b/eth2/operation_pool/src/lib.rs index cbaabe0cd..c5653e7f9 100644 --- a/eth2/operation_pool/src/lib.rs +++ b/eth2/operation_pool/src/lib.rs @@ -539,10 +539,10 @@ where /// The keys in the map should be validator indices, which will be looked up /// in the state's validator registry and then passed to `prune_if`. /// Entries for unknown validators will be kept. -fn prune_validator_hash_map( +fn prune_validator_hash_map( map: &mut HashMap, prune_if: F, - finalized_state: &BeaconState, + finalized_state: &BeaconState, ) where F: Fn(&Validator) -> bool, { @@ -722,12 +722,12 @@ mod tests { /// Create a signed attestation for use in tests. /// Signed by all validators in `committee[signing_range]` and `committee[extra_signer]`. - fn signed_attestation, B: EthSpec>( + fn signed_attestation, E: EthSpec>( committee: &CrosslinkCommittee, keypairs: &[Keypair], signing_range: R, slot: Slot, - state: &BeaconState, + state: &BeaconState, spec: &ChainSpec, extra_signer: Option, ) -> Attestation { @@ -754,10 +754,10 @@ mod tests { } /// Test state for attestation-related tests. - fn attestation_test_state( + fn attestation_test_state( num_committees: usize, - ) -> (BeaconState, Vec, ChainSpec) { - let spec = B::spec(); + ) -> (BeaconState, Vec, ChainSpec) { + let spec = E::spec(); let num_validators = num_committees * (spec.slots_per_epoch * spec.target_committee_size) as usize; @@ -775,9 +775,9 @@ mod tests { } /// Set the latest crosslink in the state to match the attestation. - fn fake_latest_crosslink( + fn fake_latest_crosslink( att: &Attestation, - state: &mut BeaconState, + state: &mut BeaconState, spec: &ChainSpec, ) { state.latest_crosslinks[att.data.shard as usize] = Crosslink {