From 6847e68c5eb1ff4bd949635c4cc963c722ec4dc5 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 13 Dec 2018 12:27:45 +1100 Subject: [PATCH] Move genesis code into its own crate --- Cargo.toml | 1 + beacon_chain/chain/src/lib.rs | 1 - beacon_chain/genesis/Cargo.toml | 11 ++ .../src/beacon_state.rs} | 146 +++++++----------- beacon_chain/genesis/src/lib.rs | 7 + beacon_chain/spec/src/lib.rs | 1 + 6 files changed, 75 insertions(+), 92 deletions(-) create mode 100644 beacon_chain/genesis/Cargo.toml rename beacon_chain/{chain/src/genesis.rs => genesis/src/beacon_state.rs} (51%) create mode 100644 beacon_chain/genesis/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 856c2dae3..963c5bc59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ name = "lighthouse" members = [ "beacon_chain/attestation_validation", "beacon_chain/chain", + "beacon_chain/genesis", "beacon_chain/naive_fork_choice", "beacon_chain/spec", "beacon_chain/state-transition", diff --git a/beacon_chain/chain/src/lib.rs b/beacon_chain/chain/src/lib.rs index 5fc9dc077..adfa682c7 100644 --- a/beacon_chain/chain/src/lib.rs +++ b/beacon_chain/chain/src/lib.rs @@ -9,7 +9,6 @@ extern crate validator_induction; extern crate validator_shuffling; mod block_processing; -mod genesis; mod maps; mod stores; mod transition; diff --git a/beacon_chain/genesis/Cargo.toml b/beacon_chain/genesis/Cargo.toml new file mode 100644 index 000000000..f8708af1f --- /dev/null +++ b/beacon_chain/genesis/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "genesis" +version = "0.1.0" +authors = ["Paul Hauner "] + +[dependencies] +bls = { path = "../utils/bls" } +spec = { path = "../spec" } +types = { path = "../types" } +validator_induction = { path = "../validator_induction" } +validator_shuffling = { path = "../validator_shuffling" } diff --git a/beacon_chain/chain/src/genesis.rs b/beacon_chain/genesis/src/beacon_state.rs similarity index 51% rename from beacon_chain/chain/src/genesis.rs rename to beacon_chain/genesis/src/beacon_state.rs index 0444c9f29..d95136c6f 100644 --- a/beacon_chain/chain/src/genesis.rs +++ b/beacon_chain/genesis/src/beacon_state.rs @@ -7,24 +7,16 @@ use validator_shuffling::{shard_and_committees_for_cycle, ValidatorAssignmentErr #[derive(Debug, PartialEq)] pub enum Error { + NoValidators, ValidationAssignmentError(ValidatorAssignmentError), NotImplemented, } -impl From for Error { - fn from(e: ValidatorAssignmentError) -> Error { - Error::ValidationAssignmentError(e) - } -} - -/// Initialize a new ChainHead with genesis parameters. -/// -/// Used when syncing a chain from scratch. -pub fn genesis_states( +pub fn genesis_beacon_state( spec: &ChainSpec, - initial_validators: Vec, + initial_validators: &[ValidatorRegistration], genesis_time: u64, - processed_pow_receipt_root: Hash256, + processed_pow_receipt_root: &Hash256, ) -> Result { /* * Parse the ValidatorRegistrations into ValidatorRecords and induct them. @@ -33,7 +25,7 @@ pub fn genesis_states( */ let validators = { let mut inductor = ValidatorInductor::new(0, spec.shard_count, vec![]); - for registration in &initial_validators { + for registration in initial_validators { let _ = inductor.induct(®istration, ValidatorStatus::Active); } inductor.to_vec() @@ -45,7 +37,7 @@ pub fn genesis_states( * Crystallizedstate stores two cycles, so we simply repeat the same assignment twice. */ let _shard_and_committee_for_slots = { - let mut a = shard_and_committees_for_cycle(&vec![0; 32], &validators, 0, &spec)?; + let mut a = shard_and_committees_for_cycle(&[0; 32], &validators, 0, &spec)?; let mut b = a.clone(); a.append(&mut b); a @@ -79,15 +71,15 @@ pub fn genesis_states( */ randao_mix: spec.zero_hash, next_seed: spec.zero_hash, - shard_committees_at_slot: vec![], + shard_committees_at_slots: vec![], persistent_committees: vec![], - persisten_committee_reassignments: vec![], + persistent_committee_reassignments: vec![], /* * Finality */ previous_justified_slot: spec.initial_slot_number, justified_slot: spec.initial_slot_number, - justified_bitfield: 0, + justification_bitfield: 0, finalized_slot: spec.initial_slot_number, /* * Recent state @@ -99,59 +91,28 @@ pub fn genesis_states( /* * PoW receipt root */ - processed_pow_receipt_root, + processed_pow_receipt_root: *processed_pow_receipt_root, candidate_pow_receipt_roots: vec![], }) } +impl From for Error { + fn from(e: ValidatorAssignmentError) -> Error { + Error::ValidationAssignmentError(e) + } +} + #[cfg(test)] mod tests { extern crate bls; extern crate validator_induction; - // TODO: implement genesis for `BeaconState` - // https://github.com/sigp/lighthouse/issues/99 - // - /* use self::bls::{create_proof_of_possession, Keypair}; use super::*; use types::{Address, Hash256, ValidatorRegistration}; - #[test] - fn test_genesis_no_validators() { - let config = ChainConfig::standard(); - let (act, cry) = genesis_states(&config).unwrap(); - - assert_eq!(cry.validator_set_change_slot, 0); - assert_eq!(cry.validators.len(), 0); - assert_eq!(cry.crosslinks.len(), config.shard_count as usize); - for cl in cry.crosslinks { - assert_eq!(cl.recently_changed, false); - assert_eq!(cl.slot, 0); - assert_eq!(cl.hash, Hash256::zero()); - } - assert_eq!(cry.last_state_recalculation_slot, 0); - assert_eq!(cry.last_finalized_slot, 0); - assert_eq!(cry.last_justified_slot, 0); - assert_eq!(cry.justified_streak, 0); - assert_eq!( - cry.shard_and_committee_for_slots.len(), - (config.cycle_length as usize) * 2 - ); - assert_eq!(cry.deposits_penalized_in_period.len(), 0); - assert_eq!(cry.validator_set_delta_hash_chain, Hash256::zero()); - assert_eq!(cry.pre_fork_version, INITIAL_FORK_VERSION); - assert_eq!(cry.post_fork_version, INITIAL_FORK_VERSION); - assert_eq!(cry.fork_slot_number, 0); - - assert_eq!(act.pending_attestations.len(), 0); - assert_eq!(act.pending_specials.len(), 0); - assert_eq!( - act.recent_block_hashes, - vec![Hash256::zero(); config.cycle_length as usize] - ); - assert_eq!(act.randao_mix, Hash256::zero()); - } + // TODO: enhance these tests. + // https://github.com/sigp/lighthouse/issues/117 fn random_registration() -> ValidatorRegistration { let keypair = Keypair::random(); @@ -164,45 +125,48 @@ mod tests { } } - #[test] - fn test_genesis_valid_validators() { - let mut config = ChainConfig::standard(); - let validator_count = 5; - - for _ in 0..validator_count { - config.initial_validators.push(random_registration()); + fn random_registrations(n: usize) -> Vec { + let mut output = Vec::with_capacity(n); + for _ in 0..n { + output.push(random_registration()) } - - let (_, cry) = genesis_states(&config).unwrap(); - - assert_eq!(cry.validators.len(), validator_count); + output } #[test] - fn test_genesis_invalid_validators() { - let mut config = ChainConfig::standard(); - let good_validator_count = 5; + fn test_genesis() { + let spec = ChainSpec::foundation(); + let genesis_time = 42; + let initial_validators = random_registrations(4); + let processed_pow_receipt_root = Hash256::from("pow_root".as_bytes()); - for _ in 0..good_validator_count { - config.initial_validators.push(random_registration()); - } + let state = genesis_beacon_state( + &spec, + &initial_validators, + genesis_time, + &processed_pow_receipt_root, + ).unwrap(); - let mut bad_v = random_registration(); - let bad_kp = Keypair::random(); - bad_v.proof_of_possession = create_proof_of_possession(&bad_kp); - config.initial_validators.push(bad_v); - - let mut bad_v = random_registration(); - bad_v.withdrawal_shard = config.shard_count + 1; - config.initial_validators.push(bad_v); - - let (_, cry) = genesis_states(&config).unwrap(); - - assert!( - config.initial_validators.len() != good_validator_count, - "test is invalid" - ); - assert_eq!(cry.validators.len(), good_validator_count); + assert_eq!(state.validator_registry.len(), 4); + } + + #[test] + fn test_genesis_bad_validator() { + let spec = ChainSpec::foundation(); + let genesis_time = 42; + let mut initial_validators = random_registrations(5); + let processed_pow_receipt_root = Hash256::from("pow_root".as_bytes()); + + let random_kp = Keypair::random(); + initial_validators[4].proof_of_possession = create_proof_of_possession(&random_kp); + + let state = genesis_beacon_state( + &spec, + &initial_validators, + genesis_time, + &processed_pow_receipt_root, + ).unwrap(); + + assert_eq!(state.validator_registry.len(), 4); } - */ } diff --git a/beacon_chain/genesis/src/lib.rs b/beacon_chain/genesis/src/lib.rs new file mode 100644 index 000000000..54d45dae8 --- /dev/null +++ b/beacon_chain/genesis/src/lib.rs @@ -0,0 +1,7 @@ +extern crate spec; +extern crate types; +extern crate validator_induction; +extern crate validator_shuffling; + +pub mod beacon_state; + diff --git a/beacon_chain/spec/src/lib.rs b/beacon_chain/spec/src/lib.rs index a15575115..e8f3cfdc3 100644 --- a/beacon_chain/spec/src/lib.rs +++ b/beacon_chain/spec/src/lib.rs @@ -4,6 +4,7 @@ mod foundation; use types::{Address, Hash256}; +#[derive(PartialEq, Debug)] pub struct ChainSpec { /* * Misc