Update beacon_chain crate with v0.5.0 updates
This commit is contained in:
parent
d94540c85c
commit
6df5eee7f4
@ -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,34 +85,22 @@ 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)) => {
|
||||||
) {
|
panic!("Attempted to access unbuilt cache {:?}.", e)
|
||||||
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(BeaconStateError::EpochOutOfBounds) => invalid_outcome!(Message::TooOld),
|
Err(e) => return Err(e),
|
||||||
Err(BeaconStateError::ShardOutOfBounds) => invalid_outcome!(Message::BadShard),
|
Ok(None) => invalid_outcome!(Message::BadValidatorIndex),
|
||||||
Err(e) => return Err(e),
|
Ok(Some(attestation_duties)) => attestation_duties,
|
||||||
Ok(None) => invalid_outcome!(Message::BadValidatorIndex),
|
};
|
||||||
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,9 +164,13 @@ 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
|
||||||
known_attestation_data.insert(attestation.data.clone());
|
.previous_epoch_attestations
|
||||||
});
|
.iter()
|
||||||
|
.chain(state.current_epoch_attestations.iter())
|
||||||
|
.for_each(|attestation| {
|
||||||
|
known_attestation_data.insert(attestation.data.clone());
|
||||||
|
});
|
||||||
|
|
||||||
self.store
|
self.store
|
||||||
.values()
|
.values()
|
||||||
|
@ -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()
|
&self.spec,
|
||||||
.get_block_root(
|
)?;
|
||||||
justified_epoch.start_slot(self.spec.slots_per_epoch),
|
|
||||||
&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)
|
||||||
&self.spec,
|
.start_slot(self.spec.slots_per_epoch),
|
||||||
)
|
&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.
|
||||||
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.
|
signature: self.spec.empty_signature.clone(), // To be completed by a validator.
|
||||||
body: BeaconBlockBody {
|
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(),
|
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user