From d12b5249e0496c6b87b5f6e38c8831c4ea258c66 Mon Sep 17 00:00:00 2001 From: Kirk Baird Date: Mon, 14 Jan 2019 16:32:55 +1100 Subject: [PATCH 1/4] Add genesis tests pre modifying the beancon structs --- beacon_chain/genesis/Cargo.toml | 1 + beacon_chain/genesis/src/beacon_block.rs | 54 ++++++++++++ beacon_chain/genesis/src/beacon_state.rs | 105 ++++++++++++++++++++++- 3 files changed, 159 insertions(+), 1 deletion(-) diff --git a/beacon_chain/genesis/Cargo.toml b/beacon_chain/genesis/Cargo.toml index 499333979..dbfd7e1fc 100644 --- a/beacon_chain/genesis/Cargo.toml +++ b/beacon_chain/genesis/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] bls = { path = "../utils/bls" } +bls-aggregates = { git = "https://github.com/sigp/signature-schemes" } spec = { path = "../spec" } ssz = { path = "../utils/ssz" } types = { path = "../types" } diff --git a/beacon_chain/genesis/src/beacon_block.rs b/beacon_chain/genesis/src/beacon_block.rs index 696ac6499..3ec321237 100644 --- a/beacon_chain/genesis/src/beacon_block.rs +++ b/beacon_chain/genesis/src/beacon_block.rs @@ -47,4 +47,58 @@ mod tests { // This only checks that the function runs without panic. genesis_beacon_block(state_root, &spec); } + + // Tests parent_root, randao_reveal, deposit_root are the zero hash after creation and slot == 0 + #[test] + fn test_zero_items() { + let spec = ChainSpec::foundation(); + + // Note: state_root will not be available without a state (test in beacon_state) + let state_root = Hash256::zero(); + + let genesis_block = genesis_beacon_block(state_root, &spec); + + assert!(genesis_block.parent_root.is_zero()); + assert!(genesis_block.randao_reveal.is_zero()); + assert!(genesis_block.slot == 0); + // assert!(genesis_block.depsoit_root.is_zero()); + + } + + #[test] + fn test_beacon_body() { + let spec = ChainSpec::foundation(); + + // Note: state_root will not be available without a state (test in beacon_state) + let state_root = Hash256::zero(); + + let genesis_block = genesis_beacon_block(state_root, &spec); + + assert!(genesis_block.body.proposer_slashings.is_empty()); + assert!(genesis_block.body.casper_slashings.is_empty()); + assert!(genesis_block.body.attestations.is_empty()); + assert!(genesis_block.body.deposits.is_empty()); + assert!(genesis_block.body.exits.is_empty()); + // Specs have changed to include 3 more variables in BeaconBody to be added later + } + + #[test] + fn test_signature() { + let spec = ChainSpec::foundation(); + + // Note: state_root will not be available without a state (test in beacon_state) + let state_root = Hash256::zero(); + + let genesis_block = genesis_beacon_block(state_root, &spec); + + // Signature should consist of [bytes48(0), bytes48(0)] + // Note this is implemented using Apache Milagro BLS which requires one extra byte -> 97bytes + let raw_sig = genesis_block.signature.as_raw(); + let raw_sig_bytes = raw_sig.as_bytes(); + + assert!(raw_sig_bytes.len() == 97); + for item in raw_sig_bytes.iter() { + assert!(*item == 0); + } + } } diff --git a/beacon_chain/genesis/src/beacon_state.rs b/beacon_chain/genesis/src/beacon_state.rs index f9c2ef327..3ebd3dba7 100644 --- a/beacon_chain/genesis/src/beacon_state.rs +++ b/beacon_chain/genesis/src/beacon_state.rs @@ -86,12 +86,13 @@ mod tests { extern crate validator_induction; use super::*; + use types::Hash256; // TODO: enhance these tests. // https://github.com/sigp/lighthouse/issues/117 #[test] - fn test_genesis() { + fn test_gen_state() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); @@ -101,4 +102,106 @@ mod tests { spec.initial_validators.len() ); } + + #[test] + fn test_gen_state_misc() { + let spec = ChainSpec::foundation(); + + let state = genesis_beacon_state(&spec).unwrap(); + + assert_eq!(state.slot, 0); + assert_eq!(state.genesis_time, spec.genesis_time); + assert_eq!(state.fork_data.pre_fork_version, 0); + assert_eq!(state.fork_data.post_fork_version, 0); + assert_eq!(state.fork_data.fork_slot, 0); + } + + #[test] + fn test_gen_state_validators() { + let spec = ChainSpec::foundation(); + + let state = genesis_beacon_state(&spec).unwrap(); + + assert_eq!(state.validator_registry, spec.initial_validators); + assert_eq!(state.validator_balances, spec.initial_balances); + assert!(state.validator_registry_latest_change_slot == 0); + assert!(state.validator_registry_exit_count == 0); + assert_eq!(state.validator_registry_delta_chain_tip, Hash256::zero()); + } + + #[test] + fn test_gen_state_randomness_committees() { + let spec = ChainSpec::foundation(); + + let state = genesis_beacon_state(&spec).unwrap(); + + // Note: specs now have randao_mixes containing 8,192 zero hashes + assert_eq!(state.randao_mix, Hash256::zero()); + + // Note: next_seed has changed to latest_vdf_outputs[8,192]8,192] + assert_eq!(state.next_seed, Hash256::zero()); + + // TODO: Check shard and committee shuffling requires solving issue: + // https://github.com/sigp/lighthouse/issues/151 + + // initial_shuffling = get_shuffling(Hash256::zero(), &state.validator_registry, 0, 0) + // initial_shuffling = initial_shuffling.append(initial_shuffling.clone()); + } + + #[test] + fn test_gen_state_custody_finanilty() { + let spec = ChainSpec::foundation(); + + let state = genesis_beacon_state(&spec).unwrap(); + + // Note: custody_challenges are not included yet but are in Eth2.0 specs + + assert_eq!(state.previous_justified_slot, 0); + assert_eq!(state.justified_slot, 0); + assert_eq!(state.justification_bitfield, 0); + assert_eq!(state.finalized_slot, 0); + } + + #[test] + fn test_gen_state_recent_state() { + let spec = ChainSpec::foundation(); + + let state = genesis_beacon_state(&spec).unwrap(); + + + // Test latest_crosslinks + assert_eq!(state.latest_crosslinks.len(), 1024); + for link in state.latest_crosslinks.iter() { + assert_eq!(link.slot, 0); + assert_eq!(link.shard_block_root, Hash256::zero()); + } + + // Test latest_block_roots + assert_eq!(state.latest_block_roots.len(), 64); + for block in state.latest_block_roots.iter() { + assert_eq!(*block, Hash256::zero()); + } + + // Test latest_penalized_exit_balances + // Note: Eth2.0 specs says this should be an array of length LATEST_PENALIZE_EXIT_LENGTH + // = (8,192) + assert!(state.latest_penalized_exit_balances.is_empty()); + + // Test latest_attestations + assert!(state.latest_attestations.is_empty()); + + // Note: missing batched_block_roots in new spec + + } + + // Note: here we refer to it as pow_reciept in the Eth2.0 specs it is called deposit + #[test] + fn test_gen_state_deposit_root() { + let spec = ChainSpec::foundation(); + + let state = genesis_beacon_state(&spec).unwrap(); + + assert_eq!(state.processed_pow_receipt_root, spec.processed_pow_receipt_root); + assert!(state.candidate_pow_receipt_roots.is_empty()); + } } From 0b47b81a6c5ecc09b7672c4378ad5b24d528d9ca Mon Sep 17 00:00:00 2001 From: Kirk Baird Date: Tue, 15 Jan 2019 12:43:14 +1100 Subject: [PATCH 2/4] Add tests for genesis and modify genesis to match new specs --- beacon_chain/genesis/src/beacon_block.rs | 16 +++---- beacon_chain/genesis/src/beacon_state.rs | 60 +++++++++++++++--------- beacon_chain/spec/src/foundation.rs | 3 ++ beacon_chain/spec/src/lib.rs | 3 ++ 4 files changed, 50 insertions(+), 32 deletions(-) diff --git a/beacon_chain/genesis/src/beacon_block.rs b/beacon_chain/genesis/src/beacon_block.rs index 423a1c64a..6caa0c80c 100644 --- a/beacon_chain/genesis/src/beacon_block.rs +++ b/beacon_chain/genesis/src/beacon_block.rs @@ -39,9 +39,6 @@ fn genesis_signature() -> Signature { mod tests { use super::*; - // TODO: enhance these tests. - // https://github.com/sigp/lighthouse/issues/117 - #[test] fn test_genesis() { let spec = ChainSpec::foundation(); @@ -51,7 +48,7 @@ mod tests { genesis_beacon_block(state_root, &spec); } - // Tests parent_root, randao_reveal, deposit_root are the zero hash after creation and slot == 0 + // Tests items that are 0 or zero_hash #[test] fn test_zero_items() { let spec = ChainSpec::foundation(); @@ -61,13 +58,13 @@ mod tests { let genesis_block = genesis_beacon_block(state_root, &spec); + assert!(genesis_block.slot == 0); assert!(genesis_block.parent_root.is_zero()); assert!(genesis_block.randao_reveal.is_zero()); - assert!(genesis_block.slot == 0); - // assert!(genesis_block.depsoit_root.is_zero()); - + assert!(genesis_block.candidate_pow_receipt_root.is_zero()); // aka deposit_root } + // Tests the BeaconBlockBody inside BeaconBlock #[test] fn test_beacon_body() { let spec = ChainSpec::foundation(); @@ -77,12 +74,13 @@ mod tests { let genesis_block = genesis_beacon_block(state_root, &spec); + // Custody items are not being implemented until phase 1 so tests to be added later + assert!(genesis_block.body.proposer_slashings.is_empty()); assert!(genesis_block.body.casper_slashings.is_empty()); assert!(genesis_block.body.attestations.is_empty()); assert!(genesis_block.body.deposits.is_empty()); assert!(genesis_block.body.exits.is_empty()); - // Specs have changed to include 3 more variables in BeaconBody to be added later } #[test] @@ -102,6 +100,6 @@ mod tests { assert!(raw_sig_bytes.len() == 97); for item in raw_sig_bytes.iter() { assert!(*item == 0); - } + } } } diff --git a/beacon_chain/genesis/src/beacon_state.rs b/beacon_chain/genesis/src/beacon_state.rs index 94207473c..7326bbf1d 100644 --- a/beacon_chain/genesis/src/beacon_state.rs +++ b/beacon_chain/genesis/src/beacon_state.rs @@ -68,8 +68,8 @@ pub fn genesis_beacon_state(spec: &ChainSpec) -> Result { * Recent state */ latest_crosslinks: vec![initial_crosslink; spec.shard_count as usize], - latest_block_roots: vec![spec.zero_hash; spec.epoch_length as usize], - latest_penalized_exit_balances: vec![], + latest_block_roots: vec![spec.zero_hash; spec.latest_block_roots_length as usize], + latest_penalized_exit_balances: vec![0; spec.latest_penalized_exit_length as usize], latest_attestations: vec![], batched_block_roots: vec![], /* @@ -94,9 +94,6 @@ mod tests { use super::*; use types::Hash256; - // TODO: enhance these tests. - // https://github.com/sigp/lighthouse/issues/117 - #[test] fn test_gen_state() { let spec = ChainSpec::foundation(); @@ -109,6 +106,7 @@ mod tests { ); } + // Test Misc #[test] fn test_gen_state_misc() { let spec = ChainSpec::foundation(); @@ -116,12 +114,13 @@ mod tests { let state = genesis_beacon_state(&spec).unwrap(); assert_eq!(state.slot, 0); - assert_eq!(state.genesis_time, spec.genesis_time); + assert_eq!(state.genesis_time, spec.genesis_time); assert_eq!(state.fork_data.pre_fork_version, 0); assert_eq!(state.fork_data.post_fork_version, 0); assert_eq!(state.fork_data.fork_slot, 0); } + // Test validators #[test] fn test_gen_state_validators() { let spec = ChainSpec::foundation(); @@ -135,17 +134,24 @@ mod tests { assert_eq!(state.validator_registry_delta_chain_tip, Hash256::zero()); } + // Test randomness and committees #[test] fn test_gen_state_randomness_committees() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); - // Note: specs now have randao_mixes containing 8,192 zero hashes - assert_eq!(state.randao_mix, Hash256::zero()); + // Array of size 8,192 each being zero_hash + assert_eq!(state.latest_randao_mixes.len(), 8_192); + for item in state.latest_randao_mixes.iter() { + assert_eq!(*item, Hash256::zero()); + } - // Note: next_seed has changed to latest_vdf_outputs[8,192]8,192] - assert_eq!(state.next_seed, Hash256::zero()); + // Array of size 8,192 each being a zero hash + assert_eq!(state.latest_vdf_outputs.len(), (8_192 / 64)); + for item in state.latest_vdf_outputs.iter() { + assert_eq!(*item, Hash256::zero()); + } // TODO: Check shard and committee shuffling requires solving issue: // https://github.com/sigp/lighthouse/issues/151 @@ -154,60 +160,68 @@ mod tests { // initial_shuffling = initial_shuffling.append(initial_shuffling.clone()); } + // Custody not implemented until Phase 1 + // This test will always pass until Phase 1 #[test] - fn test_gen_state_custody_finanilty() { + fn test_gen_state_custody() {} + + // Test finality + #[test] + fn test_gen_state_finanilty() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); - // Note: custody_challenges are not included yet but are in Eth2.0 specs - assert_eq!(state.previous_justified_slot, 0); assert_eq!(state.justified_slot, 0); assert_eq!(state.justification_bitfield, 0); assert_eq!(state.finalized_slot, 0); } + // Test recent state #[test] fn test_gen_state_recent_state() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); - // Test latest_crosslinks - assert_eq!(state.latest_crosslinks.len(), 1024); + assert_eq!(state.latest_crosslinks.len(), 1_024); for link in state.latest_crosslinks.iter() { assert_eq!(link.slot, 0); assert_eq!(link.shard_block_root, Hash256::zero()); } // Test latest_block_roots - assert_eq!(state.latest_block_roots.len(), 64); + assert_eq!(state.latest_block_roots.len(), 8_192); for block in state.latest_block_roots.iter() { assert_eq!(*block, Hash256::zero()); } // Test latest_penalized_exit_balances - // Note: Eth2.0 specs says this should be an array of length LATEST_PENALIZE_EXIT_LENGTH - // = (8,192) - assert!(state.latest_penalized_exit_balances.is_empty()); + assert_eq!(state.latest_penalized_exit_balances.len(), 8_192); + for item in state.latest_penalized_exit_balances.iter() { + assert!(*item == 0); + } // Test latest_attestations assert!(state.latest_attestations.is_empty()); - // Note: missing batched_block_roots in new spec - + // batched_block_roots + assert!(state.batched_block_roots.is_empty()); } - // Note: here we refer to it as pow_reciept in the Eth2.0 specs it is called deposit + // Test PoW Receipts a.k.a. deposits #[test] fn test_gen_state_deposit_root() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); - assert_eq!(state.processed_pow_receipt_root, spec.processed_pow_receipt_root); + assert_eq!( + state.processed_pow_receipt_root, + spec.processed_pow_receipt_root + ); assert!(state.candidate_pow_receipt_roots.is_empty()); } } diff --git a/beacon_chain/spec/src/foundation.rs b/beacon_chain/spec/src/foundation.rs index 1a493d72c..8e3146ed2 100644 --- a/beacon_chain/spec/src/foundation.rs +++ b/beacon_chain/spec/src/foundation.rs @@ -24,7 +24,10 @@ impl ChainSpec { beacon_chain_shard_number: u64::max_value(), bls_withdrawal_prefix_byte: 0x00, max_casper_votes: 1_024, + latest_block_roots_length: 8_192, latest_randao_mixes_length: 8_192, + latest_penalized_exit_length: 8_192, + max_withdrawals_per_epoch: 4, /* * Deposit contract */ diff --git a/beacon_chain/spec/src/lib.rs b/beacon_chain/spec/src/lib.rs index eb024cb6c..5b7bdfae3 100644 --- a/beacon_chain/spec/src/lib.rs +++ b/beacon_chain/spec/src/lib.rs @@ -18,7 +18,10 @@ pub struct ChainSpec { pub beacon_chain_shard_number: u64, pub bls_withdrawal_prefix_byte: u8, pub max_casper_votes: u64, + pub latest_block_roots_length: u64, pub latest_randao_mixes_length: u64, + pub latest_penalized_exit_length: u64, + pub max_withdrawals_per_epoch: u64, /* * Deposit contract */ From 0e3d0848acd82450762c3ed5b599ef3cb2c7b96c Mon Sep 17 00:00:00 2001 From: Kirk Baird Date: Thu, 17 Jan 2019 17:59:33 +1100 Subject: [PATCH 3/4] Relove formatting and other issues raise in PR --- beacon_chain/genesis/Cargo.toml | 1 - beacon_chain/genesis/src/beacon_block.rs | 4 ---- beacon_chain/genesis/src/beacon_state.rs | 26 ++++++++---------------- beacon_chain/types/src/beacon_state.rs | 2 +- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/beacon_chain/genesis/Cargo.toml b/beacon_chain/genesis/Cargo.toml index dbfd7e1fc..499333979 100644 --- a/beacon_chain/genesis/Cargo.toml +++ b/beacon_chain/genesis/Cargo.toml @@ -6,7 +6,6 @@ edition = "2018" [dependencies] bls = { path = "../utils/bls" } -bls-aggregates = { git = "https://github.com/sigp/signature-schemes" } spec = { path = "../spec" } ssz = { path = "../utils/ssz" } types = { path = "../types" } diff --git a/beacon_chain/genesis/src/beacon_block.rs b/beacon_chain/genesis/src/beacon_block.rs index 6caa0c80c..92230cd98 100644 --- a/beacon_chain/genesis/src/beacon_block.rs +++ b/beacon_chain/genesis/src/beacon_block.rs @@ -53,7 +53,6 @@ mod tests { fn test_zero_items() { let spec = ChainSpec::foundation(); - // Note: state_root will not be available without a state (test in beacon_state) let state_root = Hash256::zero(); let genesis_block = genesis_beacon_block(state_root, &spec); @@ -69,7 +68,6 @@ mod tests { fn test_beacon_body() { let spec = ChainSpec::foundation(); - // Note: state_root will not be available without a state (test in beacon_state) let state_root = Hash256::zero(); let genesis_block = genesis_beacon_block(state_root, &spec); @@ -87,7 +85,6 @@ mod tests { fn test_signature() { let spec = ChainSpec::foundation(); - // Note: state_root will not be available without a state (test in beacon_state) let state_root = Hash256::zero(); let genesis_block = genesis_beacon_block(state_root, &spec); @@ -97,7 +94,6 @@ mod tests { let raw_sig = genesis_block.signature.as_raw(); let raw_sig_bytes = raw_sig.as_bytes(); - assert!(raw_sig_bytes.len() == 97); for item in raw_sig_bytes.iter() { assert!(*item == 0); } diff --git a/beacon_chain/genesis/src/beacon_state.rs b/beacon_chain/genesis/src/beacon_state.rs index 7326bbf1d..58feca840 100644 --- a/beacon_chain/genesis/src/beacon_state.rs +++ b/beacon_chain/genesis/src/beacon_state.rs @@ -88,14 +88,11 @@ impl From for Error { #[cfg(test)] mod tests { - extern crate bls; - extern crate validator_induction; - use super::*; use types::Hash256; #[test] - fn test_gen_state() { + fn test_genesis_state() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); @@ -106,9 +103,8 @@ mod tests { ); } - // Test Misc #[test] - fn test_gen_state_misc() { + fn test_genesis_state_misc() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); @@ -120,9 +116,8 @@ mod tests { assert_eq!(state.fork_data.fork_slot, 0); } - // Test validators #[test] - fn test_gen_state_validators() { + fn test_genesis_state_validators() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); @@ -134,9 +129,8 @@ mod tests { assert_eq!(state.validator_registry_delta_chain_tip, Hash256::zero()); } - // Test randomness and committees #[test] - fn test_gen_state_randomness_committees() { + fn test_genesis_state_randomness_committees() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); @@ -161,13 +155,11 @@ mod tests { } // Custody not implemented until Phase 1 - // This test will always pass until Phase 1 #[test] - fn test_gen_state_custody() {} + fn test_genesis_state_custody() {} - // Test finality #[test] - fn test_gen_state_finanilty() { + fn test_genesis_state_finanilty() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); @@ -178,9 +170,8 @@ mod tests { assert_eq!(state.finalized_slot, 0); } - // Test recent state #[test] - fn test_gen_state_recent_state() { + fn test_genesis_state_recent_state() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); @@ -211,9 +202,8 @@ mod tests { assert!(state.batched_block_roots.is_empty()); } - // Test PoW Receipts a.k.a. deposits #[test] - fn test_gen_state_deposit_root() { + fn test_genesis_state_deposit_root() { let spec = ChainSpec::foundation(); let state = genesis_beacon_state(&spec).unwrap(); diff --git a/beacon_chain/types/src/beacon_state.rs b/beacon_chain/types/src/beacon_state.rs index b9994bddd..cbcb00d19 100644 --- a/beacon_chain/types/src/beacon_state.rs +++ b/beacon_chain/types/src/beacon_state.rs @@ -10,7 +10,7 @@ use hashing::canonical_hash; use rand::RngCore; use ssz::{ssz_encode, Decodable, DecodeError, Encodable, SszStream}; -// Custody will not be added to the specs until Phase 1 (Sharding Phase) so dummay class used. +// Custody will not be added to the specs until Phase 1 (Sharding Phase) so dummy class used. type CustodyChallenge = usize; #[derive(Debug, PartialEq, Clone, Default)] From dc5986b8c07d0a054f53de9b1e7d50e1bc72f6dc Mon Sep 17 00:00:00 2001 From: Kirk Baird Date: Fri, 18 Jan 2019 09:20:28 +1100 Subject: [PATCH 4/4] Minor formatting --- beacon_chain/genesis/src/beacon_block.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/beacon_chain/genesis/src/beacon_block.rs b/beacon_chain/genesis/src/beacon_block.rs index 92230cd98..78968b7a6 100644 --- a/beacon_chain/genesis/src/beacon_block.rs +++ b/beacon_chain/genesis/src/beacon_block.rs @@ -48,7 +48,6 @@ mod tests { genesis_beacon_block(state_root, &spec); } - // Tests items that are 0 or zero_hash #[test] fn test_zero_items() { let spec = ChainSpec::foundation(); @@ -63,7 +62,6 @@ mod tests { assert!(genesis_block.candidate_pow_receipt_root.is_zero()); // aka deposit_root } - // Tests the BeaconBlockBody inside BeaconBlock #[test] fn test_beacon_body() { let spec = ChainSpec::foundation();