Skip to content

Commit

Permalink
first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
SyntheticBird45 committed Nov 10, 2024
1 parent 525e20e commit b3b6eaf
Show file tree
Hide file tree
Showing 16 changed files with 339 additions and 88 deletions.
4 changes: 3 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ cuprate-levin = { path = "net/levin" ,default-feature
cuprate-wire = { path = "net/wire" ,default-features = false}
cuprate-p2p = { path = "p2p/p2p" ,default-features = false}
cuprate-p2p-core = { path = "p2p/p2p-core" ,default-features = false}
cuprate-p2p-bucket = { path = "p2p/p2p-bucket" ,default-features = false}
cuprate-p2p-bucket = { path = "p2p/bucket" ,default-features = false}
cuprate-dandelion-tower = { path = "p2p/dandelion-tower" ,default-features = false}
cuprate-async-buffer = { path = "p2p/async-buffer" ,default-features = false}
cuprate-address-book = { path = "p2p/address-book" ,default-features = false}
Expand Down
3 changes: 2 additions & 1 deletion p2p/address-book/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ authors = ["Boog900"]
cuprate-constants = { workspace = true }
cuprate-pruning = { workspace = true }
cuprate-p2p-core = { workspace = true, features = ["borsh"] }
cuprate-p2p-bucket = { workspace = true }

tower = { workspace = true, features = ["util"] }
tokio = { workspace = true, features = ["time", "fs", "rt"]}
Expand All @@ -19,7 +20,7 @@ futures = { workspace = true, features = ["std"] }

thiserror = { workspace = true }
tracing = { workspace = true, features = ["std", "attributes"] }
indexmap = { workspace = true, features = ["std"] }
#indexmap = { workspace = true, features = ["std"] }

rand = { workspace = true, features = ["std", "std_rng"] }

Expand Down
11 changes: 11 additions & 0 deletions p2p/address-book/src/book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,13 @@ impl<Z: BorshNetworkZone> AddressBook<Z> {
self.connected_peers.insert(internal_peer_id, peer);
Ok(())
}

fn add_white_peer(
&mut self,
white_peer: ZoneSpecificPeerListEntryBase<Z::Addr>
) {
self.white_list.add_new_peer(white_peer);
}
}

impl<Z: BorshNetworkZone> Service<AddressBookRequest<Z>> for AddressBook<Z> {
Expand Down Expand Up @@ -401,6 +408,10 @@ impl<Z: BorshNetworkZone> Service<AddressBookRequest<Z>> for AddressBook<Z> {
self.handle_incoming_peer_list(peer_list);
Ok(AddressBookResponse::Ok)
}
AddressBookRequest::AddWhitePeer(white_peer) =>{
self.add_white_peer(white_peer);
Ok(AddressBookResponse::Ok)
}
AddressBookRequest::TakeRandomWhitePeer { height } => self
.take_random_white_peer(height)
.map(AddressBookResponse::Peer)
Expand Down
62 changes: 31 additions & 31 deletions p2p/address-book/src/peer_list.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::collections::{BTreeMap, HashMap, HashSet};

use indexmap::IndexMap;
use rand::prelude::*;

use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use cuprate_p2p_core::{services::ZoneSpecificPeerListEntryBase, NetZoneAddress, NetworkZone};
use cuprate_pruning::PruningSeed;
use cuprate_p2p_bucket::BucketMap;

#[cfg(test)]
pub(crate) mod tests;
Expand All @@ -16,7 +16,7 @@ pub(crate) mod tests;
#[derive(Debug)]
pub(crate) struct PeerList<Z: NetworkZone> {
/// The peers with their peer data.
pub peers: IndexMap<Z::Addr, ZoneSpecificPeerListEntryBase<Z::Addr>>,
pub peers: BucketMap<ZoneSpecificPeerListEntryBase<Z::Addr>, 8>,
/// An index of Pruning seed to address, so can quickly grab peers with the blocks
/// we want.
///
Expand All @@ -33,7 +33,7 @@ pub(crate) struct PeerList<Z: NetworkZone> {
impl<Z: NetworkZone> PeerList<Z> {
/// Creates a new peer list.
pub(crate) fn new(list: Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>) -> Self {
let mut peers = IndexMap::with_capacity(list.len());
let mut peers = BucketMap::<_, 8>::new();
let mut pruning_seeds = BTreeMap::new();
let mut ban_ids = HashMap::with_capacity(list.len());

Expand All @@ -48,7 +48,7 @@ impl<Z: NetworkZone> PeerList<Z> {
.or_insert_with(Vec::new)
.push(peer.adr);

peers.insert(peer.adr, peer);
peers.push(peer);
}
Self {
peers,
Expand All @@ -64,7 +64,7 @@ impl<Z: NetworkZone> PeerList<Z> {

/// Adds a new peer to the peer list
pub(crate) fn add_new_peer(&mut self, peer: ZoneSpecificPeerListEntryBase<Z::Addr>) {
if self.peers.insert(peer.adr, peer).is_none() {
if self.peers.push(peer).is_none() {
#[expect(clippy::unwrap_or_default, reason = "It's more clear with this")]
self.pruning_seeds
.entry(peer.pruning_seed)
Expand Down Expand Up @@ -94,7 +94,14 @@ impl<Z: NetworkZone> PeerList<Z> {
// Take a random peer and see if it's in the list of must_keep_peers, if it is try again.
// TODO: improve this

// Return early if no items
if self.peers.is_empty() {
return None
}

for _ in 0..3 {

// In case we require a specific height
if let Some(needed_height) = block_needed {
let (_, addresses_with_block) = self.pruning_seeds.iter().find(|(seed, _)| {
// TODO: factor in peer blockchain height?
Expand All @@ -109,18 +116,15 @@ impl<Z: NetworkZone> PeerList<Z> {
}

return self.remove_peer(&peer);
}
let len = self.len();

if len == 0 {
return None;
}

let n = r.gen_range(0..len);

let (&key, _) = self.peers.get_index(n).unwrap();
if !must_keep_peers.contains(&key) {
return self.remove_peer(&key);
}

// Straightforward if we don't need a specific height.
let random_peer = self.peers.get_random(r);
if let Some(peer) = random_peer {

if !must_keep_peers.contains(&peer.adr) {
return self.remove_peer(&peer.adr.clone())
}
}
}

Expand All @@ -132,26 +136,22 @@ impl<Z: NetworkZone> PeerList<Z> {
r: &mut R,
len: usize,
) -> Vec<ZoneSpecificPeerListEntryBase<Z::Addr>> {
let mut peers = self.peers.values().copied().choose_multiple(r, len);
// Order of the returned peers is not random, I am unsure of the impact of this, potentially allowing someone to make guesses about which peers
// were connected first.
// So to mitigate this shuffle the result.
peers.shuffle(r);
peers.drain(len.min(peers.len())..peers.len());
peers
(0..len)
.filter_map(|_| self.peers.get_random(r).copied())
.collect::<Vec<_>>()
}

/// Returns a mutable reference to a peer.
pub(crate) fn get_peer_mut(
&mut self,
peer: &Z::Addr,
peer_addr: &Z::Addr,
) -> Option<&mut ZoneSpecificPeerListEntryBase<Z::Addr>> {
self.peers.get_mut(peer)
self.peers.get_mut(peer_addr)
}

/// Returns true if the list contains this peer.
pub(crate) fn contains_peer(&self, peer: &Z::Addr) -> bool {
self.peers.contains_key(peer)
self.peers.contains(peer)
}

/// Removes a peer from the pruning idx
Expand Down Expand Up @@ -197,7 +197,7 @@ impl<Z: NetworkZone> PeerList<Z> {
&mut self,
peer: &Z::Addr,
) -> Option<ZoneSpecificPeerListEntryBase<Z::Addr>> {
let peer_eb = self.peers.swap_remove(peer)?;
let peer_eb = self.peers.remove(peer)?;
self.remove_peer_from_all_idxs(&peer_eb);
Some(peer_eb)
}
Expand Down Expand Up @@ -226,13 +226,13 @@ impl<Z: NetworkZone> PeerList<Z> {
let target_removed = self.len() - new_len;
let mut removed_count = 0;
let mut peers_to_remove: Vec<Z::Addr> = Vec::with_capacity(target_removed);

for peer_adr in self.peers.keys() {
if removed_count >= target_removed {
break;
}
if !must_keep_peers.contains(peer_adr) {
peers_to_remove.push(*peer_adr);
if !must_keep_peers.contains(&peer_adr) {
peers_to_remove.push(peer_adr);
removed_count += 1;
}
}
Expand Down
6 changes: 3 additions & 3 deletions p2p/address-book/src/peer_list/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn peer_list_reduce_length() {
#[test]
fn peer_list_reduce_length_with_peers_we_need() {
let mut peer_list = make_fake_peer_list(0, 500);
let must_keep_peers = peer_list.peers.keys().copied().collect::<HashSet<_>>();
let must_keep_peers = peer_list.peers.keys().collect::<HashSet<_>>();

let target_len = 49;

Expand All @@ -93,7 +93,7 @@ fn peer_list_remove_specific_peer() {
addrs.iter().for_each(|adr| assert_ne!(adr, &peer.adr));
}

assert!(!peers.contains_key(&peer.adr));
assert!(!peers.contains(&peer.adr));
}

#[test]
Expand Down Expand Up @@ -170,7 +170,7 @@ fn peer_list_ban_peers() {
let ban_id = peer.adr.ban_id();

assert_eq!(peer_list.ban_ids.get(&ban_id), None);
for (addr, _) in peer_list.peers {
for addr in peer_list.peers.keys() {
assert_ne!(addr.ban_id(), ban_id);
}
}
4 changes: 2 additions & 2 deletions p2p/address-book/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ mod tests {
assert_eq!(gray_list.peers.len(), gray_list_2.peers.len());

for addr in white_list.peers.keys() {
assert!(white_list_2.contains_peer(addr));
assert!(white_list_2.contains_peer(&addr));
}

for addr in gray_list.peers.keys() {
assert!(gray_list_2.contains_peer(addr));
assert!(gray_list_2.contains_peer(&addr));
}
}
}
Loading

0 comments on commit b3b6eaf

Please sign in to comment.