From 717f8d98d7b02860465672ba35f1bc46460db79a Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 9 Apr 2021 17:00:02 -0400 Subject: [PATCH] Fix beacon chain tests non-altair --- Cargo.lock | 8 +- beacon_node/beacon_chain/src/builder.rs | 27 +-- beacon_node/beacon_chain/src/eth1_chain.rs | 52 +++--- beacon_node/beacon_chain/src/head_tracker.rs | 12 +- .../src/observed_block_producers.rs | 48 +++--- .../beacon_chain/src/snapshot_cache.rs | 56 +++--- beacon_node/beacon_chain/src/test_utils.rs | 20 ++- .../src/validator_pubkey_cache.rs | 23 ++- .../tests/attestation_production.rs | 10 +- .../tests/attestation_verification.rs | 14 +- .../beacon_chain/tests/block_verification.rs | 163 +++++++++++------- .../beacon_chain/tests/op_verification.rs | 76 ++------ .../beacon_chain/tests/persistence_tests.rs | 9 +- beacon_node/beacon_chain/tests/store_tests.rs | 56 +++--- beacon_node/beacon_chain/tests/tests.rs | 38 ++-- .../genesis/src/eth1_genesis_service.rs | 2 +- beacon_node/genesis/src/interop.rs | 13 +- beacon_node/genesis/tests/tests.rs | 2 +- beacon_node/operation_pool/src/attestation.rs | 3 +- beacon_node/store/src/partial_beacon_state.rs | 1 + .../src/per_block_processing/tests.rs | 4 +- .../altair/rewards_and_penalties.rs | 20 --- consensus/tree_hash/benches/benches.rs | 4 +- .../examples/flamegraph_beacon_state.rs | 4 +- consensus/types/src/beacon_block.rs | 48 ++++++ consensus/types/src/beacon_state/tests.rs | 8 +- consensus/types/src/lib.rs | 4 +- .../builders/testing_beacon_block_builder.rs | 4 +- .../builders/testing_beacon_state_builder.rs | 4 +- 29 files changed, 409 insertions(+), 324 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d30a958d2f7..e69a54eadae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1667,8 +1667,7 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "discv5" version = "0.1.0-beta.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f52d2228d51e8f868a37d5b5b25b82c13552b635d5b47c3a5d53855a6fc4f0" +source = "git+https://github.com/sigp/discv5?rev=02d2c896c66f8dc2b848c3996fedcd98e1dfec69#02d2c896c66f8dc2b848c3996fedcd98e1dfec69" dependencies = [ "aes-ctr", "aes-gcm 0.8.0", @@ -1681,6 +1680,7 @@ dependencies = [ "hkdf", "k256", "lazy_static", + "libp2p-core", "lru_time_cache", "parking_lot", "rand 0.7.3", @@ -1699,7 +1699,8 @@ dependencies = [ [[package]] name = "discv5" version = "0.1.0-beta.3" -source = "git+https://github.com/sigp/discv5?rev=02d2c896c66f8dc2b848c3996fedcd98e1dfec69#02d2c896c66f8dc2b848c3996fedcd98e1dfec69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f52d2228d51e8f868a37d5b5b25b82c13552b635d5b47c3a5d53855a6fc4f0" dependencies = [ "aes-ctr", "aes-gcm 0.8.0", @@ -1712,7 +1713,6 @@ dependencies = [ "hkdf", "k256", "lazy_static", - "libp2p-core", "lru_time_cache", "parking_lot", "rand 0.7.3", diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index 7a071dd0154..ff3cd43238a 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -675,7 +675,7 @@ mod test { use store::config::StoreConfig; use store::{HotColdDB, MemoryStore}; use tempfile::tempdir; - use types::{EthSpec, MinimalEthSpec, Slot}; + use types::{init_fork_schedule, EthSpec, ForkSchedule, MinimalEthSpec, Slot}; type TestEthSpec = MinimalEthSpec; @@ -686,6 +686,11 @@ mod test { #[test] fn recent_genesis() { + //TODO: handle altair + init_fork_schedule(ForkSchedule { + altair_fork_slot: None, + }); + let validator_count = 1; let genesis_time = 13_371_337; @@ -728,9 +733,10 @@ mod test { let state = head.beacon_state; let block = head.beacon_block; - assert_eq!(state.slot, Slot::new(0), "should start from genesis"); + assert_eq!(state.slot(), Slot::new(0), "should start from genesis"); assert_eq!( - state.genesis_time, 13_371_337, + state.genesis_time(), + 13_371_337, "should have the correct genesis time" ); assert_eq!( @@ -748,7 +754,7 @@ mod test { "should store genesis block under zero hash alias" ); assert_eq!( - state.validators.len(), + state.validators().len(), validator_count, "should have correct validator count" ); @@ -771,24 +777,25 @@ mod test { .expect("should build state"); assert_eq!( - state.eth1_data.block_hash, + state.eth1_data().block_hash, Hash256::from_slice(&[0x42; 32]), "eth1 block hash should be co-ordinated junk" ); assert_eq!( - state.genesis_time, genesis_time, + state.genesis_time(), + genesis_time, "genesis time should be as specified" ); - for b in &state.balances { + for b in state.balances() { assert_eq!( *b, spec.max_effective_balance, "validator balances should be max effective balance" ); } - for v in &state.validators { + for v in state.validators() { let creds = v.withdrawal_credentials.as_bytes(); assert_eq!( creds[0], spec.bls_withdrawal_prefix_byte, @@ -802,13 +809,13 @@ mod test { } assert_eq!( - state.balances.len(), + state.balances().len(), validator_count, "validator balances len should be correct" ); assert_eq!( - state.validators.len(), + state.validators().len(), validator_count, "validator count should be correct" ); diff --git a/beacon_node/beacon_chain/src/eth1_chain.rs b/beacon_node/beacon_chain/src/eth1_chain.rs index 27e2ba2f981..e25c4267062 100644 --- a/beacon_node/beacon_chain/src/eth1_chain.rs +++ b/beacon_node/beacon_chain/src/eth1_chain.rs @@ -668,7 +668,7 @@ fn is_candidate_block(block: &Eth1Block, period_start: u64, spec: &ChainSpec) -> mod test { use super::*; use environment::null_logger; - use types::{test_utils::DepositTestTask, MinimalEthSpec}; + use types::{DepositData, MinimalEthSpec, Signature}; type E = MinimalEthSpec; @@ -682,9 +682,9 @@ mod test { fn get_voting_period_start_seconds(state: &BeaconState, spec: &ChainSpec) -> u64 { let period = ::SlotsPerEth1VotingPeriod::to_u64(); - let voting_period_start_slot = (state.slot / period) * period; + let voting_period_start_slot = (state.slot() / period) * period; slot_start_seconds::( - state.genesis_time, + state.genesis_time(), spec.seconds_per_slot, voting_period_start_slot, ) @@ -725,10 +725,7 @@ mod test { mod eth1_chain_json_backend { use super::*; use eth1::DepositLog; - use types::{ - test_utils::{generate_deterministic_keypair, TestingDepositBuilder}, - EthSpec, MainnetEthSpec, - }; + use types::{test_utils::generate_deterministic_keypair, EthSpec, MainnetEthSpec}; fn get_eth1_chain() -> Eth1Chain, E> { let eth1_config = Eth1Config { @@ -745,13 +742,17 @@ mod test { fn get_deposit_log(i: u64, spec: &ChainSpec) -> DepositLog { let keypair = generate_deterministic_keypair(i as usize); - let mut builder = - TestingDepositBuilder::new(keypair.pk.clone(), spec.max_effective_balance); - builder.sign(DepositTestTask::Valid, &keypair, spec); - let deposit_data = builder.build().data; + let mut deposit = DepositData { + pubkey: keypair.pk.into(), + withdrawal_credentials: Hash256::zero(), + amount: spec.max_effective_balance, + signature: Signature::empty().into(), + }; + + deposit.signature = deposit.create_signature(&keypair.sk, &E::default_spec()); DepositLog { - deposit_data, + deposit_data: deposit, block_number: i, index: i, signature_is_valid: true, @@ -770,8 +771,8 @@ mod test { ); let mut state: BeaconState = BeaconState::new(0, get_eth1_data(0), &spec); - state.eth1_deposit_index = 0; - state.eth1_data.deposit_count = 0; + *state.eth1_deposit_index_mut() = 0; + state.eth1_data_mut().deposit_count = 0; assert!( eth1_chain @@ -780,7 +781,7 @@ mod test { "should succeed if cache is empty but no deposits are required" ); - state.eth1_data.deposit_count = 1; + state.eth1_data_mut().deposit_count = 1; assert!( eth1_chain @@ -823,8 +824,8 @@ mod test { ); let mut state: BeaconState = BeaconState::new(0, get_eth1_data(0), &spec); - state.eth1_deposit_index = 0; - state.eth1_data.deposit_count = 0; + *state.eth1_deposit_index_mut() = 0; + state.eth1_data_mut().deposit_count = 0; assert!( eth1_chain @@ -834,10 +835,10 @@ mod test { ); (0..3).for_each(|initial_deposit_index| { - state.eth1_deposit_index = initial_deposit_index as u64; + *state.eth1_deposit_index_mut() = initial_deposit_index as u64; (initial_deposit_index..deposits.len()).for_each(|i| { - state.eth1_data.deposit_count = i as u64; + state.eth1_data_mut().deposit_count = i as u64; let deposits_for_inclusion = eth1_chain .deposits_for_block_inclusion(&state, &Eth1Data::default(), spec) @@ -890,7 +891,8 @@ mod test { .eth1_data_for_block_production(&state, &spec) .expect("should produce default eth1 data vote"); assert_eq!( - a, state.eth1_data, + a, + *state.eth1_data(), "default vote should be same as state.eth1_data" ); } @@ -910,7 +912,7 @@ mod test { let mut state: BeaconState = BeaconState::new(0, get_eth1_data(0), &spec); - state.slot = Slot::from(slots_per_eth1_voting_period * 10); + *state.slot_mut() = Slot::from(slots_per_eth1_voting_period * 10); let follow_distance_seconds = eth1_follow_distance * spec.seconds_per_eth1_block; let voting_period_start = get_voting_period_start_seconds(&state, &spec); let start_eth1_block = voting_period_start - follow_distance_seconds * 2; @@ -976,8 +978,8 @@ mod test { let eth1_follow_distance = spec.eth1_follow_distance; let mut state: BeaconState = BeaconState::new(0, get_eth1_data(0), &spec); - state.genesis_time = 0; - state.slot = Slot::from(slots_per_eth1_voting_period * 10); + *state.genesis_time_mut() = 0; + *state.slot_mut() = Slot::from(slots_per_eth1_voting_period * 10); let follow_distance_seconds = eth1_follow_distance * spec.seconds_per_eth1_block; let voting_period_start = get_voting_period_start_seconds(&state, &spec); @@ -1057,7 +1059,7 @@ mod test { let votes_to_consider = get_eth1_data_vec(slots, 0); - state.eth1_data_votes = votes_to_consider[0..slots as usize / 4] + *state.eth1_data_votes_mut() = votes_to_consider[0..slots as usize / 4] .iter() .map(|(eth1_data, _)| eth1_data) .cloned() @@ -1086,7 +1088,7 @@ mod test { .expect("should have some eth1 data") .clone(); - state.eth1_data_votes = vec![duplicate_eth1_data.clone(); 4] + *state.eth1_data_votes_mut() = vec![duplicate_eth1_data.clone(); 4] .iter() .map(|(eth1_data, _)| eth1_data) .cloned() diff --git a/beacon_node/beacon_chain/src/head_tracker.rs b/beacon_node/beacon_chain/src/head_tracker.rs index 4a4ce2fe572..84c800f3b71 100644 --- a/beacon_node/beacon_chain/src/head_tracker.rs +++ b/beacon_node/beacon_chain/src/head_tracker.rs @@ -112,14 +112,14 @@ mod test { let mut block: BeaconBlock = BeaconBlock::empty(spec); let block_root = Hash256::from_low_u64_be(i); - block.slot = Slot::new(i); - block.parent_root = if i == 0 { + *block.slot_mut() = Slot::new(i); + *block.parent_root_mut() = if i == 0 { Hash256::random() } else { Hash256::from_low_u64_be(i - 1) }; - head_tracker.register_block(block_root, block.parent_root, block.slot); + head_tracker.register_block(block_root, block.parent_root(), block.slot()); } assert_eq!( @@ -130,9 +130,9 @@ mod test { let mut block: BeaconBlock = BeaconBlock::empty(spec); let block_root = Hash256::from_low_u64_be(42); - block.slot = Slot::new(15); - block.parent_root = Hash256::from_low_u64_be(14); - head_tracker.register_block(block_root, block.parent_root, block.slot); + *block.slot_mut() = Slot::new(15); + *block.parent_root_mut() = Hash256::from_low_u64_be(14); + head_tracker.register_block(block_root, block.parent_root(), block.slot()); let heads = head_tracker.heads(); diff --git a/beacon_node/beacon_chain/src/observed_block_producers.rs b/beacon_node/beacon_chain/src/observed_block_producers.rs index 9845b646051..66e036f36fc 100644 --- a/beacon_node/beacon_chain/src/observed_block_producers.rs +++ b/beacon_node/beacon_chain/src/observed_block_producers.rs @@ -119,14 +119,14 @@ impl ObservedBlockProducers { #[cfg(test)] mod tests { use super::*; - use types::MainnetEthSpec; + use types::{BeaconBlock, MainnetEthSpec}; type E = MainnetEthSpec; fn get_block(slot: u64, proposer: u64) -> BeaconBlock { let mut block = BeaconBlock::empty(&E::default_spec()); - block.slot = slot.into(); - block.proposer_index = proposer; + *block.slot_mut() = slot.into(); + *block.proposer_index_mut() = proposer; block } @@ -138,10 +138,10 @@ mod tests { assert_eq!(cache.items.len(), 0, "no slots should be present"); // Slot 0, proposer 0 - let block_a = &get_block(0, 0); + let block_a = get_block(0, 0); assert_eq!( - cache.observe_proposer(block_a), + cache.observe_proposer(block_a.to_ref()), Ok(false), "can observe proposer, indicates proposer unobserved" ); @@ -197,10 +197,10 @@ mod tests { */ // First slot of finalized epoch, proposer 0 - let block_b = &get_block(E::slots_per_epoch(), 0); + let block_b = get_block(E::slots_per_epoch(), 0); assert_eq!( - cache.observe_proposer(block_b), + cache.observe_proposer(block_b.to_ref()), Err(Error::FinalizedBlock { slot: E::slots_per_epoch().into(), finalized_slot: E::slots_per_epoch().into(), @@ -217,10 +217,10 @@ mod tests { let three_epochs = E::slots_per_epoch() * 3; // First slot of finalized epoch, proposer 0 - let block_b = &get_block(three_epochs, 0); + let block_b = get_block(three_epochs, 0); assert_eq!( - cache.observe_proposer(block_b), + cache.observe_proposer(block_b.to_ref()), Ok(false), "can insert non-finalized block" ); @@ -266,25 +266,25 @@ mod tests { let mut cache = ObservedBlockProducers::default(); // Slot 0, proposer 0 - let block_a = &get_block(0, 0); + let block_a = get_block(0, 0); assert_eq!( - cache.proposer_has_been_observed(block_a), + cache.proposer_has_been_observed(block_a.to_ref()), Ok(false), "no observation in empty cache" ); assert_eq!( - cache.observe_proposer(block_a), + cache.observe_proposer(block_a.to_ref()), Ok(false), "can observe proposer, indicates proposer unobserved" ); assert_eq!( - cache.proposer_has_been_observed(block_a), + cache.proposer_has_been_observed(block_a.to_ref()), Ok(true), "observed block is indicated as true" ); assert_eq!( - cache.observe_proposer(block_a), + cache.observe_proposer(block_a.to_ref()), Ok(true), "observing again indicates true" ); @@ -302,25 +302,25 @@ mod tests { ); // Slot 1, proposer 0 - let block_b = &get_block(1, 0); + let block_b = get_block(1, 0); assert_eq!( - cache.proposer_has_been_observed(block_b), + cache.proposer_has_been_observed(block_b.to_ref()), Ok(false), "no observation for new slot" ); assert_eq!( - cache.observe_proposer(block_b), + cache.observe_proposer(block_b.to_ref()), Ok(false), "can observe proposer for new slot, indicates proposer unobserved" ); assert_eq!( - cache.proposer_has_been_observed(block_b), + cache.proposer_has_been_observed(block_b.to_ref()), Ok(true), "observed block in slot 1 is indicated as true" ); assert_eq!( - cache.observe_proposer(block_b), + cache.observe_proposer(block_b.to_ref()), Ok(true), "observing slot 1 again indicates true" ); @@ -347,25 +347,25 @@ mod tests { ); // Slot 0, proposer 1 - let block_c = &get_block(0, 1); + let block_c = get_block(0, 1); assert_eq!( - cache.proposer_has_been_observed(block_c), + cache.proposer_has_been_observed(block_c.to_ref()), Ok(false), "no observation for new proposer" ); assert_eq!( - cache.observe_proposer(block_c), + cache.observe_proposer(block_c.to_ref()), Ok(false), "can observe new proposer, indicates proposer unobserved" ); assert_eq!( - cache.proposer_has_been_observed(block_c), + cache.proposer_has_been_observed(block_c.to_ref()), Ok(true), "observed new proposer block is indicated as true" ); assert_eq!( - cache.observe_proposer(block_c), + cache.observe_proposer(block_c.to_ref()), Ok(true), "observing new proposer again indicates true" ); diff --git a/beacon_node/beacon_chain/src/snapshot_cache.rs b/beacon_node/beacon_chain/src/snapshot_cache.rs index 0f421d2fe84..c5c0cd28112 100644 --- a/beacon_node/beacon_chain/src/snapshot_cache.rs +++ b/beacon_node/beacon_chain/src/snapshot_cache.rs @@ -279,27 +279,42 @@ impl SnapshotCache { #[cfg(test)] mod test { use super::*; + use crate::test_utils::{BeaconChainHarness, EphemeralHarnessType}; + use store::StoreConfig; use types::{ - test_utils::{generate_deterministic_keypair, TestingBeaconStateBuilder}, - BeaconBlock, Epoch, MainnetEthSpec, SignedBeaconBlock, Slot, + test_utils::generate_deterministic_keypair, BeaconBlock, Epoch, MainnetEthSpec, + SignedBeaconBlock, Slot, }; + fn get_harness() -> BeaconChainHarness> { + let harness = BeaconChainHarness::new_with_store_config( + MainnetEthSpec, + types::test_utils::generate_deterministic_keypairs(1), + StoreConfig::default(), + ); + + harness.advance_slot(); + + harness + } + const CACHE_SIZE: usize = 4; fn get_snapshot(i: u64) -> BeaconSnapshot { let spec = MainnetEthSpec::default_spec(); - let state_builder = TestingBeaconStateBuilder::from_deterministic_keypairs(1, &spec); - let (beacon_state, _keypairs) = state_builder.build(); + let beacon_state = get_harness().chain.head_beacon_state().unwrap(); + + let signed_beacon_block = SignedBeaconBlock::from_block( + BeaconBlock::empty(&spec), + generate_deterministic_keypair(0) + .sk + .sign(Hash256::from_low_u64_be(42)), + ); BeaconSnapshot { beacon_state, - beacon_block: SignedBeaconBlock { - message: BeaconBlock::empty(&spec), - signature: generate_deterministic_keypair(0) - .sk - .sign(Hash256::from_low_u64_be(42)), - }, + beacon_block: signed_beacon_block, beacon_block_root: Hash256::from_low_u64_be(i), } } @@ -319,7 +334,8 @@ mod test { let mut snapshot = get_snapshot(i); // Each snapshot should be one slot into an epoch, with each snapshot one epoch apart. - snapshot.beacon_state.slot = Slot::from(i * MainnetEthSpec::slots_per_epoch() + 1); + *snapshot.beacon_state.slot_mut() = + Slot::from(i * MainnetEthSpec::slots_per_epoch() + 1); cache.insert(snapshot, None); @@ -352,20 +368,20 @@ mod test { .get_cloned(Hash256::from_low_u64_be(1), CloneConfig::none()) .is_none()); - assert!( + assert_eq!( cache .get_cloned(Hash256::from_low_u64_be(0), CloneConfig::none()) .expect("the head should still be in the cache") - .beacon_block_root - == Hash256::from_low_u64_be(0), + .beacon_block_root, + Hash256::from_low_u64_be(0), "get_cloned should get the correct snapshot" ); - assert!( + assert_eq!( cache .get_state_for_block_processing(Hash256::from_low_u64_be(0)) .expect("the head should still be in the cache") - .beacon_block_root - == Hash256::from_low_u64_be(0), + .beacon_block_root, + Hash256::from_low_u64_be(0), "get_state_for_block_processing should get the correct snapshot" ); @@ -392,12 +408,12 @@ mod test { } // Ensure that the new head value was not removed from the cache. - assert!( + assert_eq!( cache .get_state_for_block_processing(Hash256::from_low_u64_be(2)) .expect("the new head should still be in the cache") - .beacon_block_root - == Hash256::from_low_u64_be(2), + .beacon_block_root, + Hash256::from_low_u64_be(2), "get_state_for_block_processing should get the correct snapshot" ); } diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 6c904334cfd..0667bded5a5 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -28,11 +28,11 @@ use store::{config::StoreConfig, BlockReplay, HotColdDB, ItemStore, LevelDB, Mem use tempfile::{tempdir, TempDir}; use tree_hash::TreeHash; use types::{ - AggregateSignature, Attestation, AttestationData, AttesterSlashing, BeaconState, - BeaconStateHash, ChainSpec, Checkpoint, Domain, Epoch, EthSpec, Graffiti, Hash256, - IndexedAttestation, Keypair, ProposerSlashing, SelectionProof, SignedAggregateAndProof, - SignedBeaconBlock, SignedBeaconBlockHash, SignedRoot, SignedVoluntaryExit, Slot, SubnetId, - VariableList, VoluntaryExit, + init_fork_schedule, AggregateSignature, Attestation, AttestationData, AttesterSlashing, + BeaconState, BeaconStateHash, ChainSpec, Checkpoint, Domain, Epoch, EthSpec, ForkSchedule, + Graffiti, Hash256, IndexedAttestation, Keypair, ProposerSlashing, SelectionProof, + SignedAggregateAndProof, SignedBeaconBlock, SignedBeaconBlockHash, SignedRoot, + SignedVoluntaryExit, Slot, SubnetId, VariableList, VoluntaryExit, }; pub use types::test_utils::generate_deterministic_keypairs; @@ -171,6 +171,11 @@ impl BeaconChainHarness> { store_config: StoreConfig, chain_config: ChainConfig, ) -> Self { + //TODO: handle altair + init_fork_schedule(ForkSchedule { + altair_fork_slot: None, + }); + let data_dir = tempdir().expect("should create temporary data_dir"); let mut spec = E::default_spec(); @@ -224,6 +229,11 @@ impl BeaconChainHarness> { store: Arc, LevelDB>>, validator_keypairs: Vec, ) -> Self { + //TODO: handle altair + init_fork_schedule(ForkSchedule { + altair_fork_slot: None, + }); + let data_dir = tempdir().expect("should create temporary data_dir"); let spec = E::default_spec(); diff --git a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs index e4c27a04a8e..2853a16777e 100644 --- a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs +++ b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs @@ -316,23 +316,30 @@ fn append_to_file(file: &mut File, index: usize, pubkey: &PublicKeyBytes) -> Res #[cfg(test)] mod test { use super::*; - use crate::test_utils::{test_logger, EphemeralHarnessType}; + use crate::test_utils::{test_logger, BeaconChainHarness, EphemeralHarnessType}; use std::sync::Arc; - use store::HotColdDB; + use store::{HotColdDB, StoreConfig}; use tempfile::tempdir; use types::{ - test_utils::{generate_deterministic_keypair, TestingBeaconStateBuilder}, - BeaconState, EthSpec, Keypair, MainnetEthSpec, + test_utils::generate_deterministic_keypair, BeaconState, EthSpec, Keypair, MainnetEthSpec, }; type E = MainnetEthSpec; type T = EphemeralHarnessType; fn get_state(validator_count: usize) -> (BeaconState, Vec) { - let spec = E::default_spec(); - let builder = - TestingBeaconStateBuilder::from_deterministic_keypairs(validator_count, &spec); - builder.build() + let harness = BeaconChainHarness::new_with_store_config( + MainnetEthSpec, + types::test_utils::generate_deterministic_keypairs(validator_count), + StoreConfig::default(), + ); + + harness.advance_slot(); + + ( + harness.chain.head_beacon_state().unwrap(), + harness.validator_keypairs, + ) } fn get_store() -> BeaconStore { diff --git a/beacon_node/beacon_chain/tests/attestation_production.rs b/beacon_node/beacon_chain/tests/attestation_production.rs index 4e4e062d404..a8a2d25e629 100644 --- a/beacon_node/beacon_chain/tests/attestation_production.rs +++ b/beacon_node/beacon_chain/tests/attestation_production.rs @@ -63,12 +63,12 @@ fn produces_attestations() { .block_at_slot(block_slot) .expect("should get block") .expect("block should not be skipped"); - let block_root = block.message.tree_hash_root(); + let block_root = block.message().tree_hash_root(); let epoch_boundary_slot = state .current_epoch() .start_slot(MainnetEthSpec::slots_per_epoch()); - let target_root = if state.slot == epoch_boundary_slot { + let target_root = if state.slot() == epoch_boundary_slot { block_root } else { *state @@ -116,11 +116,13 @@ fn produces_attestations() { assert_eq!(data.slot, slot, "bad slot"); assert_eq!(data.beacon_block_root, block_root, "bad block root"); assert_eq!( - data.source, state.current_justified_checkpoint, + data.source, + state.current_justified_checkpoint(), "bad source" ); assert_eq!( - data.source, state.current_justified_checkpoint, + data.source, + state.current_justified_checkpoint(), "bad source" ); assert_eq!(data.target.epoch, state.current_epoch(), "bad target epoch"); diff --git a/beacon_node/beacon_chain/tests/attestation_verification.rs b/beacon_node/beacon_chain/tests/attestation_verification.rs index 580307ddc22..6ce4f62a426 100644 --- a/beacon_node/beacon_chain/tests/attestation_verification.rs +++ b/beacon_node/beacon_chain/tests/attestation_verification.rs @@ -75,7 +75,7 @@ fn get_valid_unaggregated_attestation( .sign( &validator_sk, validator_committee_index, - &head.beacon_state.fork, + &head.beacon_state.fork(), chain.genesis_validators_root, &chain.spec, ) @@ -120,7 +120,7 @@ fn get_valid_aggregated_attestation( let proof = SelectionProof::new::( aggregate.data.slot, &aggregator_sk, - &state.fork, + &state.fork(), chain.genesis_validators_root, &chain.spec, ); @@ -138,7 +138,7 @@ fn get_valid_aggregated_attestation( aggregate, None, &aggregator_sk, - &state.fork, + &state.fork(), chain.genesis_validators_root, &chain.spec, ); @@ -169,7 +169,7 @@ fn get_non_aggregator( let proof = SelectionProof::new::( aggregate.data.slot, &aggregator_sk, - &state.fork, + &state.fork(), chain.genesis_validators_root, &chain.spec, ); @@ -905,7 +905,7 @@ fn attestation_that_skips_epochs() { .expect("should not error getting state") .expect("should find state"); - while state.slot < current_slot { + while state.slot() < current_slot { per_slot_processing(&mut state, None, &harness.spec).expect("should process slot"); } @@ -932,8 +932,8 @@ fn attestation_that_skips_epochs() { .get_item::>(&block_root) .expect("should not error getting block") .expect("should find attestation block") - .message - .slot; + .message() + .slot(); assert!( attestation.data.slot - block_slot > E::slots_per_epoch() * 2, diff --git a/beacon_node/beacon_chain/tests/block_verification.rs b/beacon_node/beacon_chain/tests/block_verification.rs index 1bd12b6e308..c085d036fd9 100644 --- a/beacon_node/beacon_chain/tests/block_verification.rs +++ b/beacon_node/beacon_chain/tests/block_verification.rs @@ -98,10 +98,11 @@ fn update_proposal_signatures( .get(proposer_index) .expect("proposer keypair should be available"); - snapshot.beacon_block = snapshot.beacon_block.message.clone().sign( + let (block, _) = snapshot.beacon_block.clone().deconstruct(); + snapshot.beacon_block = block.sign( &keypair.sk, - &state.fork, - state.genesis_validators_root, + &state.fork(), + state.genesis_validators_root(), spec, ); } @@ -111,7 +112,9 @@ fn update_parent_roots(snapshots: &mut [BeaconSnapshot]) { for i in 0..snapshots.len() { let root = snapshots[i].beacon_block.canonical_root(); if let Some(child) = snapshots.get_mut(i + 1) { - child.beacon_block.message.parent_root = root + let (mut block, signature) = child.beacon_block.clone().deconstruct(); + *block.parent_root_mut() = root; + child.beacon_block = SignedBeaconBlock::from_block(block, signature) } } } @@ -217,7 +220,9 @@ fn chain_segment_non_linear_parent_roots() { * Test with a modified parent root. */ let mut blocks = chain_segment_blocks(); - blocks[3].message.parent_root = Hash256::zero(); + let (mut block, signature) = blocks[3].clone().deconstruct(); + *block.parent_root_mut() = Hash256::zero(); + blocks[3] = SignedBeaconBlock::from_block(block, signature); assert!( matches!( @@ -244,7 +249,9 @@ fn chain_segment_non_linear_slots() { */ let mut blocks = chain_segment_blocks(); - blocks[3].message.slot = Slot::new(0); + let (mut block, signature) = blocks[3].clone().deconstruct(); + *block.slot_mut() = Slot::new(0); + blocks[3] = SignedBeaconBlock::from_block(block, signature); assert!( matches!( @@ -262,7 +269,9 @@ fn chain_segment_non_linear_slots() { */ let mut blocks = chain_segment_blocks(); - blocks[3].message.slot = blocks[2].message.slot; + let (mut block, signature) = blocks[3].clone().deconstruct(); + *block.slot_mut() = blocks[2].slot(); + blocks[3] = SignedBeaconBlock::from_block(block, signature); assert!( matches!( @@ -342,7 +351,9 @@ fn invalid_signature_gossip_block() { // Ensure the block will be rejected if imported on its own (without gossip checking). let harness = get_invalid_sigs_harness(); let mut snapshots = CHAIN_SEGMENT.clone(); - snapshots[block_index].beacon_block.signature = junk_signature(); + let (block, _) = snapshots[block_index].beacon_block.clone().deconstruct(); + snapshots[block_index].beacon_block = + SignedBeaconBlock::from_block(block.clone(), junk_signature()); // Import all the ancestors before the `block_index` block. let ancestor_blocks = CHAIN_SEGMENT .iter() @@ -358,7 +369,7 @@ fn invalid_signature_gossip_block() { matches!( harness .chain - .process_block(snapshots[block_index].beacon_block.clone()), + .process_block(SignedBeaconBlock::from_block(block, junk_signature())), Err(BlockError::InvalidSignature) ), "should not import individual block with an invalid gossip signature", @@ -371,7 +382,9 @@ fn invalid_signature_block_proposal() { for &block_index in BLOCK_INDICES { let harness = get_invalid_sigs_harness(); let mut snapshots = CHAIN_SEGMENT.clone(); - snapshots[block_index].beacon_block.signature = junk_signature(); + let (block, _) = snapshots[block_index].beacon_block.clone().deconstruct(); + snapshots[block_index].beacon_block = + SignedBeaconBlock::from_block(block.clone(), junk_signature()); let blocks = snapshots .iter() .map(|snapshot| snapshot.beacon_block.clone()) @@ -395,11 +408,9 @@ fn invalid_signature_randao_reveal() { for &block_index in BLOCK_INDICES { let harness = get_invalid_sigs_harness(); let mut snapshots = CHAIN_SEGMENT.clone(); - snapshots[block_index] - .beacon_block - .message - .body - .randao_reveal = junk_signature(); + let (mut block, signature) = snapshots[block_index].beacon_block.clone().deconstruct(); + *block.randao_reveal_mut() = junk_signature(); + snapshots[block_index].beacon_block = SignedBeaconBlock::from_block(block, signature); update_parent_roots(&mut snapshots); update_proposal_signatures(&mut snapshots, &harness); assert_invalid_signature(&harness, block_index, &snapshots, "randao"); @@ -411,23 +422,22 @@ fn invalid_signature_proposer_slashing() { for &block_index in BLOCK_INDICES { let harness = get_invalid_sigs_harness(); let mut snapshots = CHAIN_SEGMENT.clone(); + let (mut block, signature) = snapshots[block_index].beacon_block.clone().deconstruct(); let proposer_slashing = ProposerSlashing { signed_header_1: SignedBeaconBlockHeader { - message: snapshots[block_index].beacon_block.message.block_header(), + message: block.block_header(), signature: junk_signature(), }, signed_header_2: SignedBeaconBlockHeader { - message: snapshots[block_index].beacon_block.message.block_header(), + message: block.block_header(), signature: junk_signature(), }, }; - snapshots[block_index] - .beacon_block - .message - .body - .proposer_slashings + block + .proposer_slashings_mut() .push(proposer_slashing) .expect("should update proposer slashing"); + snapshots[block_index].beacon_block = SignedBeaconBlock::from_block(block, signature); update_parent_roots(&mut snapshots); update_proposal_signatures(&mut snapshots, &harness); assert_invalid_signature(&harness, block_index, &snapshots, "proposer slashing"); @@ -460,13 +470,12 @@ fn invalid_signature_attester_slashing() { attestation_1: indexed_attestation.clone(), attestation_2: indexed_attestation, }; - snapshots[block_index] - .beacon_block - .message - .body - .attester_slashings + let (mut block, signature) = snapshots[block_index].beacon_block.clone().deconstruct(); + block + .attester_slashings_mut() .push(attester_slashing) .expect("should update attester slashing"); + snapshots[block_index].beacon_block = SignedBeaconBlock::from_block(block, signature); update_parent_roots(&mut snapshots); update_proposal_signatures(&mut snapshots, &harness); assert_invalid_signature(&harness, block_index, &snapshots, "attester slashing"); @@ -480,14 +489,10 @@ fn invalid_signature_attestation() { for &block_index in BLOCK_INDICES { let harness = get_invalid_sigs_harness(); let mut snapshots = CHAIN_SEGMENT.clone(); - if let Some(attestation) = snapshots[block_index] - .beacon_block - .message - .body - .attestations - .get_mut(0) - { + let (mut block, signature) = snapshots[block_index].beacon_block.clone().deconstruct(); + if let Some(attestation) = block.attestations_mut().get_mut(0) { attestation.signature = junk_aggregate_signature(); + snapshots[block_index].beacon_block = SignedBeaconBlock::from_block(block, signature); update_parent_roots(&mut snapshots); update_proposal_signatures(&mut snapshots, &harness); assert_invalid_signature(&harness, block_index, &snapshots, "attestation"); @@ -516,13 +521,12 @@ fn invalid_signature_deposit() { signature: junk_signature().into(), }, }; - snapshots[block_index] - .beacon_block - .message - .body - .deposits + let (mut block, signature) = snapshots[block_index].beacon_block.clone().deconstruct(); + block + .deposits_mut() .push(deposit) .expect("should update deposit"); + snapshots[block_index].beacon_block = SignedBeaconBlock::from_block(block, signature); update_parent_roots(&mut snapshots); update_proposal_signatures(&mut snapshots, &harness); let blocks = snapshots @@ -548,11 +552,9 @@ fn invalid_signature_exit() { let harness = get_invalid_sigs_harness(); let mut snapshots = CHAIN_SEGMENT.clone(); let epoch = snapshots[block_index].beacon_state.current_epoch(); - snapshots[block_index] - .beacon_block - .message - .body - .voluntary_exits + let (mut block, signature) = snapshots[block_index].beacon_block.clone().deconstruct(); + block + .voluntary_exits_mut() .push(SignedVoluntaryExit { message: VoluntaryExit { epoch, @@ -561,6 +563,7 @@ fn invalid_signature_exit() { signature: junk_signature(), }) .expect("should update deposit"); + snapshots[block_index].beacon_block = SignedBeaconBlock::from_block(block, signature); update_parent_roots(&mut snapshots); update_proposal_signatures(&mut snapshots, &harness); assert_invalid_signature(&harness, block_index, &snapshots, "voluntary exit"); @@ -608,12 +611,15 @@ fn block_gossip_verification() { * future blocks for processing at the appropriate slot). */ - let mut block = CHAIN_SEGMENT[block_index].beacon_block.clone(); - let expected_block_slot = block.message.slot + 1; - block.message.slot = expected_block_slot; + let (mut block, signature) = CHAIN_SEGMENT[block_index] + .beacon_block + .clone() + .deconstruct(); + let expected_block_slot = block.slot() + 1; + *block.slot_mut() = expected_block_slot; assert!( matches!( - unwrap_err(harness.chain.verify_block_for_gossip(block)), + unwrap_err(harness.chain.verify_block_for_gossip(SignedBeaconBlock::from_block(block, signature))), BlockError::FutureSlot { present_slot, block_slot, @@ -635,7 +641,10 @@ fn block_gossip_verification() { * nodes, etc). */ - let mut block = CHAIN_SEGMENT[block_index].beacon_block.clone(); + let (mut block, signature) = CHAIN_SEGMENT[block_index] + .beacon_block + .clone() + .deconstruct(); let expected_finalized_slot = harness .chain .head_info() @@ -643,10 +652,10 @@ fn block_gossip_verification() { .finalized_checkpoint .epoch .start_slot(E::slots_per_epoch()); - block.message.slot = expected_finalized_slot; + *block.slot_mut() = expected_finalized_slot; assert!( matches!( - unwrap_err(harness.chain.verify_block_for_gossip(block)), + unwrap_err(harness.chain.verify_block_for_gossip(SignedBeaconBlock::from_block(block, signature))), BlockError::WouldRevertFinalizedSlot { block_slot, finalized_slot, @@ -665,11 +674,21 @@ fn block_gossip_verification() { * proposer_index pubkey. */ - let mut block = CHAIN_SEGMENT[block_index].beacon_block.clone(); - block.signature = junk_signature(); + let block = CHAIN_SEGMENT[block_index] + .beacon_block + .clone() + .deconstruct() + .0; assert!( matches!( - unwrap_err(harness.chain.verify_block_for_gossip(block)), + unwrap_err( + harness + .chain + .verify_block_for_gossip(SignedBeaconBlock::from_block( + block, + junk_signature() + )) + ), BlockError::ProposalSignatureInvalid ), "should not import a block with an invalid proposal signature" @@ -683,12 +702,15 @@ fn block_gossip_verification() { * The block's parent (defined by block.parent_root) passes validation. */ - let mut block = CHAIN_SEGMENT[block_index].beacon_block.clone(); + let (mut block, signature) = CHAIN_SEGMENT[block_index] + .beacon_block + .clone() + .deconstruct(); let parent_root = Hash256::from_low_u64_be(42); - block.message.parent_root = parent_root; + *block.parent_root_mut() = parent_root; assert!( matches!( - unwrap_err(harness.chain.verify_block_for_gossip(block)), + unwrap_err(harness.chain.verify_block_for_gossip(SignedBeaconBlock::from_block(block, signature))), BlockError::ParentUnknown(block) if block.parent_root() == parent_root ), @@ -705,12 +727,15 @@ fn block_gossip_verification() { * store.finalized_checkpoint.root */ - let mut block = CHAIN_SEGMENT[block_index].beacon_block.clone(); + let (mut block, signature) = CHAIN_SEGMENT[block_index] + .beacon_block + .clone() + .deconstruct(); let parent_root = CHAIN_SEGMENT[0].beacon_block_root; - block.message.parent_root = parent_root; + *block.parent_root_mut() = parent_root; assert!( matches!( - unwrap_err(harness.chain.verify_block_for_gossip(block)), + unwrap_err(harness.chain.verify_block_for_gossip(SignedBeaconBlock::from_block(block, signature))), BlockError::NotFinalizedDescendant { block_parent_root } if block_parent_root == parent_root ), @@ -728,14 +753,18 @@ fn block_gossip_verification() { * processing while proposers for the block's branch are calculated. */ - let mut block = CHAIN_SEGMENT[block_index].beacon_block.clone(); - let expected_proposer = block.message.proposer_index; + let mut block = CHAIN_SEGMENT[block_index] + .beacon_block + .clone() + .deconstruct() + .0; + let expected_proposer = block.proposer_index(); let other_proposer = (0..VALIDATOR_COUNT as u64) .into_iter() - .find(|i| *i != block.message.proposer_index) + .find(|i| *i != block.proposer_index()) .expect("there must be more than one validator in this test"); - block.message.proposer_index = other_proposer; - let block = block.message.clone().sign( + *block.proposer_index_mut() = other_proposer; + let block = block.sign( &generate_deterministic_keypair(other_proposer as usize).sk, &harness.chain.head_info().unwrap().fork, harness.chain.genesis_validators_root, @@ -760,7 +789,7 @@ fn block_gossip_verification() { proposer, slot, } - if proposer == other_proposer && slot == block.message.slot + if proposer == other_proposer && slot == block.message().slot() ), "should register any valid signature against the proposer, even if the block failed later verification" ); @@ -792,7 +821,7 @@ fn block_gossip_verification() { proposer, slot, } - if proposer == block.message.proposer_index && slot == block.message.slot + if proposer == block.message().proposer_index() && slot == block.message().slot() ), "the second proposal by this validator should be rejected" ); diff --git a/beacon_node/beacon_chain/tests/op_verification.rs b/beacon_node/beacon_chain/tests/op_verification.rs index 8d86d01ce63..18d2f17b04f 100644 --- a/beacon_node/beacon_chain/tests/op_verification.rs +++ b/beacon_node/beacon_chain/tests/op_verification.rs @@ -13,10 +13,6 @@ use sloggers::{null::NullLoggerBuilder, Build}; use std::sync::Arc; use store::{LevelDB, StoreConfig}; use tempfile::{tempdir, TempDir}; -use types::test_utils::{ - AttesterSlashingTestTask, ProposerSlashingTestTask, TestingAttesterSlashingBuilder, - TestingProposerSlashingBuilder, TestingVoluntaryExitBuilder, -}; use types::*; pub const VALIDATOR_COUNT: usize = 24; @@ -64,21 +60,13 @@ fn voluntary_exit() { AttestationStrategy::AllValidators, ); - let head_info = harness.chain.head_info().unwrap(); - - let make_exit = |validator_index: usize, exit_epoch: u64| { - TestingVoluntaryExitBuilder::new(Epoch::new(exit_epoch), validator_index as u64).build( - &KEYPAIRS[validator_index].sk, - &head_info.fork, - head_info.genesis_validators_root, - spec, - ) - }; - let validator_index1 = VALIDATOR_COUNT - 1; let validator_index2 = VALIDATOR_COUNT - 2; - let exit1 = make_exit(validator_index1, spec.shard_committee_period); + let exit1 = harness.make_voluntary_exit( + validator_index1 as u64, + Epoch::new(spec.shard_committee_period), + ); // First verification should show it to be fresh. assert!(matches!( @@ -98,14 +86,20 @@ fn voluntary_exit() { )); // A different exit for the same validator should also be detected as a duplicate. - let exit2 = make_exit(validator_index1, spec.shard_committee_period + 1); + let exit2 = harness.make_voluntary_exit( + validator_index1 as u64, + Epoch::new(spec.shard_committee_period + 1), + ); assert!(matches!( harness.chain.verify_voluntary_exit_for_gossip(exit2), Ok(ObservationOutcome::AlreadyKnown) )); // Exit for a different validator should be fine. - let exit3 = make_exit(validator_index2, spec.shard_committee_period); + let exit3 = harness.make_voluntary_exit( + validator_index2 as u64, + Epoch::new(spec.shard_committee_period), + ); assert!(matches!( harness .chain @@ -120,25 +114,11 @@ fn proposer_slashing() { let db_path = tempdir().unwrap(); let store = get_store(&db_path); let harness = get_harness(store.clone(), VALIDATOR_COUNT); - let spec = &harness.chain.spec; - - let head_info = harness.chain.head_info().unwrap(); let validator_index1 = VALIDATOR_COUNT - 1; let validator_index2 = VALIDATOR_COUNT - 2; - let make_slashing = |validator_index: usize| { - TestingProposerSlashingBuilder::double_vote::( - ProposerSlashingTestTask::Valid, - validator_index as u64, - &KEYPAIRS[validator_index].sk, - &head_info.fork, - head_info.genesis_validators_root, - spec, - ) - }; - - let slashing1 = make_slashing(validator_index1); + let slashing1 = harness.make_proposer_slashing(validator_index1 as u64); // First slashing for this proposer should be allowed. assert!(matches!( @@ -171,7 +151,7 @@ fn proposer_slashing() { )); // Proposer slashing for a different index should be accepted - let slashing3 = make_slashing(validator_index2); + let slashing3 = harness.make_proposer_slashing(validator_index2 as u64); assert!(matches!( harness .chain @@ -186,9 +166,6 @@ fn attester_slashing() { let db_path = tempdir().unwrap(); let store = get_store(&db_path); let harness = get_harness(store.clone(), VALIDATOR_COUNT); - let spec = &harness.chain.spec; - - let head_info = harness.chain.head_info().unwrap(); // First third of the validators let first_third = (0..VALIDATOR_COUNT as u64 / 3).collect::>(); @@ -199,25 +176,8 @@ fn attester_slashing() { // Last half of the validators let second_half = (VALIDATOR_COUNT as u64 / 2..VALIDATOR_COUNT as u64).collect::>(); - let signer = |idx: u64, message: &[u8]| { - KEYPAIRS[idx as usize] - .sk - .sign(Hash256::from_slice(&message)) - }; - - let make_slashing = |validators| { - TestingAttesterSlashingBuilder::double_vote::<_, E>( - AttesterSlashingTestTask::Valid, - validators, - signer, - &head_info.fork, - head_info.genesis_validators_root, - spec, - ) - }; - // Slashing for first third of validators should be accepted. - let slashing1 = make_slashing(&first_third); + let slashing1 = harness.make_attester_slashing(first_third); assert!(matches!( harness .chain @@ -227,7 +187,7 @@ fn attester_slashing() { )); // Overlapping slashing for first half of validators should also be accepted. - let slashing2 = make_slashing(&first_half); + let slashing2 = harness.make_attester_slashing(first_half); assert!(matches!( harness .chain @@ -253,7 +213,7 @@ fn attester_slashing() { )); // Slashing for last half of validators should be accepted (distinct from all existing) - let slashing3 = make_slashing(&second_half); + let slashing3 = harness.make_attester_slashing(second_half); assert!(matches!( harness .chain @@ -262,7 +222,7 @@ fn attester_slashing() { ObservationOutcome::New(_) )); // Slashing for last third (contained in last half) should be rejected. - let slashing4 = make_slashing(&last_third); + let slashing4 = harness.make_attester_slashing(last_third); assert!(matches!( harness .chain diff --git a/beacon_node/beacon_chain/tests/persistence_tests.rs b/beacon_node/beacon_chain/tests/persistence_tests.rs index 0f5aa8a6b67..1875629e414 100644 --- a/beacon_node/beacon_chain/tests/persistence_tests.rs +++ b/beacon_node/beacon_chain/tests/persistence_tests.rs @@ -62,7 +62,7 @@ fn finalizes_after_resuming_from_db() { .head() .expect("should read head") .beacon_state - .finalized_checkpoint + .finalized_checkpoint() .epoch > 0, "the chain should have already finalized" @@ -115,7 +115,8 @@ fn finalizes_after_resuming_from_db() { .expect("should read head") .beacon_state; assert_eq!( - state.slot, num_blocks_produced, + state.slot(), + num_blocks_produced, "head should be at the current slot" ); assert_eq!( @@ -124,12 +125,12 @@ fn finalizes_after_resuming_from_db() { "head should be at the expected epoch" ); assert_eq!( - state.current_justified_checkpoint.epoch, + state.current_justified_checkpoint().epoch, state.current_epoch() - 1, "the head should be justified one behind the current epoch" ); assert_eq!( - state.finalized_checkpoint.epoch, + state.finalized_checkpoint().epoch, state.current_epoch() - 2, "the head should be finalized two behind the current epoch" ); diff --git a/beacon_node/beacon_chain/tests/store_tests.rs b/beacon_node/beacon_chain/tests/store_tests.rs index a25663178cd..18b11842cc2 100644 --- a/beacon_node/beacon_chain/tests/store_tests.rs +++ b/beacon_node/beacon_chain/tests/store_tests.rs @@ -107,7 +107,11 @@ fn randomised_skips() { let state = &harness.chain.head().expect("should get head").beacon_state; - assert_eq!(state.slot, num_slots, "head should be at the current slot"); + assert_eq!( + state.slot(), + num_slots, + "head should be at the current slot" + ); check_split_slot(&harness, store); check_chain_dump(&harness, num_blocks_produced + 1); @@ -195,7 +199,7 @@ fn randao_genesis_storage() { .head() .expect("should get head") .beacon_state - .randao_mixes + .randao_mixes() .iter() .find(|x| **x == genesis_value) .is_some()); @@ -212,7 +216,7 @@ fn randao_genesis_storage() { .head() .expect("should get head") .beacon_state - .randao_mixes + .randao_mixes() .iter() .find(|x| **x == genesis_value) .is_none()); @@ -550,18 +554,21 @@ fn multiple_attestations_per_block() { let head = harness.chain.head().unwrap(); let committees_per_slot = head .beacon_state - .get_committee_count_at_slot(head.beacon_state.slot) + .get_committee_count_at_slot(head.beacon_state.slot()) .unwrap(); assert!(committees_per_slot > 1); for snapshot in harness.chain.chain_dump().unwrap() { + let slot = snapshot.beacon_block.slot(); assert_eq!( - snapshot.beacon_block.message.body.attestations.len() as u64, - if snapshot.beacon_block.slot() <= 1 { - 0 - } else { - committees_per_slot - } + snapshot + .beacon_block + .deconstruct() + .0 + .body() + .attestations() + .len() as u64, + if slot <= 1 { 0 } else { committees_per_slot } ); } } @@ -1691,15 +1698,17 @@ fn garbage_collect_temp_states_from_failed_block() { let genesis_state = harness.get_current_state(); let block_slot = Slot::new(2 * slots_per_epoch); - let (mut block, state) = harness.make_block(genesis_state, block_slot); + let (signed_block, state) = harness.make_block(genesis_state, block_slot); + + let (mut block, _) = signed_block.deconstruct(); // Mutate the block to make it invalid, and re-sign it. - block.message.state_root = Hash256::repeat_byte(0xff); - let proposer_index = block.message.proposer_index as usize; - let block = block.message.sign( + *block.state_root_mut() = Hash256::repeat_byte(0xff); + let proposer_index = block.proposer_index() as usize; + let block = block.sign( &harness.validator_keypairs[proposer_index].sk, - &state.fork, - state.genesis_validators_root, + &state.fork(), + state.genesis_validators_root(), &harness.spec, ); @@ -1725,7 +1734,8 @@ fn check_slot(harness: &TestHarness, expected_slot: u64) { let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( - state.slot, expected_slot, + state.slot(), + expected_slot, "head should be at the current slot" ); } @@ -1737,12 +1747,12 @@ fn check_finalization(harness: &TestHarness, expected_slot: u64) { check_slot(harness, expected_slot); assert_eq!( - state.current_justified_checkpoint.epoch, + state.current_justified_checkpoint().epoch, state.current_epoch() - 1, "the head should be justified one behind the current epoch" ); assert_eq!( - state.finalized_checkpoint.epoch, + state.finalized_checkpoint().epoch, state.current_epoch() - 2, "the head should be finalized two behind the current epoch" ); @@ -1757,7 +1767,7 @@ fn check_split_slot(harness: &TestHarness, store: Arc, L .head() .expect("should get head") .beacon_state - .finalized_checkpoint + .finalized_checkpoint() .epoch .start_slot(E::slots_per_epoch()), split_slot @@ -1788,8 +1798,8 @@ fn check_chain_dump(harness: &TestHarness, expected_len: u64) { .get_state(&checkpoint.beacon_state_root(), None) .expect("no error") .expect("state exists") - .slot, - checkpoint.beacon_state.slot + .slot(), + checkpoint.beacon_state.slot() ); } @@ -1866,7 +1876,7 @@ fn get_finalized_epoch_boundary_blocks( ) -> HashSet { dump.iter() .cloned() - .map(|checkpoint| checkpoint.beacon_state.finalized_checkpoint.root.into()) + .map(|checkpoint| checkpoint.beacon_state.finalized_checkpoint().root.into()) .collect() } diff --git a/beacon_node/beacon_chain/tests/tests.rs b/beacon_node/beacon_chain/tests/tests.rs index 616f2b544ff..38885776fc5 100644 --- a/beacon_node/beacon_chain/tests/tests.rs +++ b/beacon_node/beacon_chain/tests/tests.rs @@ -51,7 +51,7 @@ fn massive_skips() { } }; - assert!(state.slot > 1, "the state should skip at least one slot"); + assert!(state.slot() > 1, "the state should skip at least one slot"); assert_eq!( error, SlotProcessingError::EpochProcessingError(EpochProcessingError::BeaconStateError( @@ -133,7 +133,7 @@ fn iterators() { assert_eq!( *state_roots.first().expect("should have some state roots"), - (head.beacon_state_root(), head.beacon_state.slot), + (head.beacon_state_root(), head.beacon_state.slot()), "first state root and slot should be for the head state" ); } @@ -171,7 +171,7 @@ fn chooses_fork() { let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( - state.slot, + state.slot(), Slot::from(initial_blocks + honest_fork_blocks), "head should be at the current slot" ); @@ -202,7 +202,8 @@ fn finalizes_with_full_participation() { let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( - state.slot, num_blocks_produced, + state.slot(), + num_blocks_produced, "head should be at the current slot" ); assert_eq!( @@ -211,12 +212,12 @@ fn finalizes_with_full_participation() { "head should be at the expected epoch" ); assert_eq!( - state.current_justified_checkpoint.epoch, + state.current_justified_checkpoint().epoch, state.current_epoch() - 1, "the head should be justified one behind the current epoch" ); assert_eq!( - state.finalized_checkpoint.epoch, + state.finalized_checkpoint().epoch, state.current_epoch() - 2, "the head should be finalized two behind the current epoch" ); @@ -240,7 +241,8 @@ fn finalizes_with_two_thirds_participation() { let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( - state.slot, num_blocks_produced, + state.slot(), + num_blocks_produced, "head should be at the current slot" ); assert_eq!( @@ -254,12 +256,12 @@ fn finalizes_with_two_thirds_participation() { // included in blocks during that epoch. assert_eq!( - state.current_justified_checkpoint.epoch, + state.current_justified_checkpoint().epoch, state.current_epoch() - 2, "the head should be justified two behind the current epoch" ); assert_eq!( - state.finalized_checkpoint.epoch, + state.finalized_checkpoint().epoch, state.current_epoch() - 4, "the head should be finalized three behind the current epoch" ); @@ -284,7 +286,8 @@ fn does_not_finalize_with_less_than_two_thirds_participation() { let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( - state.slot, num_blocks_produced, + state.slot(), + num_blocks_produced, "head should be at the current slot" ); assert_eq!( @@ -293,11 +296,13 @@ fn does_not_finalize_with_less_than_two_thirds_participation() { "head should be at the expected epoch" ); assert_eq!( - state.current_justified_checkpoint.epoch, 0, + state.current_justified_checkpoint().epoch, + 0, "no epoch should have been justified" ); assert_eq!( - state.finalized_checkpoint.epoch, 0, + state.finalized_checkpoint().epoch, + 0, "no epoch should have been finalized" ); } @@ -317,7 +322,8 @@ fn does_not_finalize_without_attestation() { let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( - state.slot, num_blocks_produced, + state.slot(), + num_blocks_produced, "head should be at the current slot" ); assert_eq!( @@ -326,11 +332,13 @@ fn does_not_finalize_without_attestation() { "head should be at the expected epoch" ); assert_eq!( - state.current_justified_checkpoint.epoch, 0, + state.current_justified_checkpoint().epoch, + 0, "no epoch should have been justified" ); assert_eq!( - state.finalized_checkpoint.epoch, 0, + state.finalized_checkpoint().epoch, + 0, "no epoch should have been finalized" ); } diff --git a/beacon_node/genesis/src/eth1_genesis_service.rs b/beacon_node/genesis/src/eth1_genesis_service.rs index f0ddad16552..d5ef6ad0d90 100644 --- a/beacon_node/genesis/src/eth1_genesis_service.rs +++ b/beacon_node/genesis/src/eth1_genesis_service.rs @@ -5,7 +5,7 @@ use eth1::{DepositLog, Eth1Block, Service as Eth1Service}; use slog::{debug, error, info, trace, Logger}; use state_processing::{ eth2_genesis_time, initialize_beacon_state_from_eth1, is_valid_genesis_state, - per_block_processing::process_operations::base::process_deposit, process_activations, + per_block_processing::process_operations::process_deposit, process_activations, }; use std::sync::{ atomic::{AtomicU64, AtomicUsize, Ordering}, diff --git a/beacon_node/genesis/src/interop.rs b/beacon_node/genesis/src/interop.rs index 89d29e92fca..addb4ef142c 100644 --- a/beacon_node/genesis/src/interop.rs +++ b/beacon_node/genesis/src/interop.rs @@ -75,24 +75,25 @@ mod test { .expect("should build state"); assert_eq!( - state.eth1_data.block_hash, + state.eth1_data().block_hash, Hash256::from_slice(&[0x42; 32]), "eth1 block hash should be co-ordinated junk" ); assert_eq!( - state.genesis_time, genesis_time, + state.genesis_time(), + genesis_time, "genesis time should be as specified" ); - for b in &state.balances { + for b in state.balances() { assert_eq!( *b, spec.max_effective_balance, "validator balances should be max effective balance" ); } - for v in &state.validators { + for v in state.validators() { let creds = v.withdrawal_credentials.as_bytes(); assert_eq!( creds[0], spec.bls_withdrawal_prefix_byte, @@ -106,13 +107,13 @@ mod test { } assert_eq!( - state.balances.len(), + state.balances().len(), validator_count, "validator balances len should be correct" ); assert_eq!( - state.validators.len(), + state.validators().len(), validator_count, "validator count should be correct" ); diff --git a/beacon_node/genesis/tests/tests.rs b/beacon_node/genesis/tests/tests.rs index c5fd2192841..95378a6b8c7 100644 --- a/beacon_node/genesis/tests/tests.rs +++ b/beacon_node/genesis/tests/tests.rs @@ -91,7 +91,7 @@ fn basic() { // Note: using ganache these deposits are 1-per-block, therefore we know there should only be // the minimum number of validators. assert_eq!( - state.validators.len(), + state.validators().len(), spec.min_genesis_active_validator_count as usize, "should have expected validator count" ); diff --git a/beacon_node/operation_pool/src/attestation.rs b/beacon_node/operation_pool/src/attestation.rs index 0bd2d3d0d22..57949f5f822 100644 --- a/beacon_node/operation_pool/src/attestation.rs +++ b/beacon_node/operation_pool/src/attestation.rs @@ -1,5 +1,6 @@ use crate::max_cover::MaxCover; -use state_processing::common::{get_attesting_indices, get_base_reward}; +//TODO: altair::base_reward +use state_processing::common::{base::get_base_reward, get_attesting_indices}; use std::collections::HashMap; use types::{Attestation, BeaconState, BitList, ChainSpec, EthSpec}; diff --git a/beacon_node/store/src/partial_beacon_state.rs b/beacon_node/store/src/partial_beacon_state.rs index 6edc4dd70b3..fee317a29e5 100644 --- a/beacon_node/store/src/partial_beacon_state.rs +++ b/beacon_node/store/src/partial_beacon_state.rs @@ -306,6 +306,7 @@ macro_rules! impl_try_into_beacon_state { pubkey_cache: <_>::default(), exit_cache: <_>::default(), tree_hash_cache: <_>::default(), + current_sync_committee_cache: <_>::default(), // Variant-specific fields $( diff --git a/consensus/state_processing/src/per_block_processing/tests.rs b/consensus/state_processing/src/per_block_processing/tests.rs index 471ca011dda..79fa4f5cd30 100644 --- a/consensus/state_processing/src/per_block_processing/tests.rs +++ b/consensus/state_processing/src/per_block_processing/tests.rs @@ -167,7 +167,7 @@ fn invalid_deposit_deposit_count_too_big() { builder.build_with_n_deposits(NUM_DEPOSITS, test_task, None, None, &spec); let big_deposit_count = NUM_DEPOSITS + 1; - state.eth1_data.deposit_count = big_deposit_count; + state.eth1_data_mut().deposit_count = big_deposit_count; let result = per_block_processing( &mut state, @@ -197,7 +197,7 @@ fn invalid_deposit_count_too_small() { builder.build_with_n_deposits(NUM_DEPOSITS, test_task, None, None, &spec); let small_deposit_count = NUM_DEPOSITS - 1; - state.eth1_data.deposit_count = small_deposit_count; + state.eth1_data_mut().deposit_count = small_deposit_count; let result = per_block_processing( &mut state, diff --git a/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs b/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs index 65dcf0b2946..3c197d59029 100644 --- a/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs +++ b/consensus/state_processing/src/per_epoch_processing/altair/rewards_and_penalties.rs @@ -152,23 +152,3 @@ fn get_inactivity_penalty_deltas( } Ok(()) } - -/// Return the combined effective balance of an array of validators. -/// -/// Spec v1.1.0 -pub fn get_total_active_balance( - state: &BeaconState, - spec: &ChainSpec, -) -> Result { - let total_balance = state.get_total_balance( - state - .get_active_validator_indices(state.current_epoch(), spec)? - .as_slice(), - spec, - )?; - //TODO: this comparator should be in `get_total_balance` - Ok(std::cmp::max( - spec.effective_balance_increment, - total_balance, - )) -} diff --git a/consensus/tree_hash/benches/benches.rs b/consensus/tree_hash/benches/benches.rs index 4728dc47910..d189d71d80a 100644 --- a/consensus/tree_hash/benches/benches.rs +++ b/consensus/tree_hash/benches/benches.rs @@ -17,8 +17,8 @@ fn build_state(validator_count: usize) -> BeaconState { ) .build(); - assert_eq!(state.validators.len(), validator_count); - assert_eq!(state.balances.len(), validator_count); + assert_eq!(state.validators().len(), validator_count); + assert_eq!(state.balances().len(), validator_count); assert!(state.previous_epoch_attestations.is_empty()); assert!(state.current_epoch_attestations.is_empty()); assert!(state.eth1_data_votes.is_empty()); diff --git a/consensus/tree_hash/examples/flamegraph_beacon_state.rs b/consensus/tree_hash/examples/flamegraph_beacon_state.rs index f4934ec83c1..1101961e5f6 100644 --- a/consensus/tree_hash/examples/flamegraph_beacon_state.rs +++ b/consensus/tree_hash/examples/flamegraph_beacon_state.rs @@ -9,8 +9,8 @@ fn build_state(validator_count: usize) -> BeaconState { TestingBeaconStateBuilder::from_deterministic_keypairs(validator_count, &T::default_spec()) .build(); - assert_eq!(state.validators.len(), validator_count); - assert_eq!(state.balances.len(), validator_count); + assert_eq!(state.validators().len(), validator_count); + assert_eq!(state.balances().len(), validator_count); assert!(state.previous_epoch_attestations.is_empty()); assert!(state.current_epoch_attestations.is_empty()); assert!(state.eth1_data_votes.is_empty()); diff --git a/consensus/types/src/beacon_block.rs b/consensus/types/src/beacon_block.rs index ac7c94b97db..25e7edc373f 100644 --- a/consensus/types/src/beacon_block.rs +++ b/consensus/types/src/beacon_block.rs @@ -199,6 +199,54 @@ impl BeaconBlock { self.to_ref().body() } + pub fn voluntary_exits_mut( + &mut self, + ) -> &mut VariableList { + match self { + BeaconBlock::Base(block) => &mut block.body.voluntary_exits, + BeaconBlock::Altair(block) => &mut block.body.voluntary_exits, + } + } + + pub fn attestations_mut(&mut self) -> &mut VariableList, T::MaxAttestations> { + match self { + BeaconBlock::Base(block) => &mut block.body.attestations, + BeaconBlock::Altair(block) => &mut block.body.attestations, + } + } + + pub fn attester_slashings_mut( + &mut self, + ) -> &mut VariableList, T::MaxAttesterSlashings> { + match self { + BeaconBlock::Base(block) => &mut block.body.attester_slashings, + BeaconBlock::Altair(block) => &mut block.body.attester_slashings, + } + } + + pub fn proposer_slashings_mut( + &mut self, + ) -> &mut VariableList { + match self { + BeaconBlock::Base(block) => &mut block.body.proposer_slashings, + BeaconBlock::Altair(block) => &mut block.body.proposer_slashings, + } + } + + pub fn randao_reveal_mut(&mut self) -> &mut Signature { + match self { + BeaconBlock::Base(block) => &mut block.body.randao_reveal, + BeaconBlock::Altair(block) => &mut block.body.randao_reveal, + } + } + + pub fn deposits_mut(&mut self) -> &mut VariableList { + match self { + BeaconBlock::Base(block) => &mut block.body.deposits, + BeaconBlock::Altair(block) => &mut block.body.deposits, + } + } + /// Returns the epoch corresponding to `self.slot()`. pub fn epoch(&self) -> Epoch { self.slot().epoch(T::slots_per_epoch()) diff --git a/consensus/types/src/beacon_state/tests.rs b/consensus/types/src/beacon_state/tests.rs index 5fef50a9064..82e4e30d2c0 100644 --- a/consensus/types/src/beacon_state/tests.rs +++ b/consensus/types/src/beacon_state/tests.rs @@ -437,8 +437,8 @@ mod get_outstanding_deposit_len { let mut state = state(); assert_eq!(state.get_outstanding_deposit_len(), Ok(0)); - state.eth1_data.deposit_count = 17; - state.eth1_deposit_index = 16; + state.eth1_data_mut().deposit_count = 17; + *state.eth1_deposit_index_mut() = 16; assert_eq!(state.get_outstanding_deposit_len(), Ok(1)); } @@ -446,8 +446,8 @@ mod get_outstanding_deposit_len { fn returns_err_if_the_state_is_invalid() { let mut state = state(); // The state is invalid, deposit count is lower than deposit index. - state.eth1_data.deposit_count = 16; - state.eth1_deposit_index = 17; + state.eth1_data_mut().deposit_count = 16; + *state.eth1_deposit_index_mut() = 17; assert_eq!( state.get_outstanding_deposit_len(), diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index af16fb1d91a..0364d1928fa 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -100,7 +100,9 @@ pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch}; pub use crate::selection_proof::SelectionProof; pub use crate::shuffling_id::AttestationShufflingId; pub use crate::signed_aggregate_and_proof::SignedAggregateAndProof; -pub use crate::signed_beacon_block::{SignedBeaconBlock, SignedBeaconBlockHash}; +pub use crate::signed_beacon_block::{ + SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockHash, +}; pub use crate::signed_beacon_block_header::SignedBeaconBlockHeader; pub use crate::signed_voluntary_exit::SignedVoluntaryExit; pub use crate::signing_data::{SignedRoot, SigningData}; diff --git a/consensus/types/src/test_utils/builders/testing_beacon_block_builder.rs b/consensus/types/src/test_utils/builders/testing_beacon_block_builder.rs index b95981ae5a2..d6213d7b3a9 100644 --- a/consensus/types/src/test_utils/builders/testing_beacon_block_builder.rs +++ b/consensus/types/src/test_utils/builders/testing_beacon_block_builder.rs @@ -334,8 +334,8 @@ impl TestingBeaconBlockBuilder { if test_task == DepositTestTask::NoReset { state.eth1_data.deposit_count += num_deposits; } else { - state.eth1_deposit_index = 0; - state.eth1_data.deposit_count = num_deposits; + *state.eth1_deposit_index_mut() = 0; + state.eth1_data_mut().deposit_count = num_deposits; } } diff --git a/consensus/types/src/test_utils/builders/testing_beacon_state_builder.rs b/consensus/types/src/test_utils/builders/testing_beacon_state_builder.rs index 922d4017fea..3efdafe585e 100644 --- a/consensus/types/src/test_utils/builders/testing_beacon_state_builder.rs +++ b/consensus/types/src/test_utils/builders/testing_beacon_state_builder.rs @@ -84,8 +84,8 @@ impl TestingBeaconStateBuilder { spec, ); - state.eth1_data.deposit_count = validator_count as u64; - state.eth1_deposit_index = validator_count as u64; + state.eth1_data_mut().deposit_count = validator_count as u64; + *state.eth1_deposit_index_mut() = validator_count as u64; let balances = vec![starting_balance; validator_count].into();