Tidy BeaconState

This commit is contained in:
Paul Hauner 2019-02-11 17:24:56 +11:00
parent 75a9e0f3de
commit 03e84a63ec
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
3 changed files with 29 additions and 103 deletions

View File

@ -125,26 +125,44 @@ pub struct BeaconState {
} }
impl BeaconState { impl BeaconState {
/// Return the tree hash root for this `BeaconState`.
///
/// Spec v0.2.0
pub fn canonical_root(&self) -> Hash256 { pub fn canonical_root(&self) -> Hash256 {
Hash256::from(&self.hash_tree_root()[..]) Hash256::from(&self.hash_tree_root()[..])
} }
/// The epoch corresponding to `self.slot`.
///
/// Spec v0.2.0
pub fn current_epoch(&self, spec: &ChainSpec) -> Epoch { pub fn current_epoch(&self, spec: &ChainSpec) -> Epoch {
self.slot.epoch(spec.epoch_length) self.slot.epoch(spec.epoch_length)
} }
/// The epoch prior to `self.current_epoch()`.
///
/// Spec v0.2.0
pub fn previous_epoch(&self, spec: &ChainSpec) -> Epoch { pub fn previous_epoch(&self, spec: &ChainSpec) -> Epoch {
self.current_epoch(spec).saturating_sub(1_u64) self.current_epoch(spec).saturating_sub(1_u64)
} }
/// The epoch following `self.current_epoch()`.
///
/// Spec v0.2.0
pub fn next_epoch(&self, spec: &ChainSpec) -> Epoch { pub fn next_epoch(&self, spec: &ChainSpec) -> Epoch {
self.current_epoch(spec).saturating_add(1_u64) self.current_epoch(spec).saturating_add(1_u64)
} }
/// The first slot of the epoch corresponding to `self.slot`.
///
/// Spec v0.2.0
pub fn current_epoch_start_slot(&self, spec: &ChainSpec) -> Slot { pub fn current_epoch_start_slot(&self, spec: &ChainSpec) -> Slot {
self.current_epoch(spec).start_slot(spec.epoch_length) self.current_epoch(spec).start_slot(spec.epoch_length)
} }
/// The first slot of the epoch preceeding the one corresponding to `self.slot`.
///
/// Spec v0.2.0
pub fn previous_epoch_start_slot(&self, spec: &ChainSpec) -> Slot { pub fn previous_epoch_start_slot(&self, spec: &ChainSpec) -> Slot {
self.previous_epoch(spec).start_slot(spec.epoch_length) self.previous_epoch(spec).start_slot(spec.epoch_length)
} }
@ -331,6 +349,10 @@ impl BeaconState {
Ok(crosslinks_at_slot) Ok(crosslinks_at_slot)
} }
/// Returns the `slot`, `shard` and `committee_index` for which a validator must produce an
/// attestation.
///
/// Spec v0.2.0
pub fn attestation_slot_and_shard_for_validator( pub fn attestation_slot_and_shard_for_validator(
&self, &self,
validator_index: usize, validator_index: usize,
@ -764,107 +786,6 @@ impl BeaconState {
} }
Ok(participants) Ok(participants)
} }
pub fn validate_attestation(
&self,
attestation: &Attestation,
spec: &ChainSpec,
) -> Result<(), AttestationValidationError> {
self.validate_attestation_signature_optional(attestation, spec, true)
}
pub fn validate_attestation_without_signature(
&self,
attestation: &Attestation,
spec: &ChainSpec,
) -> Result<(), AttestationValidationError> {
self.validate_attestation_signature_optional(attestation, spec, false)
}
fn validate_attestation_signature_optional(
&self,
attestation: &Attestation,
spec: &ChainSpec,
verify_signature: bool,
) -> Result<(), AttestationValidationError> {
ensure!(
attestation.data.slot + spec.min_attestation_inclusion_delay <= self.slot,
AttestationValidationError::IncludedTooEarly
);
ensure!(
attestation.data.slot + spec.epoch_length >= self.slot,
AttestationValidationError::IncludedTooLate
);
if attestation.data.slot >= self.current_epoch_start_slot(spec) {
ensure!(
attestation.data.justified_epoch == self.justified_epoch,
AttestationValidationError::WrongJustifiedSlot
);
} else {
ensure!(
attestation.data.justified_epoch == self.previous_justified_epoch,
AttestationValidationError::WrongJustifiedSlot
);
}
ensure!(
attestation.data.justified_block_root
== *self
.get_block_root(
attestation
.data
.justified_epoch
.start_slot(spec.epoch_length),
&spec
)
.ok_or(AttestationValidationError::NoBlockRoot)?,
AttestationValidationError::WrongJustifiedRoot
);
ensure!(
(attestation.data.latest_crosslink
== self.latest_crosslinks[attestation.data.shard as usize])
|| (attestation.data.latest_crosslink
== self.latest_crosslinks[attestation.data.shard as usize]),
AttestationValidationError::BadLatestCrosslinkRoot
);
if verify_signature {
let participants = self.get_attestation_participants(
&attestation.data,
&attestation.aggregation_bitfield,
spec,
)?;
let mut group_public_key = AggregatePublicKey::new();
for participant in participants {
group_public_key.add(
self.validator_registry[participant as usize]
.pubkey
.as_raw(),
)
}
ensure!(
bls_verify_aggregate(
&group_public_key,
&attestation.signable_message(PHASE_0_CUSTODY_BIT),
&attestation.aggregate_signature,
get_domain(
&self.fork,
attestation.data.slot.epoch(spec.epoch_length),
DOMAIN_ATTESTATION
)
),
AttestationValidationError::BadSignature
);
}
ensure!(
attestation.data.shard_block_root == spec.zero_hash,
AttestationValidationError::ShardBlockRootNotZero
);
Ok(())
}
}
fn get_domain(_fork: &Fork, _epoch: Epoch, _domain_type: u64) -> u64 {
// TODO: stubbed out.
0
} }
impl From<AttestationParticipantsError> for AttestationValidationError { impl From<AttestationParticipantsError> for AttestationValidationError {

View File

@ -7,6 +7,8 @@ impl ChainSpec {
/// ///
/// Of course, the actual foundation specs are unknown at this point so these are just a rough /// Of course, the actual foundation specs are unknown at this point so these are just a rough
/// estimate. /// estimate.
///
/// Spec v0.2.0
pub fn foundation() -> Self { pub fn foundation() -> Self {
let genesis_slot = Slot::new(2_u64.pow(19)); let genesis_slot = Slot::new(2_u64.pow(19));
let epoch_length = 64; let epoch_length = 64;
@ -57,7 +59,7 @@ impl ChainSpec {
min_attestation_inclusion_delay: Slot::new(4), min_attestation_inclusion_delay: Slot::new(4),
epoch_length, epoch_length,
seed_lookahead: Epoch::new(1), seed_lookahead: Epoch::new(1),
entry_exit_delay: Epoch::new(4), entry_exit_delay: 4,
eth1_data_voting_period: 16, eth1_data_voting_period: 16,
min_validator_withdrawal_epochs: Epoch::new(256), min_validator_withdrawal_epochs: Epoch::new(256),

View File

@ -3,6 +3,9 @@ mod foundation;
use crate::{Address, Epoch, Hash256, Slot}; use crate::{Address, Epoch, Hash256, Slot};
use bls::Signature; use bls::Signature;
/// Holds all the "constants" for a BeaconChain.
///
/// Spec v0.2.0
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub struct ChainSpec { pub struct ChainSpec {
/* /*
@ -49,7 +52,7 @@ pub struct ChainSpec {
pub min_attestation_inclusion_delay: Slot, pub min_attestation_inclusion_delay: Slot,
pub epoch_length: u64, pub epoch_length: u64,
pub seed_lookahead: Epoch, pub seed_lookahead: Epoch,
pub entry_exit_delay: Epoch, pub entry_exit_delay: u64,
pub eth1_data_voting_period: u64, pub eth1_data_voting_period: u64,
pub min_validator_withdrawal_epochs: Epoch, pub min_validator_withdrawal_epochs: Epoch,