mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-17 12:58:31 +00:00
Merge branch 'unstable' into merge-unstable-to-deneb-20230808
# Conflicts: # Cargo.lock # beacon_node/beacon_chain/src/lib.rs # beacon_node/execution_layer/src/engine_api.rs # beacon_node/execution_layer/src/engine_api/http.rs # beacon_node/execution_layer/src/test_utils/mod.rs # beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs # beacon_node/lighthouse_network/src/rpc/handler.rs # beacon_node/lighthouse_network/src/rpc/protocol.rs # beacon_node/lighthouse_network/src/service/utils.rs # beacon_node/lighthouse_network/tests/rpc_tests.rs # beacon_node/network/Cargo.toml # beacon_node/network/src/network_beacon_processor/tests.rs # lcli/src/parse_ssz.rs # scripts/cross/Dockerfile # validator_client/src/block_service.rs # validator_client/src/validator_store.rs
This commit is contained in:
@@ -56,6 +56,11 @@ impl CommitteeCache {
|
||||
return Err(Error::ZeroSlotsPerEpoch);
|
||||
}
|
||||
|
||||
// The use of `NonZeroUsize` reduces the maximum number of possible validators by one.
|
||||
if state.validators().len() == usize::max_value() {
|
||||
return Err(Error::TooManyValidators);
|
||||
}
|
||||
|
||||
let active_validator_indices = get_active_validator_indices(state.validators(), epoch);
|
||||
|
||||
if active_validator_indices.is_empty() {
|
||||
@@ -75,11 +80,6 @@ impl CommitteeCache {
|
||||
)
|
||||
.ok_or(Error::UnableToShuffle)?;
|
||||
|
||||
// The use of `NonZeroUsize` reduces the maximum number of possible validators by one.
|
||||
if state.validators().len() == usize::max_value() {
|
||||
return Err(Error::TooManyValidators);
|
||||
}
|
||||
|
||||
let mut shuffling_positions = vec![<_>::default(); state.validators().len()];
|
||||
for (i, &v) in shuffling.iter().enumerate() {
|
||||
*shuffling_positions
|
||||
@@ -174,7 +174,7 @@ impl CommitteeCache {
|
||||
.ok_or(Error::CommitteeCacheUninitialized(None))?;
|
||||
|
||||
initialized_epoch.slot_iter(self.slots_per_epoch).try_fold(
|
||||
Vec::with_capacity(self.slots_per_epoch as usize),
|
||||
Vec::with_capacity(self.epoch_committee_count()),
|
||||
|mut vec, slot| {
|
||||
vec.append(&mut self.get_beacon_committees_at_slot(slot)?);
|
||||
Ok(vec)
|
||||
|
||||
@@ -6,6 +6,7 @@ use serde_derive::Deserialize;
|
||||
use serde_utils::quoted_u64::MaybeQuoted;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
/// Each of the BLS signature domains.
|
||||
@@ -178,7 +179,15 @@ pub struct ChainSpec {
|
||||
pub attestation_subnet_count: u64,
|
||||
pub subnets_per_node: u8,
|
||||
pub epochs_per_subnet_subscription: u64,
|
||||
pub gossip_max_size: u64,
|
||||
pub min_epochs_for_block_requests: u64,
|
||||
pub max_chunk_size: u64,
|
||||
pub ttfb_timeout: u64,
|
||||
pub resp_timeout: u64,
|
||||
pub message_domain_invalid_snappy: [u8; 4],
|
||||
pub message_domain_valid_snappy: [u8; 4],
|
||||
pub attestation_subnet_extra_bits: u8,
|
||||
pub attestation_subnet_prefix_bits: u8,
|
||||
|
||||
/*
|
||||
* Application params
|
||||
@@ -468,10 +477,16 @@ impl ChainSpec {
|
||||
Hash256::from(domain)
|
||||
}
|
||||
|
||||
#[allow(clippy::arithmetic_side_effects)]
|
||||
pub const fn attestation_subnet_prefix_bits(&self) -> u32 {
|
||||
let attestation_subnet_count_bits = self.attestation_subnet_count.ilog2();
|
||||
self.attestation_subnet_extra_bits as u32 + attestation_subnet_count_bits
|
||||
pub fn maximum_gossip_clock_disparity(&self) -> Duration {
|
||||
Duration::from_millis(self.maximum_gossip_clock_disparity_millis)
|
||||
}
|
||||
|
||||
pub fn ttfb_timeout(&self) -> Duration {
|
||||
Duration::from_secs(self.ttfb_timeout)
|
||||
}
|
||||
|
||||
pub fn resp_timeout(&self) -> Duration {
|
||||
Duration::from_secs(self.resp_timeout)
|
||||
}
|
||||
|
||||
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
|
||||
@@ -641,8 +656,15 @@ impl ChainSpec {
|
||||
maximum_gossip_clock_disparity_millis: 500,
|
||||
target_aggregators_per_committee: 16,
|
||||
epochs_per_subnet_subscription: 256,
|
||||
attestation_subnet_extra_bits: 0,
|
||||
|
||||
gossip_max_size: default_gossip_max_size(),
|
||||
min_epochs_for_block_requests: default_min_epochs_for_block_requests(),
|
||||
max_chunk_size: default_max_chunk_size(),
|
||||
ttfb_timeout: default_ttfb_timeout(),
|
||||
resp_timeout: default_resp_timeout(),
|
||||
message_domain_invalid_snappy: default_message_domain_invalid_snappy(),
|
||||
message_domain_valid_snappy: default_message_domain_valid_snappy(),
|
||||
attestation_subnet_extra_bits: default_attestation_subnet_extra_bits(),
|
||||
attestation_subnet_prefix_bits: default_attestation_subnet_prefix_bits(),
|
||||
/*
|
||||
* Application specific
|
||||
*/
|
||||
@@ -876,7 +898,15 @@ impl ChainSpec {
|
||||
maximum_gossip_clock_disparity_millis: 500,
|
||||
target_aggregators_per_committee: 16,
|
||||
epochs_per_subnet_subscription: 256,
|
||||
attestation_subnet_extra_bits: 0,
|
||||
gossip_max_size: default_gossip_max_size(),
|
||||
min_epochs_for_block_requests: default_min_epochs_for_block_requests(),
|
||||
max_chunk_size: default_max_chunk_size(),
|
||||
ttfb_timeout: default_ttfb_timeout(),
|
||||
resp_timeout: default_resp_timeout(),
|
||||
message_domain_invalid_snappy: default_message_domain_invalid_snappy(),
|
||||
message_domain_valid_snappy: default_message_domain_valid_snappy(),
|
||||
attestation_subnet_extra_bits: default_attestation_subnet_extra_bits(),
|
||||
attestation_subnet_prefix_bits: default_attestation_subnet_prefix_bits(),
|
||||
|
||||
/*
|
||||
* Application specific
|
||||
@@ -995,6 +1025,34 @@ pub struct Config {
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
deposit_network_id: u64,
|
||||
deposit_contract_address: Address,
|
||||
|
||||
#[serde(default = "default_gossip_max_size")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
gossip_max_size: u64,
|
||||
#[serde(default = "default_min_epochs_for_block_requests")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
min_epochs_for_block_requests: u64,
|
||||
#[serde(default = "default_max_chunk_size")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
max_chunk_size: u64,
|
||||
#[serde(default = "default_ttfb_timeout")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
ttfb_timeout: u64,
|
||||
#[serde(default = "default_resp_timeout")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
resp_timeout: u64,
|
||||
#[serde(default = "default_message_domain_invalid_snappy")]
|
||||
#[serde(with = "serde_utils::bytes_4_hex")]
|
||||
message_domain_invalid_snappy: [u8; 4],
|
||||
#[serde(default = "default_message_domain_valid_snappy")]
|
||||
#[serde(with = "serde_utils::bytes_4_hex")]
|
||||
message_domain_valid_snappy: [u8; 4],
|
||||
#[serde(default = "default_attestation_subnet_extra_bits")]
|
||||
#[serde(with = "serde_utils::quoted_u8")]
|
||||
attestation_subnet_extra_bits: u8,
|
||||
#[serde(default = "default_attestation_subnet_prefix_bits")]
|
||||
#[serde(with = "serde_utils::quoted_u8")]
|
||||
attestation_subnet_prefix_bits: u8,
|
||||
}
|
||||
|
||||
fn default_bellatrix_fork_version() -> [u8; 4] {
|
||||
@@ -1040,6 +1098,42 @@ fn default_subnets_per_node() -> u8 {
|
||||
2u8
|
||||
}
|
||||
|
||||
const fn default_gossip_max_size() -> u64 {
|
||||
10485760
|
||||
}
|
||||
|
||||
const fn default_min_epochs_for_block_requests() -> u64 {
|
||||
33024
|
||||
}
|
||||
|
||||
const fn default_max_chunk_size() -> u64 {
|
||||
10485760
|
||||
}
|
||||
|
||||
const fn default_ttfb_timeout() -> u64 {
|
||||
5
|
||||
}
|
||||
|
||||
const fn default_resp_timeout() -> u64 {
|
||||
10
|
||||
}
|
||||
|
||||
const fn default_message_domain_invalid_snappy() -> [u8; 4] {
|
||||
[0, 0, 0, 0]
|
||||
}
|
||||
|
||||
const fn default_message_domain_valid_snappy() -> [u8; 4] {
|
||||
[1, 0, 0, 0]
|
||||
}
|
||||
|
||||
const fn default_attestation_subnet_extra_bits() -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
const fn default_attestation_subnet_prefix_bits() -> u8 {
|
||||
6
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
let chain_spec = MainnetEthSpec::default_spec();
|
||||
@@ -1139,6 +1233,16 @@ impl Config {
|
||||
deposit_chain_id: spec.deposit_chain_id,
|
||||
deposit_network_id: spec.deposit_network_id,
|
||||
deposit_contract_address: spec.deposit_contract_address,
|
||||
|
||||
gossip_max_size: spec.gossip_max_size,
|
||||
min_epochs_for_block_requests: spec.min_epochs_for_block_requests,
|
||||
max_chunk_size: spec.max_chunk_size,
|
||||
ttfb_timeout: spec.ttfb_timeout,
|
||||
resp_timeout: spec.resp_timeout,
|
||||
message_domain_invalid_snappy: spec.message_domain_invalid_snappy,
|
||||
message_domain_valid_snappy: spec.message_domain_valid_snappy,
|
||||
attestation_subnet_extra_bits: spec.attestation_subnet_extra_bits,
|
||||
attestation_subnet_prefix_bits: spec.attestation_subnet_prefix_bits,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1185,6 +1289,15 @@ impl Config {
|
||||
deposit_chain_id,
|
||||
deposit_network_id,
|
||||
deposit_contract_address,
|
||||
gossip_max_size,
|
||||
min_epochs_for_block_requests,
|
||||
max_chunk_size,
|
||||
ttfb_timeout,
|
||||
resp_timeout,
|
||||
message_domain_invalid_snappy,
|
||||
message_domain_valid_snappy,
|
||||
attestation_subnet_extra_bits,
|
||||
attestation_subnet_prefix_bits,
|
||||
} = self;
|
||||
|
||||
if preset_base != T::spec_name().to_string().as_str() {
|
||||
@@ -1224,6 +1337,15 @@ impl Config {
|
||||
terminal_block_hash,
|
||||
terminal_block_hash_activation_epoch,
|
||||
safe_slots_to_import_optimistically,
|
||||
gossip_max_size,
|
||||
min_epochs_for_block_requests,
|
||||
max_chunk_size,
|
||||
ttfb_timeout,
|
||||
resp_timeout,
|
||||
message_domain_invalid_snappy,
|
||||
message_domain_valid_snappy,
|
||||
attestation_subnet_extra_bits,
|
||||
attestation_subnet_prefix_bits,
|
||||
..chain_spec.clone()
|
||||
})
|
||||
}
|
||||
@@ -1364,6 +1486,7 @@ mod tests {
|
||||
#[cfg(test)]
|
||||
mod yaml_tests {
|
||||
use super::*;
|
||||
use paste::paste;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
#[test]
|
||||
@@ -1468,29 +1591,35 @@ mod yaml_tests {
|
||||
"#;
|
||||
|
||||
let chain_spec: Config = serde_yaml::from_str(spec).unwrap();
|
||||
assert_eq!(
|
||||
chain_spec.terminal_total_difficulty,
|
||||
default_terminal_total_difficulty()
|
||||
);
|
||||
assert_eq!(
|
||||
chain_spec.terminal_block_hash,
|
||||
default_terminal_block_hash()
|
||||
);
|
||||
assert_eq!(
|
||||
chain_spec.terminal_block_hash_activation_epoch,
|
||||
default_terminal_block_hash_activation_epoch()
|
||||
);
|
||||
assert_eq!(
|
||||
chain_spec.safe_slots_to_import_optimistically,
|
||||
default_safe_slots_to_import_optimistically()
|
||||
);
|
||||
|
||||
// Asserts that `chain_spec.$name` and `default_$name()` are equal.
|
||||
macro_rules! check_default {
|
||||
($name: ident) => {
|
||||
paste! {
|
||||
assert_eq!(
|
||||
chain_spec.$name,
|
||||
[<default_ $name>](),
|
||||
"{} does not match default", stringify!($name));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
check_default!(terminal_total_difficulty);
|
||||
check_default!(terminal_block_hash);
|
||||
check_default!(terminal_block_hash_activation_epoch);
|
||||
check_default!(safe_slots_to_import_optimistically);
|
||||
check_default!(bellatrix_fork_version);
|
||||
check_default!(gossip_max_size);
|
||||
check_default!(min_epochs_for_block_requests);
|
||||
check_default!(max_chunk_size);
|
||||
check_default!(ttfb_timeout);
|
||||
check_default!(resp_timeout);
|
||||
check_default!(message_domain_invalid_snappy);
|
||||
check_default!(message_domain_valid_snappy);
|
||||
check_default!(attestation_subnet_extra_bits);
|
||||
check_default!(attestation_subnet_prefix_bits);
|
||||
|
||||
assert_eq!(chain_spec.bellatrix_fork_epoch, None);
|
||||
|
||||
assert_eq!(
|
||||
chain_spec.bellatrix_fork_version,
|
||||
default_bellatrix_fork_version()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -71,6 +71,7 @@ pub mod sync_duty;
|
||||
pub mod validator;
|
||||
pub mod validator_subscription;
|
||||
pub mod voluntary_exit;
|
||||
pub mod withdrawal_credentials;
|
||||
#[macro_use]
|
||||
pub mod slot_epoch_macros;
|
||||
pub mod config_and_preset;
|
||||
@@ -196,6 +197,7 @@ pub use crate::validator_registration_data::*;
|
||||
pub use crate::validator_subscription::ValidatorSubscription;
|
||||
pub use crate::voluntary_exit::VoluntaryExit;
|
||||
pub use crate::withdrawal::Withdrawal;
|
||||
pub use crate::withdrawal_credentials::WithdrawalCredentials;
|
||||
|
||||
pub type CommitteeIndex = u64;
|
||||
pub type Hash256 = H256;
|
||||
|
||||
@@ -84,7 +84,7 @@ impl SubnetId {
|
||||
let subscription_duration = spec.epochs_per_subnet_subscription;
|
||||
|
||||
let node_id_prefix =
|
||||
(node_id >> (256 - spec.attestation_subnet_prefix_bits() as usize)).as_usize();
|
||||
(node_id >> (256 - spec.attestation_subnet_prefix_bits as usize)).as_usize();
|
||||
|
||||
// NOTE: The as_u64() panics if the number is larger than u64::max_value(). This cannot be
|
||||
// true as spec.epochs_per_subnet_subscription is a u64.
|
||||
@@ -99,7 +99,7 @@ impl SubnetId {
|
||||
let permutation_seed =
|
||||
ethereum_hashing::hash(&int_to_bytes::int_to_bytes8(subscription_event_idx));
|
||||
|
||||
let num_subnets = 1 << spec.attestation_subnet_prefix_bits();
|
||||
let num_subnets = 1 << spec.attestation_subnet_prefix_bits;
|
||||
let permutated_prefix = compute_shuffled_index(
|
||||
node_id_prefix,
|
||||
num_subnets,
|
||||
|
||||
57
consensus/types/src/withdrawal_credentials.rs
Normal file
57
consensus/types/src/withdrawal_credentials.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
use crate::*;
|
||||
use bls::get_withdrawal_credentials;
|
||||
|
||||
pub struct WithdrawalCredentials(Hash256);
|
||||
|
||||
impl WithdrawalCredentials {
|
||||
pub fn bls(withdrawal_public_key: &PublicKey, spec: &ChainSpec) -> Self {
|
||||
let withdrawal_credentials =
|
||||
get_withdrawal_credentials(withdrawal_public_key, spec.bls_withdrawal_prefix_byte);
|
||||
Self(Hash256::from_slice(&withdrawal_credentials))
|
||||
}
|
||||
|
||||
pub fn eth1(withdrawal_address: Address, spec: &ChainSpec) -> Self {
|
||||
let mut withdrawal_credentials = [0; 32];
|
||||
withdrawal_credentials[0] = spec.eth1_address_withdrawal_prefix_byte;
|
||||
withdrawal_credentials[12..].copy_from_slice(withdrawal_address.as_bytes());
|
||||
Self(Hash256::from_slice(&withdrawal_credentials))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WithdrawalCredentials> for Hash256 {
|
||||
fn from(withdrawal_credentials: WithdrawalCredentials) -> Self {
|
||||
withdrawal_credentials.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::test_utils::generate_deterministic_keypair;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn bls_withdrawal_credentials() {
|
||||
let spec = &MainnetEthSpec::default_spec();
|
||||
let keypair = generate_deterministic_keypair(0);
|
||||
let credentials = WithdrawalCredentials::bls(&keypair.pk, spec);
|
||||
let manually_generated_credentials =
|
||||
get_withdrawal_credentials(&keypair.pk, spec.bls_withdrawal_prefix_byte);
|
||||
let hash: Hash256 = credentials.into();
|
||||
assert_eq!(hash[0], spec.bls_withdrawal_prefix_byte);
|
||||
assert_eq!(hash.as_bytes(), &manually_generated_credentials);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eth1_withdrawal_credentials() {
|
||||
let spec = &MainnetEthSpec::default_spec();
|
||||
let address = Address::from_str("0x25c4a76E7d118705e7Ea2e9b7d8C59930d8aCD3b").unwrap();
|
||||
let credentials = WithdrawalCredentials::eth1(address, spec);
|
||||
let hash: Hash256 = credentials.into();
|
||||
assert_eq!(
|
||||
hash,
|
||||
Hash256::from_str("0x01000000000000000000000025c4a76E7d118705e7Ea2e9b7d8C59930d8aCD3b")
|
||||
.unwrap()
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user