Skip to content

Commit 8353ec9

Browse files
Update deterministic subnets upgrade to allow prefix computation (#4959)
* add new spec field to spec * add spec changes * fix bug and update expected subnets with validation from pyspec * fix values and make test prettier (?) * fix style --------- Co-authored-by: Lion - dapplion <[email protected]>
1 parent d2aef1b commit 8353ec9

File tree

8 files changed

+51
-27
lines changed

8 files changed

+51
-27
lines changed

common/eth2_network_config/built_in_network_configs/gnosis/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,4 @@ MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
105105
ATTESTATION_SUBNET_COUNT: 64
106106
ATTESTATION_SUBNET_EXTRA_BITS: 0
107107
ATTESTATION_SUBNET_PREFIX_BITS: 6
108+
ATTESTATION_SUBNET_SHUFFLING_PREFIX_BITS: 3

common/eth2_network_config/built_in_network_configs/holesky/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ ATTESTATION_SUBNET_COUNT: 64
105105
ATTESTATION_SUBNET_EXTRA_BITS: 0
106106
# ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS
107107
ATTESTATION_SUBNET_PREFIX_BITS: 6
108+
ATTESTATION_SUBNET_SHUFFLING_PREFIX_BITS: 3
108109

109110
# Deneb
110111
# `2**7` (=128)

common/eth2_network_config/built_in_network_configs/mainnet/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,4 @@ MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
105105
ATTESTATION_SUBNET_COUNT: 64
106106
ATTESTATION_SUBNET_EXTRA_BITS: 0
107107
ATTESTATION_SUBNET_PREFIX_BITS: 6
108+
ATTESTATION_SUBNET_SHUFFLING_PREFIX_BITS: 3

common/eth2_network_config/built_in_network_configs/prater/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ ATTESTATION_SUBNET_COUNT: 64
115115
ATTESTATION_SUBNET_EXTRA_BITS: 0
116116
# ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS
117117
ATTESTATION_SUBNET_PREFIX_BITS: 6
118+
ATTESTATION_SUBNET_SHUFFLING_PREFIX_BITS: 3
118119

119120
# Deneb
120121
# `2**7` (=128)

common/eth2_network_config/built_in_network_configs/sepolia/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ ATTESTATION_SUBNET_COUNT: 64
104104
ATTESTATION_SUBNET_EXTRA_BITS: 0
105105
# ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS
106106
ATTESTATION_SUBNET_PREFIX_BITS: 6
107+
ATTESTATION_SUBNET_SHUFFLING_PREFIX_BITS: 3
107108

108109
# Deneb
109110
# `2**7` (=128)

consensus/types/src/chain_spec.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ pub struct ChainSpec {
189189
pub attestation_subnet_count: u64,
190190
pub attestation_subnet_extra_bits: u8,
191191
pub attestation_subnet_prefix_bits: u8,
192+
pub attestation_subnet_shuffling_prefix_bits: u8,
192193

193194
/*
194195
* Networking Deneb
@@ -701,6 +702,8 @@ impl ChainSpec {
701702
message_domain_valid_snappy: default_message_domain_valid_snappy(),
702703
attestation_subnet_extra_bits: default_attestation_subnet_extra_bits(),
703704
attestation_subnet_prefix_bits: default_attestation_subnet_prefix_bits(),
705+
attestation_subnet_shuffling_prefix_bits:
706+
default_attestation_subnet_shuffling_prefix_bits(),
704707
max_request_blocks: default_max_request_blocks(),
705708

706709
/*
@@ -962,6 +965,8 @@ impl ChainSpec {
962965
message_domain_valid_snappy: default_message_domain_valid_snappy(),
963966
attestation_subnet_extra_bits: default_attestation_subnet_extra_bits(),
964967
attestation_subnet_prefix_bits: default_attestation_subnet_prefix_bits(),
968+
attestation_subnet_shuffling_prefix_bits:
969+
default_attestation_subnet_shuffling_prefix_bits(),
965970
max_request_blocks: default_max_request_blocks(),
966971

967972
/*
@@ -1139,6 +1144,9 @@ pub struct Config {
11391144
#[serde(default = "default_attestation_subnet_prefix_bits")]
11401145
#[serde(with = "serde_utils::quoted_u8")]
11411146
attestation_subnet_prefix_bits: u8,
1147+
#[serde(default = "default_attestation_subnet_shuffling_prefix_bits")]
1148+
#[serde(with = "serde_utils::quoted_u8")]
1149+
attestation_subnet_shuffling_prefix_bits: u8,
11421150
#[serde(default = "default_max_request_blocks_deneb")]
11431151
#[serde(with = "serde_utils::quoted_u64")]
11441152
max_request_blocks_deneb: u64,
@@ -1236,6 +1244,10 @@ const fn default_attestation_subnet_prefix_bits() -> u8 {
12361244
6
12371245
}
12381246

1247+
const fn default_attestation_subnet_shuffling_prefix_bits() -> u8 {
1248+
3
1249+
}
1250+
12391251
const fn default_max_request_blocks() -> u64 {
12401252
1024
12411253
}
@@ -1414,6 +1426,7 @@ impl Config {
14141426
message_domain_valid_snappy: spec.message_domain_valid_snappy,
14151427
attestation_subnet_extra_bits: spec.attestation_subnet_extra_bits,
14161428
attestation_subnet_prefix_bits: spec.attestation_subnet_prefix_bits,
1429+
attestation_subnet_shuffling_prefix_bits: spec.attestation_subnet_shuffling_prefix_bits,
14171430
max_request_blocks_deneb: spec.max_request_blocks_deneb,
14181431
max_request_blob_sidecars: spec.max_request_blob_sidecars,
14191432
min_epochs_for_blob_sidecars_requests: spec.min_epochs_for_blob_sidecars_requests,
@@ -1474,6 +1487,7 @@ impl Config {
14741487
message_domain_valid_snappy,
14751488
attestation_subnet_extra_bits,
14761489
attestation_subnet_prefix_bits,
1490+
attestation_subnet_shuffling_prefix_bits,
14771491
max_request_blocks,
14781492
epochs_per_subnet_subscription,
14791493
attestation_propagation_slot_range,
@@ -1531,6 +1545,7 @@ impl Config {
15311545
message_domain_valid_snappy,
15321546
attestation_subnet_extra_bits,
15331547
attestation_subnet_prefix_bits,
1548+
attestation_subnet_shuffling_prefix_bits,
15341549
max_request_blocks,
15351550
epochs_per_subnet_subscription,
15361551
attestation_propagation_slot_range,
@@ -1817,6 +1832,7 @@ mod yaml_tests {
18171832
check_default!(message_domain_valid_snappy);
18181833
check_default!(attestation_subnet_extra_bits);
18191834
check_default!(attestation_subnet_prefix_bits);
1835+
check_default!(attestation_subnet_shuffling_prefix_bits);
18201836

18211837
assert_eq!(chain_spec.bellatrix_fork_epoch, None);
18221838
}

consensus/types/src/subnet_id.rs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -72,36 +72,43 @@ impl SubnetId {
7272
.into())
7373
}
7474

75-
#[allow(clippy::arithmetic_side_effects)]
7675
/// Computes the set of subnets the node should be subscribed to during the current epoch,
7776
/// along with the first epoch in which these subscriptions are no longer valid.
77+
#[allow(clippy::arithmetic_side_effects)]
7878
pub fn compute_subnets_for_epoch<T: EthSpec>(
7979
node_id: ethereum_types::U256,
8080
epoch: Epoch,
8181
spec: &ChainSpec,
8282
) -> Result<(impl Iterator<Item = SubnetId>, Epoch), &'static str> {
83-
// Simplify the variable name
83+
// simplify variable naming
8484
let subscription_duration = spec.epochs_per_subnet_subscription;
85+
let prefix_bits = spec.attestation_subnet_prefix_bits as u64;
86+
let shuffling_prefix_bits = spec.attestation_subnet_shuffling_prefix_bits as u64;
8587

86-
let node_id_prefix =
87-
(node_id >> (256 - spec.attestation_subnet_prefix_bits as usize)).as_usize();
88+
// calculate the prefixes used to compute the subnet and shuffling
89+
let node_id_prefix = (node_id >> (256 - prefix_bits)).as_u64();
90+
let shuffling_prefix = (node_id >> (256 - (prefix_bits + shuffling_prefix_bits))).as_u64();
8891

89-
// NOTE: The as_u64() panics if the number is larger than u64::max_value(). This cannot be
90-
// true as spec.epochs_per_subnet_subscription is a u64.
91-
let node_offset = (node_id % ethereum_types::U256::from(subscription_duration)).as_u64();
92+
// number of groups the shuffling creates
93+
let shuffling_groups = 1 << shuffling_prefix_bits;
94+
// shuffling group for this node
95+
let shuffling_bits = shuffling_prefix % shuffling_groups;
96+
let epoch_transition = (node_id_prefix
97+
+ (shuffling_bits * (subscription_duration >> shuffling_prefix_bits)))
98+
% subscription_duration;
9299

93100
// Calculate at which epoch this node needs to re-evaluate
94101
let valid_until_epoch = epoch.as_u64()
95102
+ subscription_duration
96-
.saturating_sub((epoch.as_u64() + node_offset) % subscription_duration);
103+
.saturating_sub((epoch.as_u64() + epoch_transition) % subscription_duration);
97104

98-
let subscription_event_idx = (epoch.as_u64() + node_offset) / subscription_duration;
105+
let subscription_event_idx = (epoch.as_u64() + epoch_transition) / subscription_duration;
99106
let permutation_seed =
100107
ethereum_hashing::hash(&int_to_bytes::int_to_bytes8(subscription_event_idx));
101108

102109
let num_subnets = 1 << spec.attestation_subnet_prefix_bits;
103110
let permutated_prefix = compute_shuffled_index(
104-
node_id_prefix,
111+
node_id_prefix as usize,
105112
num_subnets,
106113
&permutation_seed,
107114
spec.shuffle_round_count,
@@ -180,38 +187,33 @@ mod tests {
180187
"60930578857433095740782970114409273483106482059893286066493409689627770333527",
181188
"103822458477361691467064888613019442068586830412598673713899771287914656699997",
182189
]
183-
.into_iter()
184-
.map(|v| ethereum_types::U256::from_dec_str(v).unwrap())
185-
.collect::<Vec<_>>();
190+
.map(|v| ethereum_types::U256::from_dec_str(v).unwrap());
186191

187192
let epochs = [
188193
54321u64, 1017090249, 1827566880, 846255942, 766597383, 1204990115, 1616209495,
189194
1774367616, 1484598751, 3525502229,
190195
]
191-
.into_iter()
192-
.map(Epoch::from)
193-
.collect::<Vec<_>>();
196+
.map(Epoch::from);
194197

195198
// Test mainnet
196199
let spec = ChainSpec::mainnet();
197200

198201
// Calculated by hand
199-
let expected_valid_time: Vec<u64> = [
200-
54528, 1017090371, 1827567108, 846256076, 766597570, 1204990135, 1616209582,
201-
1774367723, 1484598953, 3525502371,
202-
]
203-
.into();
202+
let expected_valid_time = [
203+
54528u64, 1017090255, 1827567030, 846256049, 766597387, 1204990287, 1616209536,
204+
1774367857, 1484598847, 3525502311,
205+
];
204206

205207
// Calculated from pyspec
206-
let expected_subnets = vec![
208+
let expected_subnets = [
207209
vec![4u64, 5u64],
208-
vec![61, 62],
209-
vec![23, 24],
210+
vec![31, 32],
211+
vec![39, 40],
210212
vec![38, 39],
211213
vec![53, 54],
212-
vec![39, 40],
214+
vec![57, 58],
213215
vec![48, 49],
214-
vec![39, 40],
216+
vec![1, 2],
215217
vec![34, 35],
216218
vec![37, 38],
217219
];
@@ -228,11 +230,11 @@ mod tests {
228230
>(node_ids[x], epochs[x], &spec)
229231
.unwrap();
230232

231-
assert_eq!(Epoch::from(expected_valid_time[x]), valid_time);
232233
assert_eq!(
233234
expected_subnets[x],
234235
computed_subnets.map(SubnetId::into).collect::<Vec<u64>>()
235236
);
237+
assert_eq!(Epoch::from(expected_valid_time[x]), valid_time);
236238
}
237239
}
238240
}

lighthouse/environment/tests/testnet_dir/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,4 @@ MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
9797
ATTESTATION_SUBNET_COUNT: 64
9898
ATTESTATION_SUBNET_EXTRA_BITS: 0
9999
ATTESTATION_SUBNET_PREFIX_BITS: 6
100+
ATTESTATION_SUBNET_SHUFFLING_PREFIX_BITS: 3

0 commit comments

Comments
 (0)