mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-21 13:54:44 +00:00
Merge branch 'unstable' of https://github.com/sigp/lighthouse into deneb-free-blobs
This commit is contained in:
@@ -176,11 +176,9 @@ pub struct ChainSpec {
|
||||
pub maximum_gossip_clock_disparity_millis: u64,
|
||||
pub target_aggregators_per_committee: u64,
|
||||
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,
|
||||
pub attestation_subnet_extra_bits: u8,
|
||||
|
||||
/*
|
||||
* Application params
|
||||
@@ -472,17 +470,7 @@ impl ChainSpec {
|
||||
|
||||
#[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()
|
||||
};
|
||||
|
||||
let attestation_subnet_count_bits = self.attestation_subnet_count.ilog2();
|
||||
self.attestation_subnet_extra_bits as u32 + attestation_subnet_count_bits
|
||||
}
|
||||
|
||||
@@ -649,13 +637,11 @@ impl ChainSpec {
|
||||
network_id: 1, // mainnet network id
|
||||
attestation_propagation_slot_range: 32,
|
||||
attestation_subnet_count: 64,
|
||||
random_subnets_per_validator: 1,
|
||||
subnets_per_node: 1,
|
||||
subnets_per_node: 2,
|
||||
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,
|
||||
attestation_subnet_extra_bits: 0,
|
||||
|
||||
/*
|
||||
* Application specific
|
||||
@@ -886,13 +872,11 @@ impl ChainSpec {
|
||||
network_id: 100, // Gnosis Chain network id
|
||||
attestation_propagation_slot_range: 32,
|
||||
attestation_subnet_count: 64,
|
||||
random_subnets_per_validator: 1,
|
||||
subnets_per_node: 1,
|
||||
subnets_per_node: 4, // Make this larger than usual to avoid network damage
|
||||
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,
|
||||
attestation_subnet_extra_bits: 0,
|
||||
|
||||
/*
|
||||
* Application specific
|
||||
@@ -988,6 +972,9 @@ pub struct Config {
|
||||
shard_committee_period: u64,
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
eth1_follow_distance: u64,
|
||||
#[serde(default = "default_subnets_per_node")]
|
||||
#[serde(with = "serde_utils::quoted_u8")]
|
||||
subnets_per_node: u8,
|
||||
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
inactivity_score_bias: u64,
|
||||
@@ -1049,6 +1036,10 @@ fn default_safe_slots_to_import_optimistically() -> u64 {
|
||||
128u64
|
||||
}
|
||||
|
||||
fn default_subnets_per_node() -> u8 {
|
||||
2u8
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
let chain_spec = MainnetEthSpec::default_spec();
|
||||
@@ -1135,6 +1126,7 @@ impl Config {
|
||||
min_validator_withdrawability_delay: spec.min_validator_withdrawability_delay,
|
||||
shard_committee_period: spec.shard_committee_period,
|
||||
eth1_follow_distance: spec.eth1_follow_distance,
|
||||
subnets_per_node: spec.subnets_per_node,
|
||||
|
||||
inactivity_score_bias: spec.inactivity_score_bias,
|
||||
inactivity_score_recovery_rate: spec.inactivity_score_recovery_rate,
|
||||
@@ -1183,6 +1175,7 @@ impl Config {
|
||||
min_validator_withdrawability_delay,
|
||||
shard_committee_period,
|
||||
eth1_follow_distance,
|
||||
subnets_per_node,
|
||||
inactivity_score_bias,
|
||||
inactivity_score_recovery_rate,
|
||||
ejection_balance,
|
||||
@@ -1217,6 +1210,7 @@ impl Config {
|
||||
min_validator_withdrawability_delay,
|
||||
shard_committee_period,
|
||||
eth1_follow_distance,
|
||||
subnets_per_node,
|
||||
inactivity_score_bias,
|
||||
inactivity_score_recovery_rate,
|
||||
ejection_balance,
|
||||
|
||||
@@ -87,10 +87,6 @@ pub fn get_extra_fields(spec: &ChainSpec) -> HashMap<String, Value> {
|
||||
"domain_application_mask".to_uppercase()=> u32_hex(spec.domain_application_mask),
|
||||
"target_aggregators_per_committee".to_uppercase() =>
|
||||
spec.target_aggregators_per_committee.to_string().into(),
|
||||
"random_subnets_per_validator".to_uppercase() =>
|
||||
spec.random_subnets_per_validator.to_string().into(),
|
||||
"epochs_per_random_subnet_subscription".to_uppercase() =>
|
||||
spec.epochs_per_random_subnet_subscription.to_string().into(),
|
||||
"domain_contribution_and_proof".to_uppercase() =>
|
||||
u32_hex(spec.domain_contribution_and_proof),
|
||||
"domain_sync_committee".to_uppercase() => u32_hex(spec.domain_sync_committee),
|
||||
|
||||
@@ -80,15 +80,26 @@ impl SubnetId {
|
||||
epoch: Epoch,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(impl Iterator<Item = SubnetId>, Epoch), &'static str> {
|
||||
// Simplify the variable name
|
||||
let subscription_duration = spec.epochs_per_subnet_subscription;
|
||||
|
||||
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;
|
||||
// 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.
|
||||
let node_offset = (node_id % ethereum_types::U256::from(subscription_duration)).as_u64();
|
||||
|
||||
// Calculate at which epoch this node needs to re-evaluate
|
||||
let valid_until_epoch = epoch.as_u64()
|
||||
+ subscription_duration
|
||||
.saturating_sub((epoch.as_u64() + node_offset) % subscription_duration);
|
||||
|
||||
let subscription_event_idx = (epoch.as_u64() + node_offset) / subscription_duration;
|
||||
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 permutated_prefix = compute_shuffled_index(
|
||||
node_id_prefix,
|
||||
num_subnets,
|
||||
@@ -107,7 +118,6 @@ impl SubnetId {
|
||||
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()))
|
||||
}
|
||||
}
|
||||
@@ -149,3 +159,80 @@ impl AsRef<str> for SubnetId {
|
||||
subnet_id_to_string(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// A set of tests compared to the python specification
|
||||
#[test]
|
||||
fn compute_subnets_for_epoch_unit_test() {
|
||||
// Randomized variables used generated with the python specification
|
||||
let node_ids = [
|
||||
"0",
|
||||
"88752428858350697756262172400162263450541348766581994718383409852729519486397",
|
||||
"18732750322395381632951253735273868184515463718109267674920115648614659369468",
|
||||
"27726842142488109545414954493849224833670205008410190955613662332153332462900",
|
||||
"39755236029158558527862903296867805548949739810920318269566095185775868999998",
|
||||
"31899136003441886988955119620035330314647133604576220223892254902004850516297",
|
||||
"58579998103852084482416614330746509727562027284701078483890722833654510444626",
|
||||
"28248042035542126088870192155378394518950310811868093527036637864276176517397",
|
||||
"60930578857433095740782970114409273483106482059893286066493409689627770333527",
|
||||
"103822458477361691467064888613019442068586830412598673713899771287914656699997",
|
||||
]
|
||||
.into_iter()
|
||||
.map(|v| ethereum_types::U256::from_dec_str(v).unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let epochs = [
|
||||
54321u64, 1017090249, 1827566880, 846255942, 766597383, 1204990115, 1616209495,
|
||||
1774367616, 1484598751, 3525502229,
|
||||
]
|
||||
.into_iter()
|
||||
.map(Epoch::from)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Test mainnet
|
||||
let spec = ChainSpec::mainnet();
|
||||
|
||||
// Calculated by hand
|
||||
let expected_valid_time: Vec<u64> = [
|
||||
54528, 1017090371, 1827567108, 846256076, 766597570, 1204990135, 1616209582,
|
||||
1774367723, 1484598953, 3525502371,
|
||||
]
|
||||
.into();
|
||||
|
||||
// Calculated from pyspec
|
||||
let expected_subnets = vec![
|
||||
vec![4u64, 5u64],
|
||||
vec![61, 62],
|
||||
vec![23, 24],
|
||||
vec![38, 39],
|
||||
vec![53, 54],
|
||||
vec![39, 40],
|
||||
vec![48, 49],
|
||||
vec![39, 40],
|
||||
vec![34, 35],
|
||||
vec![37, 38],
|
||||
];
|
||||
|
||||
for x in 0..node_ids.len() {
|
||||
println!("Test: {}", x);
|
||||
println!(
|
||||
"NodeId: {}\n Epoch: {}\n, expected_update_time: {}\n, expected_subnets: {:?}",
|
||||
node_ids[x], epochs[x], expected_valid_time[x], expected_subnets[x]
|
||||
);
|
||||
|
||||
let (computed_subnets, valid_time) = SubnetId::compute_subnets_for_epoch::<
|
||||
crate::MainnetEthSpec,
|
||||
>(node_ids[x], epochs[x], &spec)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(Epoch::from(expected_valid_time[x]), valid_time);
|
||||
assert_eq!(
|
||||
expected_subnets[x],
|
||||
computed_subnets.map(SubnetId::into).collect::<Vec<u64>>()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user