Files
lighthouse/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs
Jimmy Chen c0b4f01cf3 Improve get_custody_columns validation, caching and error handling (#6308)
* Improve `get_custody_columns` validation, caching and error handling.

* Merge branch 'unstable' into get-custody-columns-error-handing

* Fix failing test and add more test.

* Fix failing test and add more test.

* Merge branch 'unstable' into get-custody-columns-error-handing

# Conflicts:
#	beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs
#	beacon_node/lighthouse_network/src/peer_manager/peerdb.rs
#	beacon_node/lighthouse_network/src/peer_manager/peerdb/peer_info.rs
#	beacon_node/lighthouse_network/src/types/globals.rs
#	beacon_node/network/src/service.rs
#	consensus/types/src/data_column_subnet_id.rs

* Add unit test to make sure the default specs won't panic on the `compute_custody_requirement_subnets` function.

* Add condition when calling `compute_custody_subnets_from_metadata` and update logs.

* Validate `csc` when returning from enr. Remove `csc` computation on connection since we get them on metadata anyway.

* Add `peers_per_custody_subnet_count` to track peer csc and supernodes.

* Disconnect peers with invalid metadata and find other peers instead.

* Fix sampling tests.

* Merge branch 'unstable' into get-custody-columns-error-handing

* Merge branch 'unstable' into get-custody-columns-error-handing
2024-09-06 07:39:16 +00:00

63 lines
2.0 KiB
Rust

//! 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,
spec: Arc<ChainSpec>,
) -> impl Fn(&Enr) -> bool + Send
where
E: EthSpec,
{
let log_clone = log.clone();
move |enr: &Enr| {
let attestation_bitfield: EnrAttestationBitfield<E> = match enr.attestation_bitfield::<E>()
{
Ok(b) => b,
Err(_e) => return false,
};
// Pre-fork/fork-boundary enrs may not contain a syncnets field.
// Don't return early here.
let sync_committee_bitfield: Result<EnrSyncCommitteeBitfield<E>, _> =
enr.sync_committee_bitfield::<E>();
let predicate = subnets.iter().any(|subnet| match subnet {
Subnet::Attestation(s) => attestation_bitfield
.get(*s.deref() as usize)
.unwrap_or(false),
Subnet::SyncCommittee(s) => sync_committee_bitfield
.as_ref()
.map_or(false, |b| b.get(*s.deref() as usize).unwrap_or(false)),
Subnet::DataColumn(s) => {
if let Ok(custody_subnet_count) = enr.custody_subnet_count::<E>(&spec) {
DataColumnSubnetId::compute_custody_subnets::<E>(
enr.node_id().raw(),
custody_subnet_count,
&spec,
)
.map_or(false, |mut subnets| subnets.contains(s))
} else {
false
}
}
});
if !predicate {
trace!(
log_clone,
"Peer found but not on any of the desired subnets";
"peer_id" => %enr.peer_id()
);
}
predicate
}
}