mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 10:22:38 +00:00
Add DataColumnSidecar gossip topic and message handling (#6147)
* Add `DataColumnSidecar` gossip topic and verification (#5050 and #5783). * Remove gossip verification changes (#5783). * Merge branch 'unstable' into data-column-gossip # Conflicts: # beacon_node/beacon_chain/src/data_column_verification.rs # beacon_node/beacon_chain/src/lib.rs * Add gossip cache timeout for data columns. Rename data column metrics for consistency. * Remove usage of `unimplemented!` and address review comments. * Remove unnused `GossipDataColumnError` variants and address review comments. * Merge branch 'unstable' into data-column-gossip * Update Cargo.lock * Arc `ChainSpec` in discovery to avoid performance regression when needing to clone it repeatedly.
This commit is contained in:
@@ -43,7 +43,7 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tokio::sync::mpsc;
|
||||
use types::{EnrForkId, EthSpec};
|
||||
use types::{ChainSpec, EnrForkId, EthSpec};
|
||||
|
||||
mod subnet_predicate;
|
||||
pub use subnet_predicate::subnet_predicate;
|
||||
@@ -192,6 +192,7 @@ pub struct Discovery<E: EthSpec> {
|
||||
|
||||
/// Logger for the discovery behaviour.
|
||||
log: slog::Logger,
|
||||
spec: Arc<ChainSpec>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Discovery<E> {
|
||||
@@ -201,6 +202,7 @@ impl<E: EthSpec> Discovery<E> {
|
||||
config: &NetworkConfig,
|
||||
network_globals: Arc<NetworkGlobals<E>>,
|
||||
log: &slog::Logger,
|
||||
spec: &ChainSpec,
|
||||
) -> error::Result<Self> {
|
||||
let log = log.clone();
|
||||
|
||||
@@ -325,6 +327,7 @@ impl<E: EthSpec> Discovery<E> {
|
||||
update_ports,
|
||||
log,
|
||||
enr_dir,
|
||||
spec: Arc::new(spec.clone()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -548,6 +551,8 @@ impl<E: EthSpec> Discovery<E> {
|
||||
)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
}
|
||||
// Data column subnets are computed from node ID. No subnet bitfield in the ENR.
|
||||
Subnet::DataColumn(_) => return Ok(()),
|
||||
}
|
||||
|
||||
// replace the global version
|
||||
@@ -753,7 +758,8 @@ impl<E: EthSpec> Discovery<E> {
|
||||
// Only start a discovery query if we have a subnet to look for.
|
||||
if !filtered_subnet_queries.is_empty() {
|
||||
// build the subnet predicate as a combination of the eth2_fork_predicate and the subnet predicate
|
||||
let subnet_predicate = subnet_predicate::<E>(filtered_subnets, &self.log);
|
||||
let subnet_predicate =
|
||||
subnet_predicate::<E>(filtered_subnets, &self.log, self.spec.clone());
|
||||
|
||||
debug!(
|
||||
self.log,
|
||||
@@ -867,6 +873,7 @@ impl<E: EthSpec> Discovery<E> {
|
||||
let query_str = match query.subnet {
|
||||
Subnet::Attestation(_) => "attestation",
|
||||
Subnet::SyncCommittee(_) => "sync_committee",
|
||||
Subnet::DataColumn(_) => "data_column",
|
||||
};
|
||||
|
||||
if let Some(v) = metrics::get_int_counter(
|
||||
@@ -879,8 +886,11 @@ impl<E: EthSpec> Discovery<E> {
|
||||
self.add_subnet_query(query.subnet, query.min_ttl, query.retries + 1);
|
||||
|
||||
// Check the specific subnet against the enr
|
||||
let subnet_predicate =
|
||||
subnet_predicate::<E>(vec![query.subnet], &self.log);
|
||||
let subnet_predicate = subnet_predicate::<E>(
|
||||
vec![query.subnet],
|
||||
&self.log,
|
||||
self.spec.clone(),
|
||||
);
|
||||
|
||||
r.clone()
|
||||
.into_iter()
|
||||
@@ -1194,6 +1204,7 @@ mod tests {
|
||||
}
|
||||
|
||||
async fn build_discovery() -> Discovery<E> {
|
||||
let spec = ChainSpec::default();
|
||||
let keypair = secp256k1::Keypair::generate();
|
||||
let mut config = NetworkConfig::default();
|
||||
config.set_listening_addr(crate::ListenAddress::unused_v4_ports());
|
||||
@@ -1212,7 +1223,7 @@ mod tests {
|
||||
&log,
|
||||
);
|
||||
let keypair = keypair.into();
|
||||
Discovery::new(keypair, &config, Arc::new(globals), &log)
|
||||
Discovery::new(keypair, &config, Arc::new(globals), &log, &spec)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
//! The subnet predicate used for searching for a particular subnet.
|
||||
use super::*;
|
||||
use crate::types::{EnrAttestationBitfield, EnrSyncCommitteeBitfield};
|
||||
use itertools::Itertools;
|
||||
use slog::trace;
|
||||
use std::ops::Deref;
|
||||
use types::{ChainSpec, DataColumnSubnetId};
|
||||
|
||||
/// Returns the predicate for a given subnet.
|
||||
pub fn subnet_predicate<E>(subnets: Vec<Subnet>, log: &slog::Logger) -> impl Fn(&Enr) -> bool + Send
|
||||
pub fn subnet_predicate<E>(
|
||||
subnets: Vec<Subnet>,
|
||||
log: &slog::Logger,
|
||||
spec: Arc<ChainSpec>,
|
||||
) -> impl Fn(&Enr) -> bool + Send
|
||||
where
|
||||
E: EthSpec,
|
||||
{
|
||||
@@ -19,10 +25,13 @@ where
|
||||
};
|
||||
|
||||
// Pre-fork/fork-boundary enrs may not contain a syncnets field.
|
||||
// Don't return early here
|
||||
// Don't return early here.
|
||||
let sync_committee_bitfield: Result<EnrSyncCommitteeBitfield<E>, _> =
|
||||
enr.sync_committee_bitfield::<E>();
|
||||
|
||||
// TODO(das): compute from enr
|
||||
let custody_subnet_count = spec.custody_requirement;
|
||||
|
||||
let predicate = subnets.iter().any(|subnet| match subnet {
|
||||
Subnet::Attestation(s) => attestation_bitfield
|
||||
.get(*s.deref() as usize)
|
||||
@@ -30,6 +39,14 @@ where
|
||||
Subnet::SyncCommittee(s) => sync_committee_bitfield
|
||||
.as_ref()
|
||||
.map_or(false, |b| b.get(*s.deref() as usize).unwrap_or(false)),
|
||||
Subnet::DataColumn(s) => {
|
||||
let mut subnets = DataColumnSubnetId::compute_custody_subnets::<E>(
|
||||
enr.node_id().raw().into(),
|
||||
custody_subnet_count,
|
||||
&spec,
|
||||
);
|
||||
subnets.contains(s)
|
||||
}
|
||||
});
|
||||
|
||||
if !predicate {
|
||||
|
||||
Reference in New Issue
Block a user