mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-21 13:54:44 +00:00
Add AttesterCache for attestation production (#2478)
## Issue Addressed - Resolves #2169 ## Proposed Changes Adds the `AttesterCache` to allow validators to produce attestations for older slots. Presently, some arbitrary restrictions can force validators to receive an error when attesting to a slot earlier than the present one. This can cause attestation misses when there is excessive load on the validator client or time sync issues between the VC and BN. ## Additional Info NA
This commit is contained in:
@@ -21,7 +21,10 @@ use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
pub use self::committee_cache::CommitteeCache;
|
||||
pub use self::committee_cache::{
|
||||
compute_committee_index_in_epoch, compute_committee_range_in_epoch, epoch_committee_count,
|
||||
CommitteeCache,
|
||||
};
|
||||
pub use clone_config::CloneConfig;
|
||||
pub use eth_spec::*;
|
||||
pub use iter::BlockRootsIter;
|
||||
@@ -1310,10 +1313,22 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
let epoch = relative_epoch.into_epoch(self.current_epoch());
|
||||
let i = Self::committee_cache_index(relative_epoch);
|
||||
|
||||
*self.committee_cache_at_index_mut(i)? = CommitteeCache::initialized(&self, epoch, spec)?;
|
||||
*self.committee_cache_at_index_mut(i)? = self.initialize_committee_cache(epoch, spec)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initializes a new committee cache for the given `epoch`, regardless of whether one already
|
||||
/// exists. Returns the committee cache without attaching it to `self`.
|
||||
///
|
||||
/// To build a cache and store it on `self`, use `Self::build_committee_cache`.
|
||||
pub fn initialize_committee_cache(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<CommitteeCache, Error> {
|
||||
CommitteeCache::initialized(&self, epoch, spec)
|
||||
}
|
||||
|
||||
/// Advances the cache for this state into the next epoch.
|
||||
///
|
||||
/// This should be used if the `slot` of this state is advanced beyond an epoch boundary.
|
||||
|
||||
@@ -121,8 +121,12 @@ impl CommitteeCache {
|
||||
return None;
|
||||
}
|
||||
|
||||
let committee_index =
|
||||
(slot.as_u64() % self.slots_per_epoch) * self.committees_per_slot + index;
|
||||
let committee_index = compute_committee_index_in_epoch(
|
||||
slot,
|
||||
self.slots_per_epoch as usize,
|
||||
self.committees_per_slot as usize,
|
||||
index as usize,
|
||||
);
|
||||
let committee = self.compute_committee(committee_index as usize)?;
|
||||
|
||||
Some(BeaconCommittee {
|
||||
@@ -219,7 +223,10 @@ impl CommitteeCache {
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
pub fn epoch_committee_count(&self) -> usize {
|
||||
self.committees_per_slot as usize * self.slots_per_epoch as usize
|
||||
epoch_committee_count(
|
||||
self.committees_per_slot as usize,
|
||||
self.slots_per_epoch as usize,
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns the number of committees per slot for this cache's epoch.
|
||||
@@ -242,16 +249,7 @@ impl CommitteeCache {
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
fn compute_committee_range(&self, index: usize) -> Option<Range<usize>> {
|
||||
let count = self.epoch_committee_count();
|
||||
if count == 0 || index >= count {
|
||||
return None;
|
||||
}
|
||||
|
||||
let num_validators = self.shuffling.len();
|
||||
let start = (num_validators * index) / count;
|
||||
let end = (num_validators * (index + 1)) / count;
|
||||
|
||||
Some(start..end)
|
||||
compute_committee_range_in_epoch(self.epoch_committee_count(), index, self.shuffling.len())
|
||||
}
|
||||
|
||||
/// Returns the index of some validator in `self.shuffling`.
|
||||
@@ -264,6 +262,44 @@ impl CommitteeCache {
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the position of the given `committee_index` with respect to all committees in the
|
||||
/// epoch.
|
||||
///
|
||||
/// The return result may be used to provide input to the `compute_committee_range_in_epoch`
|
||||
/// function.
|
||||
pub fn compute_committee_index_in_epoch(
|
||||
slot: Slot,
|
||||
slots_per_epoch: usize,
|
||||
committees_per_slot: usize,
|
||||
committee_index: usize,
|
||||
) -> usize {
|
||||
(slot.as_usize() % slots_per_epoch) * committees_per_slot + committee_index
|
||||
}
|
||||
|
||||
/// Computes the range for slicing the shuffled indices to determine the members of a committee.
|
||||
///
|
||||
/// The `index_in_epoch` parameter can be computed computed using
|
||||
/// `compute_committee_index_in_epoch`.
|
||||
pub fn compute_committee_range_in_epoch(
|
||||
epoch_committee_count: usize,
|
||||
index_in_epoch: usize,
|
||||
shuffling_len: usize,
|
||||
) -> Option<Range<usize>> {
|
||||
if epoch_committee_count == 0 || index_in_epoch >= epoch_committee_count {
|
||||
return None;
|
||||
}
|
||||
|
||||
let start = (shuffling_len * index_in_epoch) / epoch_committee_count;
|
||||
let end = (shuffling_len * (index_in_epoch + 1)) / epoch_committee_count;
|
||||
|
||||
Some(start..end)
|
||||
}
|
||||
|
||||
/// Returns the total number of committees in an epoch.
|
||||
pub fn epoch_committee_count(committees_per_slot: usize, slots_per_epoch: usize) -> usize {
|
||||
committees_per_slot * slots_per_epoch
|
||||
}
|
||||
|
||||
/// Returns a list of all `validators` indices where the validator is active at the given
|
||||
/// `epoch`.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user