Skip to content

feat: add select_random_peers to census #1850

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions bin/portal-bridge/src/census/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashSet, time::Duration};
use discv5::enr::NodeId;
use ethportal_api::{
types::{network::Subnetwork, portal_wire::OfferTrace},
OverlayContentKey,
BeaconContentKey, HistoryContentKey, OverlayContentKey, StateContentKey,
};
use network::{Network, NetworkAction, NetworkInitializationConfig, NetworkManager};
use peer::PeerInfo;
Expand Down Expand Up @@ -75,9 +75,22 @@ impl Census {
content_key: &impl OverlayContentKey,
) -> Result<Vec<PeerInfo>, CensusError> {
match subnetwork {
Subnetwork::History => self.history.select_peers(content_key),
Subnetwork::State => self.state.select_peers(content_key),
Subnetwork::Beacon => self.beacon.select_peers(content_key),
Subnetwork::History => self.history.select_peers(Some(content_key)),
Subnetwork::State => self.state.select_peers(Some(content_key)),
Subnetwork::Beacon => self.beacon.select_peers(Some(content_key)),
_ => Err(CensusError::UnsupportedSubnetwork(subnetwork)),
}
}

/// Selects random peers to receive content.
pub fn select_random_peers(
&self,
subnetwork: Subnetwork,
) -> Result<Vec<PeerInfo>, CensusError> {
match subnetwork {
Subnetwork::History => self.history.select_peers(None::<&HistoryContentKey>),
Subnetwork::State => self.state.select_peers(None::<&StateContentKey>),
Subnetwork::Beacon => self.beacon.select_peers(None::<&BeaconContentKey>),
_ => Err(CensusError::UnsupportedSubnetwork(subnetwork)),
}
}
Expand Down
5 changes: 4 additions & 1 deletion bin/portal-bridge/src/census/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,12 @@ impl Network {
}

/// Selects peers to receive content.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this documentation should clarify what happens in None is passed, something like:

Suggested change
/// Selects peers to receive content.
/// Selects peers to receive content.
///
/// If content key is present, only peers interested in content will be returned.
/// Otherwise, all peers are eligible.

///
/// If content key is present, only peers interested in content will be returned.
/// Otherwise, all peers are eligible.
pub fn select_peers(
&self,
content_key: &impl OverlayContentKey,
content_key: Option<&impl OverlayContentKey>,
) -> Result<Vec<PeerInfo>, CensusError> {
if self.peers.is_empty() {
error!(
Expand Down
5 changes: 4 additions & 1 deletion bin/portal-bridge/src/census/peers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ impl<W: Weight> Peers<W> {
}

/// Selects peers to receive content.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here

pub fn select_peers(&self, content_key: &impl OverlayContentKey) -> Vec<PeerInfo> {
///
/// If content key is present, only peers interested in content will be returned.
/// Otherwise, all peers are eligible.
pub fn select_peers(&self, content_key: Option<&impl OverlayContentKey>) -> Vec<PeerInfo> {
self.selector
.select_peers(content_key, self.read().peers.values())
}
Expand Down
24 changes: 14 additions & 10 deletions bin/portal-bridge/src/census/scoring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,25 @@ use super::peer::{Peer, PeerInfo};

/// A trait for calculating peer's weight.
pub trait Weight: Send + Sync {
/// Calculates peer's weight based on
/// - content key and id
/// - OfferResult's
/// - LivenessCheck's
fn weight(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have a documentation as well.

&self,
content_key: &impl OverlayContentKey,
content_id: &[u8; 32],
content_key_and_id: &Option<(&impl OverlayContentKey, [u8; 32])>,
peer: &Peer,
) -> u32;

fn weight_all<'a>(
&self,
content_key: &impl OverlayContentKey,
content_key: Option<&impl OverlayContentKey>,
peers: impl IntoIterator<Item = &'a Peer>,
) -> impl Iterator<Item = (&'a Peer, u32)> {
let content_id = content_key.content_id();
let content_key_and_id = content_key.map(|key| (key, key.content_id()));
peers
.into_iter()
.map(move |peer| (peer, self.weight(content_key, &content_id, peer)))
.map(move |peer| (peer, self.weight(&content_key_and_id, peer)))
}
}

Expand Down Expand Up @@ -83,12 +86,13 @@ impl Default for AdditiveWeight {
impl Weight for AdditiveWeight {
fn weight(
&self,
content_key: &impl OverlayContentKey,
content_id: &[u8; 32],
content_key_and_id: &Option<(&impl OverlayContentKey, [u8; 32])>,
peer: &Peer,
) -> u32 {
if !peer.is_interested_in_content(content_key, content_id) {
return 0;
if let Some((content_key, content_id)) = content_key_and_id {
if !peer.is_interested_in_content(*content_key, content_id) {
return 0;
}
}

let liveness_weight = peer
Expand Down Expand Up @@ -145,7 +149,7 @@ impl<W: Weight> PeerSelector<W> {
/// Selects up to `self.limit` peers based on their weights.
pub fn select_peers<'a>(
&self,
content_key: &impl OverlayContentKey,
content_key: Option<&impl OverlayContentKey>,
peers: impl IntoIterator<Item = &'a Peer>,
) -> Vec<PeerInfo> {
let weighted_peers = self
Expand Down