mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-23 14:54:45 +00:00
Merge branch 'unstable' into validator-manager
This commit is contained in:
@@ -447,6 +447,21 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
Ok(self.pubkey_cache().get(pubkey))
|
||||
}
|
||||
|
||||
/// Immutable variant of `get_validator_index` which errors if the cache is not up to date.
|
||||
pub fn get_validator_index_read_only(
|
||||
&self,
|
||||
pubkey: &PublicKeyBytes,
|
||||
) -> Result<Option<usize>, Error> {
|
||||
let pubkey_cache = self.pubkey_cache();
|
||||
if pubkey_cache.len() != self.validators().len() {
|
||||
return Err(Error::PubkeyCacheIncomplete {
|
||||
cache_len: pubkey_cache.len(),
|
||||
registry_len: self.validators().len(),
|
||||
});
|
||||
}
|
||||
Ok(pubkey_cache.get(pubkey))
|
||||
}
|
||||
|
||||
/// The epoch corresponding to `self.slot()`.
|
||||
pub fn current_epoch(&self) -> Epoch {
|
||||
self.slot().epoch(T::slots_per_epoch())
|
||||
|
||||
@@ -162,6 +162,9 @@ pub struct ChainSpec {
|
||||
pub attestation_subnet_count: u64,
|
||||
pub random_subnets_per_validator: u64,
|
||||
pub epochs_per_random_subnet_subscription: u64,
|
||||
pub subnets_per_node: u8,
|
||||
pub epochs_per_subnet_subscription: u64,
|
||||
attestation_subnet_extra_bits: u8,
|
||||
|
||||
/*
|
||||
* Application params
|
||||
@@ -428,6 +431,22 @@ impl ChainSpec {
|
||||
Hash256::from(domain)
|
||||
}
|
||||
|
||||
#[allow(clippy::integer_arithmetic)]
|
||||
pub const fn attestation_subnet_prefix_bits(&self) -> u32 {
|
||||
// maybe use log2 when stable https://github.com/rust-lang/rust/issues/70887
|
||||
|
||||
// NOTE: this line is here simply to guarantee that if self.attestation_subnet_count type
|
||||
// is changed, a compiler warning will be raised. This code depends on the type being u64.
|
||||
let attestation_subnet_count: u64 = self.attestation_subnet_count;
|
||||
let attestation_subnet_count_bits = if attestation_subnet_count == 0 {
|
||||
0
|
||||
} else {
|
||||
63 - attestation_subnet_count.leading_zeros()
|
||||
};
|
||||
|
||||
self.attestation_subnet_extra_bits as u32 + attestation_subnet_count_bits
|
||||
}
|
||||
|
||||
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
|
||||
pub fn mainnet() -> Self {
|
||||
Self {
|
||||
@@ -578,9 +597,12 @@ impl ChainSpec {
|
||||
attestation_propagation_slot_range: 32,
|
||||
attestation_subnet_count: 64,
|
||||
random_subnets_per_validator: 1,
|
||||
subnets_per_node: 1,
|
||||
maximum_gossip_clock_disparity_millis: 500,
|
||||
target_aggregators_per_committee: 16,
|
||||
epochs_per_random_subnet_subscription: 256,
|
||||
epochs_per_subnet_subscription: 256,
|
||||
attestation_subnet_extra_bits: 6,
|
||||
|
||||
/*
|
||||
* Application specific
|
||||
@@ -789,9 +811,12 @@ impl ChainSpec {
|
||||
attestation_propagation_slot_range: 32,
|
||||
attestation_subnet_count: 64,
|
||||
random_subnets_per_validator: 1,
|
||||
subnets_per_node: 1,
|
||||
maximum_gossip_clock_disparity_millis: 500,
|
||||
target_aggregators_per_committee: 16,
|
||||
epochs_per_random_subnet_subscription: 256,
|
||||
epochs_per_subnet_subscription: 256,
|
||||
attestation_subnet_extra_bits: 6,
|
||||
|
||||
/*
|
||||
* Application specific
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
//! Identifies each shard by an integer identifier.
|
||||
use crate::{AttestationData, ChainSpec, CommitteeIndex, EthSpec, Slot};
|
||||
use crate::{AttestationData, ChainSpec, CommitteeIndex, Epoch, EthSpec, Slot};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use swap_or_not_shuffle::compute_shuffled_index;
|
||||
|
||||
const MAX_SUBNET_ID: usize = 64;
|
||||
|
||||
@@ -71,6 +72,45 @@ impl SubnetId {
|
||||
.safe_rem(spec.attestation_subnet_count)?
|
||||
.into())
|
||||
}
|
||||
|
||||
#[allow(clippy::integer_arithmetic)]
|
||||
/// Computes the set of subnets the node should be subscribed to during the current epoch,
|
||||
/// along with the first epoch in which these subscriptions are no longer valid.
|
||||
pub fn compute_subnets_for_epoch<T: EthSpec>(
|
||||
node_id: ethereum_types::U256,
|
||||
epoch: Epoch,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(impl Iterator<Item = SubnetId>, Epoch), &'static str> {
|
||||
let node_id_prefix =
|
||||
(node_id >> (256 - spec.attestation_subnet_prefix_bits() as usize)).as_usize();
|
||||
|
||||
let subscription_event_idx = epoch.as_u64() / spec.epochs_per_subnet_subscription;
|
||||
let permutation_seed =
|
||||
eth2_hashing::hash(&int_to_bytes::int_to_bytes8(subscription_event_idx));
|
||||
|
||||
let num_subnets = 1 << spec.attestation_subnet_prefix_bits();
|
||||
|
||||
let permutated_prefix = compute_shuffled_index(
|
||||
node_id_prefix,
|
||||
num_subnets,
|
||||
&permutation_seed,
|
||||
spec.shuffle_round_count,
|
||||
)
|
||||
.ok_or("Unable to shuffle")? as u64;
|
||||
|
||||
// Get the constants we need to avoid holding a reference to the spec
|
||||
let &ChainSpec {
|
||||
subnets_per_node,
|
||||
attestation_subnet_count,
|
||||
..
|
||||
} = spec;
|
||||
|
||||
let subnet_set_generator = (0..subnets_per_node).map(move |idx| {
|
||||
SubnetId::new((permutated_prefix + idx as u64) % attestation_subnet_count)
|
||||
});
|
||||
let valid_until_epoch = (subscription_event_idx + 1) * spec.epochs_per_subnet_subscription;
|
||||
Ok((subnet_set_generator, valid_until_epoch.into()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for SubnetId {
|
||||
|
||||
Reference in New Issue
Block a user