Update beacon_chain crate with v0.5.0 updates

This commit is contained in:
Paul Hauner 2019-03-17 18:10:20 +11:00
parent d94540c85c
commit 6df5eee7f4
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
2 changed files with 67 additions and 90 deletions

View File

@ -1,4 +1,3 @@
use log::trace;
use ssz::TreeHash; use ssz::TreeHash;
use state_processing::per_block_processing::validate_attestation_without_signature; use state_processing::per_block_processing::validate_attestation_without_signature;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -86,10 +85,8 @@ impl AttestationAggregator {
free_attestation: &FreeAttestation, free_attestation: &FreeAttestation,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<Outcome, BeaconStateError> { ) -> Result<Outcome, BeaconStateError> {
let attestation_duties = match state.attestation_slot_and_shard_for_validator( let duties =
free_attestation.validator_index as usize, match state.get_attestation_duties(free_attestation.validator_index as usize, spec) {
spec,
) {
Err(BeaconStateError::EpochCacheUninitialized(e)) => { Err(BeaconStateError::EpochCacheUninitialized(e)) => {
panic!("Attempted to access unbuilt cache {:?}.", e) panic!("Attempted to access unbuilt cache {:?}.", e)
} }
@ -100,20 +97,10 @@ impl AttestationAggregator {
Ok(Some(attestation_duties)) => attestation_duties, Ok(Some(attestation_duties)) => attestation_duties,
}; };
let (slot, shard, committee_index) = attestation_duties; if free_attestation.data.slot != duties.slot {
trace!(
"slot: {}, shard: {}, committee_index: {}, val_index: {}",
slot,
shard,
committee_index,
free_attestation.validator_index
);
if free_attestation.data.slot != slot {
invalid_outcome!(Message::BadSlot); invalid_outcome!(Message::BadSlot);
} }
if free_attestation.data.shard != shard { if free_attestation.data.shard != duties.shard {
invalid_outcome!(Message::BadShard); invalid_outcome!(Message::BadShard);
} }
@ -143,7 +130,7 @@ impl AttestationAggregator {
if let Some(updated_attestation) = aggregate_attestation( if let Some(updated_attestation) = aggregate_attestation(
existing_attestation, existing_attestation,
&free_attestation.signature, &free_attestation.signature,
committee_index as usize, duties.committee_index as usize,
) { ) {
self.store.insert(signable_message, updated_attestation); self.store.insert(signable_message, updated_attestation);
valid_outcome!(Message::Aggregated); valid_outcome!(Message::Aggregated);
@ -154,7 +141,7 @@ impl AttestationAggregator {
let mut aggregate_signature = AggregateSignature::new(); let mut aggregate_signature = AggregateSignature::new();
aggregate_signature.add(&free_attestation.signature); aggregate_signature.add(&free_attestation.signature);
let mut aggregation_bitfield = Bitfield::new(); 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 { let new_attestation = Attestation {
data: free_attestation.data.clone(), data: free_attestation.data.clone(),
aggregation_bitfield, aggregation_bitfield,
@ -177,7 +164,11 @@ impl AttestationAggregator {
) -> Vec<Attestation> { ) -> Vec<Attestation> {
let mut known_attestation_data: HashSet<AttestationData> = HashSet::new(); let mut known_attestation_data: HashSet<AttestationData> = HashSet::new();
state.latest_attestations.iter().for_each(|attestation| { state
.previous_epoch_attestations
.iter()
.chain(state.current_epoch_attestations.iter())
.for_each(|attestation| {
known_attestation_data.insert(attestation.data.clone()); known_attestation_data.insert(attestation.data.clone());
}); });

View File

@ -15,10 +15,7 @@ use state_processing::{
per_slot_processing, BlockProcessingError, SlotProcessingError, per_slot_processing, BlockProcessingError, SlotProcessingError,
}; };
use std::sync::Arc; use std::sync::Arc;
use types::{ use types::*;
readers::{BeaconBlockReader, BeaconStateReader},
*,
};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum ValidBlock { pub enum ValidBlock {
@ -106,7 +103,8 @@ where
genesis_state.build_epoch_cache(RelativeEpoch::Previous, &spec)?; genesis_state.build_epoch_cache(RelativeEpoch::Previous, &spec)?;
genesis_state.build_epoch_cache(RelativeEpoch::Current, &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 { Ok(Self {
block_store, block_store,
@ -248,19 +246,15 @@ where
/// present and prior epoch is available. /// present and prior epoch is available.
pub fn block_proposer(&self, slot: Slot) -> Result<usize, BeaconStateError> { pub fn block_proposer(&self, slot: Slot) -> Result<usize, BeaconStateError> {
trace!("BeaconChain::block_proposer: slot: {}", slot); trace!("BeaconChain::block_proposer: slot: {}", slot);
let index = self let index = self.state.read().get_beacon_proposer_index(
.state slot,
.read() RelativeEpoch::Current,
.get_beacon_proposer_index(slot, &self.spec)?; &self.spec,
)?;
Ok(index) 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. /// 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 /// 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: {}", "BeaconChain::validator_attestion_slot_and_shard: validator_index: {}",
validator_index validator_index
); );
if let Some((slot, shard, _committee)) = self if let Some(attestation_duty) = self
.state .state
.read() .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 { } else {
Ok(None) Ok(None)
} }
@ -287,37 +281,33 @@ where
/// Produce an `AttestationData` that is valid for the present `slot` and given `shard`. /// Produce an `AttestationData` that is valid for the present `slot` and given `shard`.
pub fn produce_attestation_data(&self, shard: u64) -> Result<AttestationData, Error> { pub fn produce_attestation_data(&self, shard: u64) -> Result<AttestationData, Error> {
trace!("BeaconChain::produce_attestation_data: shard: {}", shard); trace!("BeaconChain::produce_attestation_data: shard: {}", shard);
let justified_epoch = self.justified_epoch(); let source_epoch = self.state.read().current_justified_epoch;
let justified_block_root = *self let source_root = *self.state.read().get_block_root(
.state source_epoch.start_slot(self.spec.slots_per_epoch),
.read()
.get_block_root(
justified_epoch.start_slot(self.spec.slots_per_epoch),
&self.spec, &self.spec,
) )?;
.ok_or_else(|| Error::BadRecentBlockRoots)?;
let epoch_boundary_root = *self let target_root = *self.state.read().get_block_root(
.state self.state
.read() .read()
.get_block_root( .slot
self.state.read().current_epoch_start_slot(&self.spec), .epoch(self.spec.slots_per_epoch)
.start_slot(self.spec.slots_per_epoch),
&self.spec, &self.spec,
) )?;
.ok_or_else(|| Error::BadRecentBlockRoots)?;
Ok(AttestationData { Ok(AttestationData {
slot: self.state.read().slot, slot: self.state.read().slot,
shard, shard,
beacon_block_root: self.head().beacon_block_root, beacon_block_root: self.head().beacon_block_root,
epoch_boundary_root, target_root,
crosslink_data_root: Hash256::zero(), crosslink_data_root: Hash256::zero(),
latest_crosslink: Crosslink { previous_crosslink: Crosslink {
epoch: self.state.read().slot.epoch(self.spec.slots_per_epoch), epoch: self.state.read().slot.epoch(self.spec.slots_per_epoch),
crosslink_data_root: Hash256::zero(), crosslink_data_root: Hash256::zero(),
}, },
justified_epoch, source_epoch,
justified_block_root, source_root,
}) })
} }
@ -581,7 +571,7 @@ where
dump.push(last_slot.clone()); dump.push(last_slot.clone());
loop { 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 { if beacon_block_root == self.spec.zero_hash {
break; // Genesis has been reached. 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. /// Will accept blocks from prior slots, however it will reject any block from a future slot.
pub fn process_block(&self, block: BeaconBlock) -> Result<BlockProcessingOutcome, Error> { pub fn process_block(&self, block: BeaconBlock) -> Result<BlockProcessingOutcome, Error> {
debug!("Processing block with slot {}...", block.slot()); debug!("Processing block with slot {}...", block.slot);
let block_root = block.canonical_root(); 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 // Load the blocks parent block from the database, returning invalid if that block is not
// found. // found.
let parent_block_root = block.parent_root; let parent_block_root = block.previous_block_root;
let parent_block = match self.block_store.get_reader(&parent_block_root)? { let parent_block = match self.block_store.get_deserialized(&parent_block_root)? {
Some(parent_root) => parent_root, Some(previous_block_root) => previous_block_root,
None => { None => {
return Ok(BlockProcessingOutcome::InvalidBlock( return Ok(BlockProcessingOutcome::InvalidBlock(
InvalidBlock::ParentUnknown, InvalidBlock::ParentUnknown,
@ -647,15 +637,11 @@ where
// Load the parent blocks state from the database, returning an error if it is not found. // 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. // 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 let parent_state = self
.state_store .state_store
.get_reader(&parent_state_root)? .get_deserialized(&parent_state_root)?
.ok_or_else(|| Error::DBInconsistent(format!("Missing state {}", 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))
})?;
// TODO: check the block proposer signature BEFORE doing a state transition. This will // TODO: check the block proposer signature BEFORE doing a state transition. This will
// significantly lower exposure surface to DoS attacks. // significantly lower exposure surface to DoS attacks.
@ -739,22 +725,22 @@ where
attestations.len() attestations.len()
); );
let parent_root = *state let previous_block_root = *state
.get_block_root(state.slot.saturating_sub(1_u64), &self.spec) .get_block_root(state.slot.saturating_sub(1_u64), &self.spec)
.ok_or_else(|| BlockProductionError::UnableToGetBlockRootFromState)?; .map_err(|_| BlockProductionError::UnableToGetBlockRootFromState)?;
let mut block = BeaconBlock { let mut block = BeaconBlock {
slot: state.slot, slot: state.slot,
parent_root, previous_block_root,
state_root: Hash256::zero(), // Updated after the state is calculated. state_root: Hash256::zero(), // Updated after the state is calculated.
signature: self.spec.empty_signature.clone(), // To be completed by a validator.
body: BeaconBlockBody {
randao_reveal, randao_reveal,
eth1_data: Eth1Data { eth1_data: Eth1Data {
// TODO: replace with real data // TODO: replace with real data
deposit_root: Hash256::zero(), deposit_root: Hash256::zero(),
block_hash: Hash256::zero(), block_hash: Hash256::zero(),
}, },
signature: self.spec.empty_signature.clone(), // To be completed by a validator.
body: BeaconBlockBody {
proposer_slashings: self.get_proposer_slashings_for_block(), proposer_slashings: self.get_proposer_slashings_for_block(),
attester_slashings: self.get_attester_slashings_for_block(), attester_slashings: self.get_attester_slashings_for_block(),
attestations, attestations,