Skip to content

Commit 2fcbea9

Browse files
committed
Add compute_attestation_subnet_prefix_mapping
1 parent 2c1f1c1 commit 2fcbea9

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

consensus/types/src/subnet_id.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
//! Identifies each shard by an integer identifier.
2+
23
use crate::SingleAttestation;
34
use crate::{AttestationRef, ChainSpec, CommitteeIndex, EthSpec, Slot};
45
use alloy_primitives::{U256, bytes::Buf};
56
use safe_arith::{ArithError, SafeArith};
67
use serde::{Deserialize, Serialize};
8+
use std::collections::HashMap;
79
use std::ops::{Deref, DerefMut};
810
use std::sync::LazyLock;
911

@@ -120,6 +122,25 @@ impl SubnetId {
120122
(0..subnets_per_node)
121123
.map(move |idx| SubnetId::new((node_id_prefix + idx as u64) % attestation_subnet_count))
122124
}
125+
126+
pub fn compute_attestation_subnet_prefix_mapping(
127+
spec: &ChainSpec,
128+
) -> HashMap<SubnetId, Vec<i32>> {
129+
let prefix_bits = spec.attestation_subnet_prefix_bits as u32;
130+
let mut mapping: HashMap<SubnetId, Vec<i32>> = HashMap::new();
131+
132+
for prefix in 0..2_i32.pow(prefix_bits) {
133+
let prefixed_node_id = U256::from(prefix) << (256 - prefix_bits);
134+
let node_id_bytes = prefixed_node_id.to_be_bytes::<32>();
135+
let subnets = Self::compute_attestation_subnets(node_id_bytes, spec);
136+
137+
for subnet in subnets {
138+
mapping.entry(subnet).or_insert_with(Vec::new).push(prefix);
139+
}
140+
}
141+
142+
mapping
143+
}
123144
}
124145

125146
impl Deref for SubnetId {
@@ -163,6 +184,7 @@ impl AsRef<str> for SubnetId {
163184
#[cfg(test)]
164185
mod tests {
165186
use crate::Uint256;
187+
use itertools::Itertools;
166188

167189
use super::*;
168190

@@ -207,4 +229,22 @@ mod tests {
207229
);
208230
}
209231
}
232+
233+
#[test]
234+
fn compute_attestation_subnet_prefix_mapping_test() {
235+
let spec = ChainSpec::mainnet();
236+
let prefix_bits = spec.attestation_subnet_prefix_bits as u32;
237+
238+
let mapping = SubnetId::compute_attestation_subnet_prefix_mapping(&spec);
239+
240+
for (subnet_id, prefixes) in mapping {
241+
// Check whether the prefixes are mapped to the correct subnet_id.
242+
for prefix in prefixes {
243+
let prefixed_node_id = U256::from(prefix) << (256 - prefix_bits);
244+
let mut computed_subnets =
245+
SubnetId::compute_attestation_subnets(prefixed_node_id.to_be_bytes(), &spec);
246+
assert!(computed_subnets.contains(&subnet_id));
247+
}
248+
}
249+
}
210250
}

0 commit comments

Comments
 (0)