From 6df5eee7f49809da48868629c1567860c957d3fc Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Sun, 17 Mar 2019 18:10:20 +1100 Subject: [PATCH] Update beacon_chain crate with v0.5.0 updates --- .../src/attestation_aggregator.rs | 53 ++++----- beacon_node/beacon_chain/src/beacon_chain.rs | 104 ++++++++---------- 2 files changed, 67 insertions(+), 90 deletions(-) diff --git a/beacon_node/beacon_chain/src/attestation_aggregator.rs b/beacon_node/beacon_chain/src/attestation_aggregator.rs index 75cfd7ee5..9b4e5a687 100644 --- a/beacon_node/beacon_chain/src/attestation_aggregator.rs +++ b/beacon_node/beacon_chain/src/attestation_aggregator.rs @@ -1,4 +1,3 @@ -use log::trace; use ssz::TreeHash; use state_processing::per_block_processing::validate_attestation_without_signature; use std::collections::{HashMap, HashSet}; @@ -86,34 +85,22 @@ impl AttestationAggregator { free_attestation: &FreeAttestation, spec: &ChainSpec, ) -> Result { - let attestation_duties = match state.attestation_slot_and_shard_for_validator( - free_attestation.validator_index as usize, - spec, - ) { - Err(BeaconStateError::EpochCacheUninitialized(e)) => { - panic!("Attempted to access unbuilt cache {:?}.", e) - } - Err(BeaconStateError::EpochOutOfBounds) => invalid_outcome!(Message::TooOld), - Err(BeaconStateError::ShardOutOfBounds) => invalid_outcome!(Message::BadShard), - Err(e) => return Err(e), - Ok(None) => invalid_outcome!(Message::BadValidatorIndex), - Ok(Some(attestation_duties)) => attestation_duties, - }; + let duties = + match state.get_attestation_duties(free_attestation.validator_index as usize, spec) { + Err(BeaconStateError::EpochCacheUninitialized(e)) => { + panic!("Attempted to access unbuilt cache {:?}.", e) + } + Err(BeaconStateError::EpochOutOfBounds) => invalid_outcome!(Message::TooOld), + Err(BeaconStateError::ShardOutOfBounds) => invalid_outcome!(Message::BadShard), + Err(e) => return Err(e), + Ok(None) => invalid_outcome!(Message::BadValidatorIndex), + Ok(Some(attestation_duties)) => attestation_duties, + }; - let (slot, shard, committee_index) = attestation_duties; - - trace!( - "slot: {}, shard: {}, committee_index: {}, val_index: {}", - slot, - shard, - committee_index, - free_attestation.validator_index - ); - - if free_attestation.data.slot != slot { + if free_attestation.data.slot != duties.slot { invalid_outcome!(Message::BadSlot); } - if free_attestation.data.shard != shard { + if free_attestation.data.shard != duties.shard { invalid_outcome!(Message::BadShard); } @@ -143,7 +130,7 @@ impl AttestationAggregator { if let Some(updated_attestation) = aggregate_attestation( existing_attestation, &free_attestation.signature, - committee_index as usize, + duties.committee_index as usize, ) { self.store.insert(signable_message, updated_attestation); valid_outcome!(Message::Aggregated); @@ -154,7 +141,7 @@ impl AttestationAggregator { let mut aggregate_signature = AggregateSignature::new(); aggregate_signature.add(&free_attestation.signature); let mut aggregation_bitfield = Bitfield::new(); - aggregation_bitfield.set(committee_index as usize, true); + aggregation_bitfield.set(duties.committee_index as usize, true); let new_attestation = Attestation { data: free_attestation.data.clone(), aggregation_bitfield, @@ -177,9 +164,13 @@ impl AttestationAggregator { ) -> Vec { let mut known_attestation_data: HashSet = HashSet::new(); - state.latest_attestations.iter().for_each(|attestation| { - known_attestation_data.insert(attestation.data.clone()); - }); + state + .previous_epoch_attestations + .iter() + .chain(state.current_epoch_attestations.iter()) + .for_each(|attestation| { + known_attestation_data.insert(attestation.data.clone()); + }); self.store .values() diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index b0e84e1e1..1082f6cab 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -15,10 +15,7 @@ use state_processing::{ per_slot_processing, BlockProcessingError, SlotProcessingError, }; use std::sync::Arc; -use types::{ - readers::{BeaconBlockReader, BeaconStateReader}, - *, -}; +use types::*; #[derive(Debug, PartialEq)] pub enum ValidBlock { @@ -106,7 +103,8 @@ where genesis_state.build_epoch_cache(RelativeEpoch::Previous, &spec)?; genesis_state.build_epoch_cache(RelativeEpoch::Current, &spec)?; - genesis_state.build_epoch_cache(RelativeEpoch::Next, &spec)?; + genesis_state.build_epoch_cache(RelativeEpoch::NextWithoutRegistryChange, &spec)?; + genesis_state.build_epoch_cache(RelativeEpoch::NextWithRegistryChange, &spec)?; Ok(Self { block_store, @@ -248,19 +246,15 @@ where /// present and prior epoch is available. pub fn block_proposer(&self, slot: Slot) -> Result { trace!("BeaconChain::block_proposer: slot: {}", slot); - let index = self - .state - .read() - .get_beacon_proposer_index(slot, &self.spec)?; + let index = self.state.read().get_beacon_proposer_index( + slot, + RelativeEpoch::Current, + &self.spec, + )?; Ok(index) } - /// Returns the justified slot for the present state. - pub fn justified_epoch(&self) -> Epoch { - self.state.read().justified_epoch - } - /// Returns the attestation slot and shard for a given validator index. /// /// Information is read from the current state, so only information from the present and prior @@ -273,12 +267,12 @@ where "BeaconChain::validator_attestion_slot_and_shard: validator_index: {}", validator_index ); - if let Some((slot, shard, _committee)) = self + if let Some(attestation_duty) = self .state .read() - .attestation_slot_and_shard_for_validator(validator_index, &self.spec)? + .get_attestation_duties(validator_index, &self.spec)? { - Ok(Some((slot, shard))) + Ok(Some((attestation_duty.slot, attestation_duty.shard))) } else { Ok(None) } @@ -287,37 +281,33 @@ where /// Produce an `AttestationData` that is valid for the present `slot` and given `shard`. pub fn produce_attestation_data(&self, shard: u64) -> Result { trace!("BeaconChain::produce_attestation_data: shard: {}", shard); - let justified_epoch = self.justified_epoch(); - let justified_block_root = *self - .state - .read() - .get_block_root( - justified_epoch.start_slot(self.spec.slots_per_epoch), - &self.spec, - ) - .ok_or_else(|| Error::BadRecentBlockRoots)?; + let source_epoch = self.state.read().current_justified_epoch; + let source_root = *self.state.read().get_block_root( + source_epoch.start_slot(self.spec.slots_per_epoch), + &self.spec, + )?; - let epoch_boundary_root = *self - .state - .read() - .get_block_root( - self.state.read().current_epoch_start_slot(&self.spec), - &self.spec, - ) - .ok_or_else(|| Error::BadRecentBlockRoots)?; + let target_root = *self.state.read().get_block_root( + self.state + .read() + .slot + .epoch(self.spec.slots_per_epoch) + .start_slot(self.spec.slots_per_epoch), + &self.spec, + )?; Ok(AttestationData { slot: self.state.read().slot, shard, beacon_block_root: self.head().beacon_block_root, - epoch_boundary_root, + target_root, crosslink_data_root: Hash256::zero(), - latest_crosslink: Crosslink { + previous_crosslink: Crosslink { epoch: self.state.read().slot.epoch(self.spec.slots_per_epoch), crosslink_data_root: Hash256::zero(), }, - justified_epoch, - justified_block_root, + source_epoch, + source_root, }) } @@ -581,7 +571,7 @@ where dump.push(last_slot.clone()); loop { - let beacon_block_root = last_slot.beacon_block.parent_root; + let beacon_block_root = last_slot.beacon_block.previous_block_root; if beacon_block_root == self.spec.zero_hash { break; // Genesis has been reached. @@ -621,7 +611,7 @@ where /// /// Will accept blocks from prior slots, however it will reject any block from a future slot. pub fn process_block(&self, block: BeaconBlock) -> Result { - debug!("Processing block with slot {}...", block.slot()); + debug!("Processing block with slot {}...", block.slot); let block_root = block.canonical_root(); @@ -635,9 +625,9 @@ where // Load the blocks parent block from the database, returning invalid if that block is not // found. - let parent_block_root = block.parent_root; - let parent_block = match self.block_store.get_reader(&parent_block_root)? { - Some(parent_root) => parent_root, + let parent_block_root = block.previous_block_root; + let parent_block = match self.block_store.get_deserialized(&parent_block_root)? { + Some(previous_block_root) => previous_block_root, None => { return Ok(BlockProcessingOutcome::InvalidBlock( InvalidBlock::ParentUnknown, @@ -647,15 +637,11 @@ where // Load the parent blocks state from the database, returning an error if it is not found. // It is an error because if know the parent block we should also know the parent state. - let parent_state_root = parent_block.state_root(); + let parent_state_root = parent_block.state_root; let parent_state = self .state_store - .get_reader(&parent_state_root)? - .ok_or_else(|| Error::DBInconsistent(format!("Missing state {}", parent_state_root)))? - .into_beacon_state() - .ok_or_else(|| { - Error::DBInconsistent(format!("State SSZ invalid {}", parent_state_root)) - })?; + .get_deserialized(&parent_state_root)? + .ok_or_else(|| Error::DBInconsistent(format!("Missing state {}", parent_state_root)))?; // TODO: check the block proposer signature BEFORE doing a state transition. This will // significantly lower exposure surface to DoS attacks. @@ -739,22 +725,22 @@ where attestations.len() ); - let parent_root = *state + let previous_block_root = *state .get_block_root(state.slot.saturating_sub(1_u64), &self.spec) - .ok_or_else(|| BlockProductionError::UnableToGetBlockRootFromState)?; + .map_err(|_| BlockProductionError::UnableToGetBlockRootFromState)?; let mut block = BeaconBlock { slot: state.slot, - parent_root, + previous_block_root, state_root: Hash256::zero(), // Updated after the state is calculated. - randao_reveal, - eth1_data: Eth1Data { - // TODO: replace with real data - deposit_root: Hash256::zero(), - block_hash: Hash256::zero(), - }, signature: self.spec.empty_signature.clone(), // To be completed by a validator. body: BeaconBlockBody { + randao_reveal, + eth1_data: Eth1Data { + // TODO: replace with real data + deposit_root: Hash256::zero(), + block_hash: Hash256::zero(), + }, proposer_slashings: self.get_proposer_slashings_for_block(), attester_slashings: self.get_attester_slashings_for_block(), attestations,