From 40560a9eed87194a410b73a146131af707fe9ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Gr=C3=BCner?= <47506558+MegaRedHand@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:57:36 -0300 Subject: [PATCH 1/2] fix: do not subscribe to subnets when not aggregating --- crates/net/p2p/src/lib.rs | 49 ++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/crates/net/p2p/src/lib.rs b/crates/net/p2p/src/lib.rs index e74216e9..8af7c85b 100644 --- a/crates/net/p2p/src/lib.rs +++ b/crates/net/p2p/src/lib.rs @@ -205,40 +205,41 @@ pub fn build_swarm( .subscribe(&aggregation_topic) .unwrap(); - // Compute the set of subnets to subscribe to. - // Validators subscribe for gossipsub mesh health; aggregators additionally - // subscribe to any explicitly requested subnets. - let validator_subnets: HashSet = config - .validator_ids - .iter() - .map(|vid| vid % config.attestation_committee_count) - .collect(); - - let mut subscribe_subnets: HashSet = validator_subnets.clone(); - + // Aggregators subscribe to attestation subnets to receive unaggregated + // attestations. Non-aggregators don't need to subscribe; they publish via + // gossipsub fanout. if config.is_aggregator { + let mut aggregate_subnets: HashSet = config + .validator_ids + .iter() + .map(|vid| vid % config.attestation_committee_count) + .collect(); if let Some(ref explicit_ids) = config.aggregate_subnet_ids { - subscribe_subnets.extend(explicit_ids); + aggregate_subnets.extend(explicit_ids); } // Aggregator with no validators and no explicit subnets: fallback to subnet 0 - if subscribe_subnets.is_empty() { - subscribe_subnets.insert(0); + if aggregate_subnets.is_empty() { + aggregate_subnets.insert(0); + } + for &subnet_id in &aggregate_subnets { + let topic = attestation_subnet_topic(subnet_id); + swarm.behaviour_mut().gossipsub.subscribe(&topic)?; + info!(subnet_id, "Subscribed to attestation subnet"); } } - // Report lowest validator subnet for backward-compatible metric - let metric_subnet = validator_subnets.iter().copied().min().unwrap_or(0); - metrics::set_attestation_committee_subnet(metric_subnet); - - // Build topics and subscribe + // Build topic cache for all validators (avoids string allocation on every publish). let mut attestation_topics: HashMap = HashMap::new(); - for &subnet_id in &subscribe_subnets { - let topic = attestation_subnet_topic(subnet_id); - swarm.behaviour_mut().gossipsub.subscribe(&topic)?; - info!(subnet_id, "Subscribed to attestation subnet"); - attestation_topics.insert(subnet_id, topic); + for &vid in &config.validator_ids { + let subnet_id = vid % config.attestation_committee_count; + attestation_topics + .entry(subnet_id) + .or_insert_with(|| attestation_subnet_topic(subnet_id)); } + let metric_subnet = attestation_topics.keys().copied().min().unwrap_or(0); + metrics::set_attestation_committee_subnet(metric_subnet); + info!(socket=%config.listening_socket, "P2P node started"); Ok(BuiltSwarm { From b3a8a52bab7a1e49185f4748acd4a6ab8f7d61bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Gr=C3=BCner?= <47506558+MegaRedHand@users.noreply.github.com> Date: Wed, 8 Apr 2026 16:20:25 -0300 Subject: [PATCH 2/2] fix: include aggregator topics in cache --- crates/net/p2p/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/net/p2p/src/lib.rs b/crates/net/p2p/src/lib.rs index 8af7c85b..c2a36b8c 100644 --- a/crates/net/p2p/src/lib.rs +++ b/crates/net/p2p/src/lib.rs @@ -228,7 +228,8 @@ pub fn build_swarm( } } - // Build topic cache for all validators (avoids string allocation on every publish). + // Build topic cache (avoids string allocation on every publish). + // Includes validator subnets and any explicit aggregate_subnet_ids. let mut attestation_topics: HashMap = HashMap::new(); for &vid in &config.validator_ids { let subnet_id = vid % config.attestation_committee_count; @@ -236,6 +237,13 @@ pub fn build_swarm( .entry(subnet_id) .or_insert_with(|| attestation_subnet_topic(subnet_id)); } + if let Some(ref explicit_ids) = config.aggregate_subnet_ids { + for &subnet_id in explicit_ids { + attestation_topics + .entry(subnet_id) + .or_insert_with(|| attestation_subnet_topic(subnet_id)); + } + } let metric_subnet = attestation_topics.keys().copied().min().unwrap_or(0); metrics::set_attestation_committee_subnet(metric_subnet);