2020-05-06 11:42:56 +00:00
|
|
|
//! Provides verification for the following attestations:
|
|
|
|
//!
|
|
|
|
//! - "Unaggregated" `Attestation` received from either gossip or the HTTP API.
|
|
|
|
//! - "Aggregated" `SignedAggregateAndProof` received from gossip or the HTTP API.
|
|
|
|
//!
|
|
|
|
//! For clarity, we define:
|
|
|
|
//!
|
|
|
|
//! - Unaggregated: an `Attestation` object that has exactly one aggregation bit set.
|
|
|
|
//! - Aggregated: a `SignedAggregateAndProof` which has zero or more signatures.
|
|
|
|
//! - Note: "zero or more" may soon change to "one or more".
|
|
|
|
//!
|
|
|
|
//! Similar to the `crate::block_verification` module, we try to avoid doing duplicate verification
|
|
|
|
//! work as an attestation passes through different stages of verification. We represent these
|
|
|
|
//! different stages of verification with wrapper types. These wrapper-types flow in a particular
|
|
|
|
//! pattern:
|
|
|
|
//!
|
|
|
|
//! ```ignore
|
|
|
|
//! types::Attestation types::SignedAggregateAndProof
|
|
|
|
//! | |
|
|
|
|
//! ▼ ▼
|
|
|
|
//! VerifiedUnaggregatedAttestation VerifiedAggregatedAttestation
|
|
|
|
//! | |
|
|
|
|
//! -------------------------------------
|
|
|
|
//! |
|
|
|
|
//! ▼
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
//! impl SignatureVerifiedAttestation
|
2020-05-06 11:42:56 +00:00
|
|
|
//! ```
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
beacon_chain::{
|
|
|
|
ATTESTATION_CACHE_LOCK_TIMEOUT, HEAD_LOCK_TIMEOUT, MAXIMUM_GOSSIP_CLOCK_DISPARITY,
|
|
|
|
VALIDATOR_PUBKEY_CACHE_LOCK_TIMEOUT,
|
|
|
|
},
|
|
|
|
metrics,
|
|
|
|
observed_attestations::ObserveOutcome,
|
|
|
|
observed_attesters::Error as ObservedAttestersError,
|
|
|
|
BeaconChain, BeaconChainError, BeaconChainTypes,
|
|
|
|
};
|
|
|
|
use bls::verify_signature_sets;
|
2020-09-27 20:59:40 +00:00
|
|
|
use proto_array::Block as ProtoBlock;
|
2020-05-06 11:42:56 +00:00
|
|
|
use slog::debug;
|
|
|
|
use slot_clock::SlotClock;
|
|
|
|
use state_processing::{
|
|
|
|
common::get_indexed_attestation,
|
|
|
|
per_block_processing::errors::AttestationValidationError,
|
|
|
|
per_slot_processing,
|
|
|
|
signature_sets::{
|
|
|
|
indexed_attestation_signature_set_from_pubkeys,
|
|
|
|
signed_aggregate_selection_proof_signature_set, signed_aggregate_signature_set,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
use std::borrow::Cow;
|
|
|
|
use tree_hash::TreeHash;
|
|
|
|
use types::{
|
|
|
|
Attestation, BeaconCommittee, CommitteeIndex, Epoch, EthSpec, Hash256, IndexedAttestation,
|
2020-06-18 09:11:03 +00:00
|
|
|
RelativeEpoch, SelectionProof, SignedAggregateAndProof, Slot, SubnetId,
|
2020-05-06 11:42:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Returned when an attestation was not successfully verified. It might not have been verified for
|
|
|
|
/// two reasons:
|
|
|
|
///
|
|
|
|
/// - The attestation is malformed or inappropriate for the context (indicated by all variants
|
|
|
|
/// other than `BeaconChainError`).
|
|
|
|
/// - The application encountered an internal error whilst attempting to determine validity
|
|
|
|
/// (the `BeaconChainError` variant)
|
2020-05-21 00:21:44 +00:00
|
|
|
#[derive(Debug)]
|
2020-05-06 11:42:56 +00:00
|
|
|
pub enum Error {
|
|
|
|
/// The attestation is from a slot that is later than the current slot (with respect to the
|
|
|
|
/// gossip clock disparity).
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// Assuming the local clock is correct, the peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
FutureSlot {
|
|
|
|
attestation_slot: Slot,
|
|
|
|
latest_permissible_slot: Slot,
|
|
|
|
},
|
|
|
|
/// The attestation is from a slot that is prior to the earliest permissible slot (with
|
|
|
|
/// respect to the gossip clock disparity).
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// Assuming the local clock is correct, the peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
PastSlot {
|
|
|
|
attestation_slot: Slot,
|
|
|
|
earliest_permissible_slot: Slot,
|
|
|
|
},
|
|
|
|
/// The attestations aggregation bits were empty when they shouldn't be.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
EmptyAggregationBitfield,
|
|
|
|
/// The `selection_proof` on the aggregate attestation does not elect it as an aggregator.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
InvalidSelectionProof { aggregator_index: u64 },
|
|
|
|
/// The `selection_proof` on the aggregate attestation selects it as a validator, however the
|
|
|
|
/// aggregator index is not in the committee for that attestation.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
AggregatorNotInCommittee { aggregator_index: u64 },
|
|
|
|
/// The aggregator index refers to a validator index that we have not seen.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
AggregatorPubkeyUnknown(u64),
|
|
|
|
/// The attestation has been seen before; either in a block, on the gossip network or from a
|
|
|
|
/// local validator.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// It's unclear if this attestation is valid, however we have already observed it and do not
|
|
|
|
/// need to observe it again.
|
2020-05-06 11:42:56 +00:00
|
|
|
AttestationAlreadyKnown(Hash256),
|
|
|
|
/// There has already been an aggregation observed for this validator, we refuse to process a
|
|
|
|
/// second.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// It's unclear if this attestation is valid, however we have already observed an aggregate
|
|
|
|
/// attestation from this validator for this epoch and should not observe another.
|
2020-05-06 11:42:56 +00:00
|
|
|
AggregatorAlreadyKnown(u64),
|
|
|
|
/// The aggregator index is higher than the maximum possible validator count.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
ValidatorIndexTooHigh(usize),
|
|
|
|
/// The `attestation.data.beacon_block_root` block is unknown.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The attestation points to a block we have not yet imported. It's unclear if the attestation
|
|
|
|
/// is valid or not.
|
2020-05-06 11:42:56 +00:00
|
|
|
UnknownHeadBlock { beacon_block_root: Hash256 },
|
2020-07-26 03:16:49 +00:00
|
|
|
/// The `attestation.data.slot` is not from the same epoch as `data.target.epoch`.
|
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
BadTargetEpoch,
|
|
|
|
/// The target root of the attestation points to a block that we have not verified.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// This is invalid behaviour whilst we first check for `UnknownHeadBlock`.
|
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
UnknownTargetRoot(Hash256),
|
|
|
|
/// A signature on the attestation is invalid.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
InvalidSignature,
|
|
|
|
/// There is no committee for the slot and committee index of this attestation and the
|
|
|
|
/// attestation should not have been produced.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
NoCommitteeForSlotAndIndex { slot: Slot, index: CommitteeIndex },
|
|
|
|
/// The unaggregated attestation doesn't have only one aggregation bit set.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
NotExactlyOneAggregationBitSet(usize),
|
|
|
|
/// We have already observed an attestation for the `validator_index` and refuse to process
|
|
|
|
/// another.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// It's unclear if this attestation is valid, however we have already observed a
|
|
|
|
/// single-participant attestation from this validator for this epoch and should not observe
|
|
|
|
/// another.
|
2020-05-06 11:42:56 +00:00
|
|
|
PriorAttestationKnown { validator_index: u64, epoch: Epoch },
|
|
|
|
/// The attestation is for an epoch in the future (with respect to the gossip clock disparity).
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// Assuming the local clock is correct, the peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
FutureEpoch {
|
|
|
|
attestation_epoch: Epoch,
|
|
|
|
current_epoch: Epoch,
|
|
|
|
},
|
|
|
|
/// The attestation is for an epoch in the past (with respect to the gossip clock disparity).
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// Assuming the local clock is correct, the peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
PastEpoch {
|
|
|
|
attestation_epoch: Epoch,
|
|
|
|
current_epoch: Epoch,
|
|
|
|
},
|
|
|
|
/// The attestation is attesting to a state that is later than itself. (Viz., attesting to the
|
|
|
|
/// future).
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
AttestsToFutureBlock { block: Slot, attestation: Slot },
|
2020-06-18 09:11:03 +00:00
|
|
|
/// The attestation was received on an invalid attestation subnet.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-06-18 09:11:03 +00:00
|
|
|
InvalidSubnetId {
|
|
|
|
received: SubnetId,
|
|
|
|
expected: SubnetId,
|
|
|
|
},
|
2020-05-06 11:42:56 +00:00
|
|
|
/// The attestation failed the `state_processing` verification stage.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
2020-05-06 11:42:56 +00:00
|
|
|
Invalid(AttestationValidationError),
|
2020-08-17 10:54:58 +00:00
|
|
|
/// The attestation head block is too far behind the attestation slot, causing many skip slots.
|
|
|
|
/// This is deemed a DoS risk.
|
|
|
|
TooManySkippedSlots {
|
|
|
|
head_block_slot: Slot,
|
|
|
|
attestation_slot: Slot,
|
|
|
|
},
|
2020-09-27 20:59:40 +00:00
|
|
|
/// The attestation has an invalid target epoch.
|
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
|
|
|
InvalidTargetEpoch { slot: Slot, epoch: Epoch },
|
|
|
|
/// The attestation references an invalid target block.
|
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// The peer has sent an invalid message.
|
|
|
|
InvalidTargetRoot {
|
|
|
|
attestation: Hash256,
|
|
|
|
expected: Hash256,
|
|
|
|
},
|
2020-05-06 11:42:56 +00:00
|
|
|
/// There was an error whilst processing the attestation. It is not known if it is valid or invalid.
|
2020-07-26 03:16:49 +00:00
|
|
|
///
|
|
|
|
/// ## Peer scoring
|
|
|
|
///
|
|
|
|
/// We were unable to process this attestation due to an internal error. It's unclear if the
|
|
|
|
/// attestation is valid.
|
2020-05-06 11:42:56 +00:00
|
|
|
BeaconChainError(BeaconChainError),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<BeaconChainError> for Error {
|
|
|
|
fn from(e: BeaconChainError) -> Self {
|
|
|
|
Error::BeaconChainError(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Wraps a `SignedAggregateAndProof` that has been verified for propagation on the gossip network.
|
|
|
|
pub struct VerifiedAggregatedAttestation<T: BeaconChainTypes> {
|
|
|
|
signed_aggregate: SignedAggregateAndProof<T::EthSpec>,
|
|
|
|
indexed_attestation: IndexedAttestation<T::EthSpec>,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Wraps an `Attestation` that has been verified for propagation on the gossip network.
|
|
|
|
pub struct VerifiedUnaggregatedAttestation<T: BeaconChainTypes> {
|
|
|
|
attestation: Attestation<T::EthSpec>,
|
|
|
|
indexed_attestation: IndexedAttestation<T::EthSpec>,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Custom `Clone` implementation is to avoid the restrictive trait bounds applied by the usual derive
|
|
|
|
/// macro.
|
|
|
|
impl<T: BeaconChainTypes> Clone for VerifiedUnaggregatedAttestation<T> {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
Self {
|
|
|
|
attestation: self.attestation.clone(),
|
|
|
|
indexed_attestation: self.indexed_attestation.clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A helper trait implemented on wrapper types that can be progressed to a state where they can be
|
|
|
|
/// verified for application to fork choice.
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
pub trait SignatureVerifiedAttestation<T: BeaconChainTypes> {
|
|
|
|
fn indexed_attestation(&self) -> &IndexedAttestation<T::EthSpec>;
|
2020-05-06 11:42:56 +00:00
|
|
|
}
|
|
|
|
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
impl<'a, T: BeaconChainTypes> SignatureVerifiedAttestation<T> for VerifiedAggregatedAttestation<T> {
|
|
|
|
fn indexed_attestation(&self) -> &IndexedAttestation<T::EthSpec> {
|
|
|
|
&self.indexed_attestation
|
2020-05-06 11:42:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
impl<T: BeaconChainTypes> SignatureVerifiedAttestation<T> for VerifiedUnaggregatedAttestation<T> {
|
|
|
|
fn indexed_attestation(&self) -> &IndexedAttestation<T::EthSpec> {
|
|
|
|
&self.indexed_attestation
|
2020-05-06 11:42:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: BeaconChainTypes> VerifiedAggregatedAttestation<T> {
|
|
|
|
/// Returns `Ok(Self)` if the `signed_aggregate` is valid to be (re)published on the gossip
|
|
|
|
/// network.
|
|
|
|
pub fn verify(
|
|
|
|
signed_aggregate: SignedAggregateAndProof<T::EthSpec>,
|
|
|
|
chain: &BeaconChain<T>,
|
|
|
|
) -> Result<Self, Error> {
|
|
|
|
let attestation = &signed_aggregate.message.aggregate;
|
|
|
|
|
|
|
|
// Ensure attestation is within the last ATTESTATION_PROPAGATION_SLOT_RANGE slots (within a
|
|
|
|
// MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance).
|
|
|
|
//
|
|
|
|
// We do not queue future attestations for later processing.
|
|
|
|
verify_propagation_slot_range(chain, attestation)?;
|
|
|
|
|
2020-06-05 01:32:46 +00:00
|
|
|
// Ensure the valid aggregated attestation has not already been seen locally.
|
2020-05-06 11:42:56 +00:00
|
|
|
let attestation_root = attestation.tree_hash_root();
|
|
|
|
if chain
|
|
|
|
.observed_attestations
|
|
|
|
.is_known(attestation, attestation_root)
|
|
|
|
.map_err(|e| Error::BeaconChainError(e.into()))?
|
|
|
|
{
|
|
|
|
return Err(Error::AttestationAlreadyKnown(attestation_root));
|
|
|
|
}
|
|
|
|
|
|
|
|
let aggregator_index = signed_aggregate.message.aggregator_index;
|
|
|
|
|
|
|
|
// Ensure there has been no other observed aggregate for the given `aggregator_index`.
|
|
|
|
//
|
|
|
|
// Note: do not observe yet, only observe once the attestation has been verfied.
|
|
|
|
match chain
|
|
|
|
.observed_aggregators
|
|
|
|
.validator_has_been_observed(attestation, aggregator_index as usize)
|
|
|
|
{
|
|
|
|
Ok(true) => Err(Error::AggregatorAlreadyKnown(aggregator_index)),
|
|
|
|
Ok(false) => Ok(()),
|
|
|
|
Err(ObservedAttestersError::ValidatorIndexTooHigh(i)) => {
|
|
|
|
Err(Error::ValidatorIndexTooHigh(i))
|
|
|
|
}
|
|
|
|
Err(e) => Err(BeaconChainError::from(e).into()),
|
|
|
|
}?;
|
|
|
|
|
|
|
|
// Ensure the block being voted for (attestation.data.beacon_block_root) passes validation.
|
2020-08-17 10:54:58 +00:00
|
|
|
// Don't enforce the skip slot restriction for aggregates.
|
2020-05-06 11:42:56 +00:00
|
|
|
//
|
|
|
|
// This indirectly checks to see if the `attestation.data.beacon_block_root` is in our fork
|
|
|
|
// choice. Any known, non-finalized, processed block should be in fork choice, so this
|
|
|
|
// check immediately filters out attestations that attest to a block that has not been
|
|
|
|
// processed.
|
|
|
|
//
|
|
|
|
// Attestations must be for a known block. If the block is unknown, we simply drop the
|
|
|
|
// attestation and do not delay consideration for later.
|
2020-08-17 10:54:58 +00:00
|
|
|
verify_head_block_is_known(chain, &attestation, None)?;
|
2020-05-06 11:42:56 +00:00
|
|
|
|
2020-06-05 01:32:46 +00:00
|
|
|
// Ensure that the attestation has participants.
|
|
|
|
if attestation.aggregation_bits.is_zero() {
|
|
|
|
return Err(Error::EmptyAggregationBitfield);
|
|
|
|
}
|
|
|
|
|
2020-06-18 09:11:03 +00:00
|
|
|
let indexed_attestation =
|
|
|
|
map_attestation_committee(chain, attestation, |(committee, _)| {
|
|
|
|
// Note: this clones the signature which is known to be a relatively slow operation.
|
|
|
|
//
|
|
|
|
// Future optimizations should remove this clone.
|
|
|
|
let selection_proof =
|
|
|
|
SelectionProof::from(signed_aggregate.message.selection_proof.clone());
|
|
|
|
|
|
|
|
if !selection_proof
|
|
|
|
.is_aggregator(committee.committee.len(), &chain.spec)
|
|
|
|
.map_err(|e| Error::BeaconChainError(e.into()))?
|
|
|
|
{
|
|
|
|
return Err(Error::InvalidSelectionProof { aggregator_index });
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the aggregator is a member of the committee for which it is aggregating.
|
|
|
|
if !committee.committee.contains(&(aggregator_index as usize)) {
|
|
|
|
return Err(Error::AggregatorNotInCommittee { aggregator_index });
|
|
|
|
}
|
|
|
|
|
|
|
|
get_indexed_attestation(committee.committee, &attestation)
|
|
|
|
.map_err(|e| BeaconChainError::from(e).into())
|
|
|
|
})?;
|
2020-05-06 11:42:56 +00:00
|
|
|
|
2020-06-05 01:32:46 +00:00
|
|
|
// Ensure that all signatures are valid.
|
2020-05-06 11:42:56 +00:00
|
|
|
if !verify_signed_aggregate_signatures(chain, &signed_aggregate, &indexed_attestation)? {
|
|
|
|
return Err(Error::InvalidSignature);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Observe the valid attestation so we do not re-process it.
|
|
|
|
//
|
|
|
|
// It's important to double check that the attestation is not already known, otherwise two
|
|
|
|
// attestations processed at the same time could be published.
|
|
|
|
if let ObserveOutcome::AlreadyKnown = chain
|
|
|
|
.observed_attestations
|
|
|
|
.observe_attestation(attestation, Some(attestation_root))
|
|
|
|
.map_err(|e| Error::BeaconChainError(e.into()))?
|
|
|
|
{
|
|
|
|
return Err(Error::AttestationAlreadyKnown(attestation_root));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Observe the aggregator so we don't process another aggregate from them.
|
|
|
|
//
|
|
|
|
// It's important to double check that the attestation is not already known, otherwise two
|
|
|
|
// attestations processed at the same time could be published.
|
|
|
|
if chain
|
|
|
|
.observed_aggregators
|
|
|
|
.observe_validator(&attestation, aggregator_index as usize)
|
2020-07-23 14:18:00 +00:00
|
|
|
.map_err(BeaconChainError::from)?
|
2020-05-06 11:42:56 +00:00
|
|
|
{
|
|
|
|
return Err(Error::PriorAttestationKnown {
|
|
|
|
validator_index: aggregator_index,
|
|
|
|
epoch: attestation.data.target.epoch,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(VerifiedAggregatedAttestation {
|
|
|
|
signed_aggregate,
|
|
|
|
indexed_attestation,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A helper function to add this aggregate to `beacon_chain.op_pool`.
|
|
|
|
pub fn add_to_pool(self, chain: &BeaconChain<T>) -> Result<Self, Error> {
|
|
|
|
chain.add_to_block_inclusion_pool(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the underlying `attestation` for the `signed_aggregate`.
|
|
|
|
pub fn attestation(&self) -> &Attestation<T::EthSpec> {
|
|
|
|
&self.signed_aggregate.message.aggregate
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: BeaconChainTypes> VerifiedUnaggregatedAttestation<T> {
|
|
|
|
/// Returns `Ok(Self)` if the `attestation` is valid to be (re)published on the gossip
|
|
|
|
/// network.
|
2020-06-18 09:11:03 +00:00
|
|
|
///
|
|
|
|
/// `subnet_id` is the subnet from which we received this attestation. This function will
|
|
|
|
/// verify that it was received on the correct subnet.
|
2020-05-06 11:42:56 +00:00
|
|
|
pub fn verify(
|
|
|
|
attestation: Attestation<T::EthSpec>,
|
2020-06-18 09:11:03 +00:00
|
|
|
subnet_id: SubnetId,
|
2020-05-06 11:42:56 +00:00
|
|
|
chain: &BeaconChain<T>,
|
|
|
|
) -> Result<Self, Error> {
|
2020-09-27 20:59:40 +00:00
|
|
|
let attestation_epoch = attestation.data.slot.epoch(T::EthSpec::slots_per_epoch());
|
|
|
|
|
|
|
|
// Check the attestation's epoch matches its target.
|
|
|
|
if attestation_epoch != attestation.data.target.epoch {
|
|
|
|
return Err(Error::InvalidTargetEpoch {
|
|
|
|
slot: attestation.data.slot,
|
|
|
|
epoch: attestation.data.target.epoch,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-05-06 11:42:56 +00:00
|
|
|
// Ensure attestation is within the last ATTESTATION_PROPAGATION_SLOT_RANGE slots (within a
|
|
|
|
// MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance).
|
|
|
|
//
|
|
|
|
// We do not queue future attestations for later processing.
|
|
|
|
verify_propagation_slot_range(chain, &attestation)?;
|
|
|
|
|
|
|
|
// Check to ensure that the attestation is "unaggregated". I.e., it has exactly one
|
|
|
|
// aggregation bit set.
|
2020-09-27 20:59:40 +00:00
|
|
|
let num_aggregation_bits = attestation.aggregation_bits.num_set_bits();
|
|
|
|
if num_aggregation_bits != 1 {
|
|
|
|
return Err(Error::NotExactlyOneAggregationBitSet(num_aggregation_bits));
|
2020-05-06 11:42:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Attestations must be for a known block. If the block is unknown, we simply drop the
|
|
|
|
// attestation and do not delay consideration for later.
|
2020-08-17 10:54:58 +00:00
|
|
|
//
|
|
|
|
// Enforce a maximum skip distance for unaggregated attestations.
|
2020-09-27 20:59:40 +00:00
|
|
|
let head_block =
|
|
|
|
verify_head_block_is_known(chain, &attestation, chain.config.import_max_skip_slots)?;
|
|
|
|
|
|
|
|
// Check the attestation target root.
|
|
|
|
let head_block_epoch = head_block.slot.epoch(T::EthSpec::slots_per_epoch());
|
|
|
|
if head_block_epoch > attestation_epoch {
|
|
|
|
// The attestation points to a head block from an epoch later than the attestation.
|
|
|
|
//
|
|
|
|
// Whilst this seems clearly invalid in the "spirit of the protocol", there is nothing
|
|
|
|
// in the specification to prevent these messages from propagating.
|
|
|
|
//
|
|
|
|
// Reference:
|
|
|
|
// https://github.com/ethereum/eth2.0-specs/pull/2001#issuecomment-699246659
|
|
|
|
} else {
|
|
|
|
let target_root = if head_block_epoch == attestation_epoch {
|
|
|
|
// If the block is in the same epoch as the attestation, then use the target root
|
|
|
|
// from the block.
|
|
|
|
head_block.target_root
|
|
|
|
} else {
|
|
|
|
// If the head block is from a previous epoch then skip slots will cause the head block
|
|
|
|
// root to become the target block root.
|
|
|
|
//
|
|
|
|
// We know the head block is from a previous epoch due to a previous check.
|
|
|
|
head_block.root
|
|
|
|
};
|
|
|
|
|
|
|
|
// Reject any attestation with an invalid target root.
|
|
|
|
if target_root != attestation.data.target.root {
|
|
|
|
return Err(Error::InvalidTargetRoot {
|
|
|
|
attestation: attestation.data.target.root,
|
|
|
|
expected: target_root,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2020-05-06 11:42:56 +00:00
|
|
|
|
2020-06-18 09:11:03 +00:00
|
|
|
let (indexed_attestation, committees_per_slot) =
|
|
|
|
obtain_indexed_attestation_and_committees_per_slot(chain, &attestation)?;
|
|
|
|
|
|
|
|
let expected_subnet_id = SubnetId::compute_subnet_for_attestation_data::<T::EthSpec>(
|
|
|
|
&indexed_attestation.data,
|
|
|
|
committees_per_slot,
|
|
|
|
&chain.spec,
|
|
|
|
)
|
|
|
|
.map_err(BeaconChainError::from)?;
|
|
|
|
|
|
|
|
// Ensure the attestation is from the correct subnet.
|
|
|
|
if subnet_id != expected_subnet_id {
|
|
|
|
return Err(Error::InvalidSubnetId {
|
|
|
|
received: subnet_id,
|
|
|
|
expected: expected_subnet_id,
|
|
|
|
});
|
|
|
|
}
|
2020-05-06 11:42:56 +00:00
|
|
|
|
|
|
|
let validator_index = *indexed_attestation
|
|
|
|
.attesting_indices
|
|
|
|
.first()
|
|
|
|
.ok_or_else(|| Error::NotExactlyOneAggregationBitSet(0))?;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The attestation is the first valid attestation received for the participating validator
|
|
|
|
* for the slot, attestation.data.slot.
|
|
|
|
*/
|
|
|
|
if chain
|
|
|
|
.observed_attesters
|
|
|
|
.validator_has_been_observed(&attestation, validator_index as usize)
|
2020-07-23 14:18:00 +00:00
|
|
|
.map_err(BeaconChainError::from)?
|
2020-05-06 11:42:56 +00:00
|
|
|
{
|
|
|
|
return Err(Error::PriorAttestationKnown {
|
|
|
|
validator_index,
|
|
|
|
epoch: attestation.data.target.epoch,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// The aggregate signature of the attestation is valid.
|
|
|
|
verify_attestation_signature(chain, &indexed_attestation)?;
|
|
|
|
|
|
|
|
// Now that the attestation has been fully verified, store that we have received a valid
|
|
|
|
// attestation from this validator.
|
|
|
|
//
|
|
|
|
// It's important to double check that the attestation still hasn't been observed, since
|
|
|
|
// there can be a race-condition if we receive two attestations at the same time and
|
|
|
|
// process them in different threads.
|
|
|
|
if chain
|
|
|
|
.observed_attesters
|
|
|
|
.observe_validator(&attestation, validator_index as usize)
|
2020-07-23 14:18:00 +00:00
|
|
|
.map_err(BeaconChainError::from)?
|
2020-05-06 11:42:56 +00:00
|
|
|
{
|
|
|
|
return Err(Error::PriorAttestationKnown {
|
|
|
|
validator_index,
|
|
|
|
epoch: attestation.data.target.epoch,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Self {
|
|
|
|
attestation,
|
|
|
|
indexed_attestation,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A helper function to add this attestation to `beacon_chain.naive_aggregation_pool`.
|
|
|
|
pub fn add_to_pool(self, chain: &BeaconChain<T>) -> Result<Self, Error> {
|
|
|
|
chain.add_to_naive_aggregation_pool(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the wrapped `attestation`.
|
|
|
|
pub fn attestation(&self) -> &Attestation<T::EthSpec> {
|
|
|
|
&self.attestation
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns a mutable reference to the underlying attestation.
|
|
|
|
///
|
|
|
|
/// Only use during testing since modifying the `IndexedAttestation` can cause the attestation
|
|
|
|
/// to no-longer be valid.
|
|
|
|
pub fn __indexed_attestation_mut(&mut self) -> &mut IndexedAttestation<T::EthSpec> {
|
|
|
|
&mut self.indexed_attestation
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `Ok(())` if the `attestation.data.beacon_block_root` is known to this chain.
|
|
|
|
///
|
|
|
|
/// The block root may not be known for two reasons:
|
|
|
|
///
|
|
|
|
/// 1. The block has never been verified by our application.
|
|
|
|
/// 2. The block is prior to the latest finalized block.
|
|
|
|
///
|
|
|
|
/// Case (1) is the exact thing we're trying to detect. However case (2) is a little different, but
|
|
|
|
/// it's still fine to reject here because there's no need for us to handle attestations that are
|
|
|
|
/// already finalized.
|
|
|
|
fn verify_head_block_is_known<T: BeaconChainTypes>(
|
|
|
|
chain: &BeaconChain<T>,
|
|
|
|
attestation: &Attestation<T::EthSpec>,
|
2020-08-17 10:54:58 +00:00
|
|
|
max_skip_slots: Option<u64>,
|
2020-09-27 20:59:40 +00:00
|
|
|
) -> Result<ProtoBlock, Error> {
|
2020-08-17 10:54:58 +00:00
|
|
|
if let Some(block) = chain
|
2020-05-06 11:42:56 +00:00
|
|
|
.fork_choice
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
.read()
|
2020-08-17 10:54:58 +00:00
|
|
|
.get_block(&attestation.data.beacon_block_root)
|
2020-05-06 11:42:56 +00:00
|
|
|
{
|
2020-08-17 10:54:58 +00:00
|
|
|
// Reject any block that exceeds our limit on skipped slots.
|
|
|
|
if let Some(max_skip_slots) = max_skip_slots {
|
2020-08-18 06:28:26 +00:00
|
|
|
if attestation.data.slot > block.slot + max_skip_slots {
|
2020-08-17 10:54:58 +00:00
|
|
|
return Err(Error::TooManySkippedSlots {
|
|
|
|
head_block_slot: block.slot,
|
|
|
|
attestation_slot: attestation.data.slot,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2020-09-27 20:59:40 +00:00
|
|
|
Ok(block)
|
2020-05-06 11:42:56 +00:00
|
|
|
} else {
|
|
|
|
Err(Error::UnknownHeadBlock {
|
|
|
|
beacon_block_root: attestation.data.beacon_block_root,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Verify that the `attestation` is within the acceptable gossip propagation range, with reference
|
|
|
|
/// to the current slot of the `chain`.
|
|
|
|
///
|
|
|
|
/// Accounts for `MAXIMUM_GOSSIP_CLOCK_DISPARITY`.
|
|
|
|
pub fn verify_propagation_slot_range<T: BeaconChainTypes>(
|
|
|
|
chain: &BeaconChain<T>,
|
|
|
|
attestation: &Attestation<T::EthSpec>,
|
|
|
|
) -> Result<(), Error> {
|
|
|
|
let attestation_slot = attestation.data.slot;
|
|
|
|
|
|
|
|
let latest_permissible_slot = chain
|
|
|
|
.slot_clock
|
|
|
|
.now_with_future_tolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY)
|
|
|
|
.ok_or_else(|| BeaconChainError::UnableToReadSlot)?;
|
|
|
|
if attestation_slot > latest_permissible_slot {
|
|
|
|
return Err(Error::FutureSlot {
|
|
|
|
attestation_slot,
|
|
|
|
latest_permissible_slot,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Taking advantage of saturating subtraction on `Slot`.
|
|
|
|
let earliest_permissible_slot = chain
|
|
|
|
.slot_clock
|
|
|
|
.now_with_past_tolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY)
|
|
|
|
.ok_or_else(|| BeaconChainError::UnableToReadSlot)?
|
|
|
|
- T::EthSpec::slots_per_epoch();
|
|
|
|
if attestation_slot < earliest_permissible_slot {
|
|
|
|
return Err(Error::PastSlot {
|
|
|
|
attestation_slot,
|
|
|
|
earliest_permissible_slot,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Verifies that the signature of the `indexed_attestation` is valid.
|
|
|
|
pub fn verify_attestation_signature<T: BeaconChainTypes>(
|
|
|
|
chain: &BeaconChain<T>,
|
|
|
|
indexed_attestation: &IndexedAttestation<T::EthSpec>,
|
|
|
|
) -> Result<(), Error> {
|
|
|
|
let signature_setup_timer =
|
|
|
|
metrics::start_timer(&metrics::ATTESTATION_PROCESSING_SIGNATURE_SETUP_TIMES);
|
|
|
|
|
|
|
|
let pubkey_cache = chain
|
|
|
|
.validator_pubkey_cache
|
|
|
|
.try_read_for(VALIDATOR_PUBKEY_CACHE_LOCK_TIMEOUT)
|
|
|
|
.ok_or_else(|| BeaconChainError::ValidatorPubkeyCacheLockTimeout)?;
|
|
|
|
|
|
|
|
let fork = chain
|
|
|
|
.canonical_head
|
|
|
|
.try_read_for(HEAD_LOCK_TIMEOUT)
|
|
|
|
.ok_or_else(|| BeaconChainError::CanonicalHeadLockTimeout)
|
2020-07-23 14:18:00 +00:00
|
|
|
.map(|head| head.beacon_state.fork)?;
|
2020-05-06 11:42:56 +00:00
|
|
|
|
|
|
|
let signature_set = indexed_attestation_signature_set_from_pubkeys(
|
|
|
|
|validator_index| pubkey_cache.get(validator_index).map(Cow::Borrowed),
|
|
|
|
&indexed_attestation.signature,
|
|
|
|
&indexed_attestation,
|
|
|
|
&fork,
|
|
|
|
chain.genesis_validators_root,
|
|
|
|
&chain.spec,
|
|
|
|
)
|
|
|
|
.map_err(BeaconChainError::SignatureSetError)?;
|
|
|
|
|
|
|
|
metrics::stop_timer(signature_setup_timer);
|
|
|
|
|
|
|
|
let _signature_verification_timer =
|
|
|
|
metrics::start_timer(&metrics::ATTESTATION_PROCESSING_SIGNATURE_TIMES);
|
|
|
|
|
2020-07-25 02:03:18 +00:00
|
|
|
if signature_set.verify() {
|
2020-05-06 11:42:56 +00:00
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(Error::InvalidSignature)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Verifies all the signatures in a `SignedAggregateAndProof` using BLS batch verification. This
|
|
|
|
/// includes three signatures:
|
|
|
|
///
|
|
|
|
/// - `signed_aggregate.signature`
|
2020-06-05 01:32:46 +00:00
|
|
|
/// - `signed_aggregate.message.selection_proof`
|
|
|
|
/// - `signed_aggregate.message.aggregate.signature`
|
2020-05-06 11:42:56 +00:00
|
|
|
///
|
|
|
|
/// # Returns
|
|
|
|
///
|
|
|
|
/// - `Ok(true)`: if all signatures are valid.
|
|
|
|
/// - `Ok(false)`: if one or more signatures are invalid.
|
|
|
|
/// - `Err(e)`: if there was an error preventing signature verification.
|
|
|
|
pub fn verify_signed_aggregate_signatures<T: BeaconChainTypes>(
|
|
|
|
chain: &BeaconChain<T>,
|
|
|
|
signed_aggregate: &SignedAggregateAndProof<T::EthSpec>,
|
|
|
|
indexed_attestation: &IndexedAttestation<T::EthSpec>,
|
|
|
|
) -> Result<bool, Error> {
|
|
|
|
let pubkey_cache = chain
|
|
|
|
.validator_pubkey_cache
|
|
|
|
.try_read_for(VALIDATOR_PUBKEY_CACHE_LOCK_TIMEOUT)
|
|
|
|
.ok_or_else(|| BeaconChainError::ValidatorPubkeyCacheLockTimeout)?;
|
|
|
|
|
|
|
|
let aggregator_index = signed_aggregate.message.aggregator_index;
|
|
|
|
if aggregator_index >= pubkey_cache.len() as u64 {
|
|
|
|
return Err(Error::AggregatorPubkeyUnknown(aggregator_index));
|
|
|
|
}
|
|
|
|
|
|
|
|
let fork = chain
|
|
|
|
.canonical_head
|
|
|
|
.try_read_for(HEAD_LOCK_TIMEOUT)
|
|
|
|
.ok_or_else(|| BeaconChainError::CanonicalHeadLockTimeout)
|
2020-07-23 14:18:00 +00:00
|
|
|
.map(|head| head.beacon_state.fork)?;
|
2020-05-06 11:42:56 +00:00
|
|
|
|
|
|
|
let signature_sets = vec![
|
|
|
|
signed_aggregate_selection_proof_signature_set(
|
|
|
|
|validator_index| pubkey_cache.get(validator_index).map(Cow::Borrowed),
|
|
|
|
&signed_aggregate,
|
|
|
|
&fork,
|
|
|
|
chain.genesis_validators_root,
|
|
|
|
&chain.spec,
|
|
|
|
)
|
|
|
|
.map_err(BeaconChainError::SignatureSetError)?,
|
|
|
|
signed_aggregate_signature_set(
|
|
|
|
|validator_index| pubkey_cache.get(validator_index).map(Cow::Borrowed),
|
|
|
|
&signed_aggregate,
|
|
|
|
&fork,
|
|
|
|
chain.genesis_validators_root,
|
|
|
|
&chain.spec,
|
|
|
|
)
|
|
|
|
.map_err(BeaconChainError::SignatureSetError)?,
|
|
|
|
indexed_attestation_signature_set_from_pubkeys(
|
|
|
|
|validator_index| pubkey_cache.get(validator_index).map(Cow::Borrowed),
|
|
|
|
&indexed_attestation.signature,
|
|
|
|
&indexed_attestation,
|
|
|
|
&fork,
|
|
|
|
chain.genesis_validators_root,
|
|
|
|
&chain.spec,
|
|
|
|
)
|
|
|
|
.map_err(BeaconChainError::SignatureSetError)?,
|
|
|
|
];
|
|
|
|
|
2020-07-25 02:03:18 +00:00
|
|
|
Ok(verify_signature_sets(signature_sets.iter()))
|
2020-05-06 11:42:56 +00:00
|
|
|
}
|
|
|
|
|
2020-06-18 09:11:03 +00:00
|
|
|
/// Assists in readability.
|
|
|
|
type CommitteesPerSlot = u64;
|
|
|
|
|
|
|
|
/// Returns the `indexed_attestation` and committee count per slot for the `attestation` using the
|
|
|
|
/// public keys cached in the `chain`.
|
|
|
|
pub fn obtain_indexed_attestation_and_committees_per_slot<T: BeaconChainTypes>(
|
2020-05-06 11:42:56 +00:00
|
|
|
chain: &BeaconChain<T>,
|
|
|
|
attestation: &Attestation<T::EthSpec>,
|
2020-06-18 09:11:03 +00:00
|
|
|
) -> Result<(IndexedAttestation<T::EthSpec>, CommitteesPerSlot), Error> {
|
|
|
|
map_attestation_committee(chain, attestation, |(committee, committees_per_slot)| {
|
2020-05-06 11:42:56 +00:00
|
|
|
get_indexed_attestation(committee.committee, &attestation)
|
2020-06-18 09:11:03 +00:00
|
|
|
.map(|attestation| (attestation, committees_per_slot))
|
2020-09-27 20:59:40 +00:00
|
|
|
.map_err(Error::Invalid)
|
2020-05-06 11:42:56 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-06-18 09:11:03 +00:00
|
|
|
/// Runs the `map_fn` with the committee and committee count per slot for the given `attestation`.
|
2020-05-06 11:42:56 +00:00
|
|
|
///
|
|
|
|
/// This function exists in this odd "map" pattern because efficiently obtaining the committee for
|
|
|
|
/// an attestation can be complex. It might involve reading straight from the
|
|
|
|
/// `beacon_chain.shuffling_cache` or it might involve reading it from a state from the DB. Due to
|
|
|
|
/// the complexities of `RwLock`s on the shuffling cache, a simple `Cow` isn't suitable here.
|
|
|
|
///
|
|
|
|
/// If the committee for `attestation` isn't found in the `shuffling_cache`, we will read a state
|
|
|
|
/// from disk and then update the `shuffling_cache`.
|
|
|
|
pub fn map_attestation_committee<'a, T, F, R>(
|
|
|
|
chain: &'a BeaconChain<T>,
|
|
|
|
attestation: &Attestation<T::EthSpec>,
|
|
|
|
map_fn: F,
|
|
|
|
) -> Result<R, Error>
|
|
|
|
where
|
|
|
|
T: BeaconChainTypes,
|
2020-06-18 09:11:03 +00:00
|
|
|
F: Fn((BeaconCommittee, CommitteesPerSlot)) -> Result<R, Error>,
|
2020-05-06 11:42:56 +00:00
|
|
|
{
|
|
|
|
let attestation_epoch = attestation.data.slot.epoch(T::EthSpec::slots_per_epoch());
|
|
|
|
let target = &attestation.data.target;
|
|
|
|
|
|
|
|
// Attestation target must be for a known block.
|
|
|
|
//
|
|
|
|
// We use fork choice to find the target root, which means that we reject any attestation
|
|
|
|
// that has a `target.root` earlier than our latest finalized root. There's no point in
|
|
|
|
// processing an attestation that does not include our latest finalized block in its chain.
|
|
|
|
//
|
|
|
|
// We do not delay consideration for later, we simply drop the attestation.
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
let target_block = chain
|
2020-05-06 11:42:56 +00:00
|
|
|
.fork_choice
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
.read()
|
|
|
|
.get_block(&target.root)
|
2020-05-06 11:42:56 +00:00
|
|
|
.ok_or_else(|| Error::UnknownTargetRoot(target.root))?;
|
|
|
|
|
|
|
|
// Obtain the shuffling cache, timing how long we wait.
|
|
|
|
let cache_wait_timer =
|
|
|
|
metrics::start_timer(&metrics::ATTESTATION_PROCESSING_SHUFFLING_CACHE_WAIT_TIMES);
|
|
|
|
|
|
|
|
let mut shuffling_cache = chain
|
|
|
|
.shuffling_cache
|
|
|
|
.try_write_for(ATTESTATION_CACHE_LOCK_TIMEOUT)
|
|
|
|
.ok_or_else(|| BeaconChainError::AttestationCacheLockTimeout)?;
|
|
|
|
|
|
|
|
metrics::stop_timer(cache_wait_timer);
|
|
|
|
|
|
|
|
if let Some(committee_cache) = shuffling_cache.get(attestation_epoch, target.root) {
|
2020-06-18 09:11:03 +00:00
|
|
|
let committees_per_slot = committee_cache.committees_per_slot();
|
2020-05-06 11:42:56 +00:00
|
|
|
committee_cache
|
|
|
|
.get_beacon_committee(attestation.data.slot, attestation.data.index)
|
2020-06-18 09:11:03 +00:00
|
|
|
.map(|committee| map_fn((committee, committees_per_slot)))
|
2020-05-06 11:42:56 +00:00
|
|
|
.unwrap_or_else(|| {
|
|
|
|
Err(Error::NoCommitteeForSlotAndIndex {
|
|
|
|
slot: attestation.data.slot,
|
|
|
|
index: attestation.data.index,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
// Drop the shuffling cache to avoid holding the lock for any longer than
|
|
|
|
// required.
|
|
|
|
drop(shuffling_cache);
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
chain.log,
|
|
|
|
"Attestation processing cache miss";
|
|
|
|
"attn_epoch" => attestation_epoch.as_u64(),
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
"target_block_epoch" => target_block.slot.epoch(T::EthSpec::slots_per_epoch()).as_u64(),
|
2020-05-06 11:42:56 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let state_read_timer =
|
|
|
|
metrics::start_timer(&metrics::ATTESTATION_PROCESSING_STATE_READ_TIMES);
|
|
|
|
|
|
|
|
let mut state = chain
|
2020-08-17 08:05:13 +00:00
|
|
|
.store
|
|
|
|
.get_inconsistent_state_for_attestation_verification_only(
|
|
|
|
&target_block.state_root,
|
|
|
|
Some(target_block.slot),
|
|
|
|
)
|
|
|
|
.map_err(BeaconChainError::from)?
|
v0.12 fork choice update (#1229)
* Incomplete scraps
* Add progress on new fork choice impl
* Further progress
* First complete compiling version
* Remove chain reference
* Add new lmd_ghost crate
* Start integrating into beacon chain
* Update `milagro_bls` to new release (#1183)
* Update milagro_bls to new release
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Tidy up fake cryptos
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* move SecretHash to bls and put plaintext back
Signed-off-by: Kirk Baird <baird.k@outlook.com>
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Rough beacon chain impl working
* Remove fork_choice_2
* Remove checkpoint manager
* Half finished ssz impl
* Add missed file
* Add persistence
* Tidy, fix some compile errors
* Remove RwLock from ProtoArrayForkChoice
* Fix store-based compile errors
* Add comments, tidy
* Move function out of ForkChoice struct
* Start testing
* More testing
* Fix compile error
* Tidy beacon_chain::fork_choice
* Queue attestations from the current slot
* Allow fork choice to handle prior-to-genesis start
* Improve error granularity
* Test attestation dequeuing
* Process attestations during block
* Store target root in fork choice
* Move fork choice verification into new crate
* Update tests
* Consensus updates for v0.12 (#1228)
* Update state processing for v0.12
* Fix EF test runners for v0.12
* Fix some tests
* Fix broken attestation verification test
* More test fixes
* Fix typo found in review
* Add `Block` struct to ProtoArray
* Start fixing get_ancestor
* Add rough progress on testing
* Get fork choice tests working
* Progress with testing
* Fix partialeq impl
* Move slot clock from fc_store
* Improve testing
* Add testing for best justified
* Add clone back to SystemTimeSlotClock
* Add balances test
* Start adding balances cache again
* Wire-in balances cache
* Improve tests
* Remove commented-out tests
* Remove beacon_chain::ForkChoice
* Rename crates
* Update wider codebase to new fork_choice layout
* Move advance_slot in test harness
* Tidy ForkChoice::update_time
* Fix verification tests
* Fix compile error with iter::once
* Fix fork choice tests
* Ensure block attestations are processed
* Fix failing beacon_chain tests
* Add first invalid block check
* Add finalized block check
* Progress with testing, new store builder
* Add fixes to get_ancestor
* Fix old genesis justification test
* Fix remaining fork choice tests
* Change root iteration method
* Move on_verified_block
* Remove unused method
* Start adding attestation verification tests
* Add invalid ffg target test
* Add target epoch test
* Add queued attestation test
* Remove old fork choice verification tests
* Tidy, add test
* Move fork choice lock drop
* Rename BeaconForkChoiceStore
* Add comments, tidy BeaconForkChoiceStore
* Update metrics, rename fork_choice_store.rs
* Remove genesis_block_root from ForkChoice
* Tidy
* Update fork_choice comments
* Tidy, add comments
* Tidy, simplify ForkChoice, fix compile issue
* Tidy, removed dead file
* Increase http request timeout
* Fix failing rest_api test
* Set HTTP timeout back to 5s
* Apply fix to get_ancestor
* Address Michael's comments
* Fix typo
* Revert "Fix broken attestation verification test"
This reverts commit 722cdc903b12611de27916a57eeecfa3224f2279.
Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
2020-06-17 01:10:22 +00:00
|
|
|
.ok_or_else(|| BeaconChainError::MissingBeaconState(target_block.state_root))?;
|
2020-05-06 11:42:56 +00:00
|
|
|
|
|
|
|
metrics::stop_timer(state_read_timer);
|
|
|
|
let state_skip_timer =
|
|
|
|
metrics::start_timer(&metrics::ATTESTATION_PROCESSING_STATE_SKIP_TIMES);
|
|
|
|
|
|
|
|
while state.current_epoch() + 1 < attestation_epoch {
|
|
|
|
// Here we tell `per_slot_processing` to skip hashing the state and just
|
|
|
|
// use the zero hash instead.
|
|
|
|
//
|
|
|
|
// The state roots are not useful for the shuffling, so there's no need to
|
|
|
|
// compute them.
|
|
|
|
per_slot_processing(&mut state, Some(Hash256::zero()), &chain.spec)
|
2020-07-23 14:18:00 +00:00
|
|
|
.map_err(BeaconChainError::from)?;
|
2020-05-06 11:42:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
metrics::stop_timer(state_skip_timer);
|
|
|
|
let committee_building_timer =
|
|
|
|
metrics::start_timer(&metrics::ATTESTATION_PROCESSING_COMMITTEE_BUILDING_TIMES);
|
|
|
|
|
|
|
|
let relative_epoch = RelativeEpoch::from_epoch(state.current_epoch(), attestation_epoch)
|
|
|
|
.map_err(BeaconChainError::IncorrectStateForAttestation)?;
|
|
|
|
|
|
|
|
state
|
|
|
|
.build_committee_cache(relative_epoch, &chain.spec)
|
2020-07-23 14:18:00 +00:00
|
|
|
.map_err(BeaconChainError::from)?;
|
2020-05-06 11:42:56 +00:00
|
|
|
|
|
|
|
let committee_cache = state
|
|
|
|
.committee_cache(relative_epoch)
|
2020-07-23 14:18:00 +00:00
|
|
|
.map_err(BeaconChainError::from)?;
|
2020-05-06 11:42:56 +00:00
|
|
|
|
|
|
|
chain
|
|
|
|
.shuffling_cache
|
|
|
|
.try_write_for(ATTESTATION_CACHE_LOCK_TIMEOUT)
|
|
|
|
.ok_or_else(|| BeaconChainError::AttestationCacheLockTimeout)?
|
|
|
|
.insert(attestation_epoch, target.root, committee_cache);
|
|
|
|
|
|
|
|
metrics::stop_timer(committee_building_timer);
|
|
|
|
|
2020-06-18 09:11:03 +00:00
|
|
|
let committees_per_slot = committee_cache.committees_per_slot();
|
2020-05-06 11:42:56 +00:00
|
|
|
committee_cache
|
|
|
|
.get_beacon_committee(attestation.data.slot, attestation.data.index)
|
2020-06-18 09:11:03 +00:00
|
|
|
.map(|committee| map_fn((committee, committees_per_slot)))
|
2020-05-06 11:42:56 +00:00
|
|
|
.unwrap_or_else(|| {
|
|
|
|
Err(Error::NoCommitteeForSlotAndIndex {
|
|
|
|
slot: attestation.data.slot,
|
|
|
|
index: attestation.data.index,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|