From e2b3ec29b3615a3d8eb2547d4bfa12a0a781bf5f Mon Sep 17 00:00:00 2001 From: D-Stacks <78099568+D-Stacks@users.noreply.github.com> Date: Tue, 12 Mar 2024 22:01:25 +0100 Subject: [PATCH 01/11] eviction_logic. --- Cargo.lock | 112 ++- Cargo.toml | 1 + components/addressmanager/src/lib.rs | 3 +- components/connectionmanager/Cargo.toml | 6 +- components/connectionmanager/src/eviction.rs | 818 +++++++++++++++++++ components/connectionmanager/src/lib.rs | 29 +- protocol/flows/src/v5/blockrelay/flow.rs | 4 +- protocol/flows/src/v5/txrelay/flow.rs | 5 +- protocol/p2p/src/core/peer.rs | 33 +- protocol/p2p/src/core/router.rs | 26 + utils/src/networking.rs | 65 +- 11 files changed, 1073 insertions(+), 29 deletions(-) create mode 100644 components/connectionmanager/src/eviction.rs diff --git a/Cargo.lock b/Cargo.lock index 2f2722165..2285aa60f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1277,6 +1277,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "downcast" version = "0.11.0" @@ -1737,6 +1743,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.6", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -2232,7 +2247,9 @@ dependencies = [ "log", "parking_lot", "rand 0.8.5", + "rv", "tokio", + "uuid 1.6.1", ] [[package]] @@ -3523,6 +3540,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "lru" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e7d46de488603ffdd5f30afbc64fbba2378214a2c3a2fb83abf3d33126df17" +dependencies = [ + "hashbrown 0.13.2", +] + [[package]] name = "lz4-sys" version = "1.9.4" @@ -3634,6 +3660,19 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "num_cpus", + "once_cell", + "rawpointer", + "thread-tree", +] + [[package]] name = "md-5" version = "0.10.6" @@ -3726,7 +3765,7 @@ dependencies = [ "alga", "approx", "generic-array 0.13.3", - "matrixmultiply", + "matrixmultiply 0.2.4", "num-complex 0.2.4", "num-rational 0.2.4", "num-traits", @@ -3768,7 +3807,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac06db03ec2f46ee0ecdca1a1c34a99c0d188a0d83439b84bf0cb4b386e4ab09" dependencies = [ - "matrixmultiply", + "matrixmultiply 0.2.4", "num-complex 0.2.4", "num-integer", "num-traits", @@ -4057,6 +4096,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "order-stat" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb" + [[package]] name = "ordered-float" version = "2.10.1" @@ -4163,6 +4208,30 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "peroxide" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703b5fbdc1f9018a66e2db8758633cec31d39ad3127bfd38c9b6ad510637519c" +dependencies = [ + "matrixmultiply 0.3.8", + "order-stat", + "peroxide-ad", + "puruspe", + "rand 0.8.5", + "rand_distr 0.4.3", +] + +[[package]] +name = "peroxide-ad" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6fba8ff3f40b67996f7c745f699babaa3e57ef5c8178ec999daf7eedc51dc8c" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "petgraph" version = "0.6.4" @@ -4386,6 +4455,12 @@ dependencies = [ "prost", ] +[[package]] +name = "puruspe" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6778a7ae74b21f07fc5b9d550b1fdc212d719ec76d03cd2940c41002247c8a" + [[package]] name = "quote" version = "1.0.33" @@ -4710,6 +4785,21 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +[[package]] +name = "rv" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a650cc227f4eb01b043fb7580097d6830c688a8f33cd9eabbced2026d11abf5" +dependencies = [ + "doc-comment", + "lru", + "num", + "peroxide", + "rand 0.8.5", + "rand_distr 0.4.3", + "special", +] + [[package]] name = "ryu" version = "1.0.16" @@ -5052,6 +5142,15 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd62203d74a728ae353b4d716fc2a80e8da881dfdf8bbc0c012d877a58c4030" +[[package]] +name = "special" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89cf0d71ae639fdd8097350bfac415a41aabf1d5ddd356295fdc95f09760382" +dependencies = [ + "libm", +] + [[package]] name = "spin" version = "0.9.8" @@ -5222,6 +5321,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "thread-tree" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbd370cb847953a25954d9f63e14824a36113f8c72eecf6eccef5dc4b45d630" +dependencies = [ + "crossbeam-channel", +] + [[package]] name = "time" version = "0.3.30" diff --git a/Cargo.toml b/Cargo.toml index 1791d1c55..789364ff0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -208,6 +208,7 @@ regex = "1.10.2" ripemd = { version = "0.1.3", default-features = false } rlimit = "0.10.1" rocksdb = "0.21.0" +rv = "0.16.4" secp256k1 = { version = "0.24.3", features = [ "global-context", "rand-std", diff --git a/components/addressmanager/src/lib.rs b/components/addressmanager/src/lib.rs index 85f9acb3e..4537a9945 100644 --- a/components/addressmanager/src/lib.rs +++ b/components/addressmanager/src/lib.rs @@ -436,8 +436,7 @@ mod address_store_with_cache { .iter() .filter(|(addr_key, _)| !exceptions.contains(addr_key)) .map(|(_, e)| { - let count = prefix_counter.entry(e.address.prefix_bucket()).or_insert(0); - *count += 1; + *prefix_counter.entry(e.address.prefix_bucket()).or_insert(0) += 1; (64f64.powf((MAX_CONNECTION_FAILED_COUNT + 1 - e.connection_failed_count) as f64), e.address) }) .unzip(); diff --git a/components/connectionmanager/Cargo.toml b/components/connectionmanager/Cargo.toml index 4033539e0..07c29873b 100644 --- a/components/connectionmanager/Cargo.toml +++ b/components/connectionmanager/Cargo.toml @@ -19,4 +19,8 @@ kaspa-utils.workspace = true log.workspace = true parking_lot.workspace = true rand.workspace = true -tokio.workspace = true \ No newline at end of file +tokio.workspace = true + +[dev-dependencies] +rv.workspace = true +uuid.workspace = true diff --git a/components/connectionmanager/src/eviction.rs b/components/connectionmanager/src/eviction.rs new file mode 100644 index 000000000..60a601594 --- /dev/null +++ b/components/connectionmanager/src/eviction.rs @@ -0,0 +1,818 @@ +use std::{cmp::Ordering, collections::HashMap}; + +use itertools::Itertools; +use kaspa_p2p_lib::Peer; +use kaspa_utils::networking::PrefixBucket; +use rand::{seq::SliceRandom, thread_rng, Rng}; + +/* +# Eviction Logic +This module contains the backbone for the logic of evicting peers from the peer list. +The logic is based on ranking peers, which are calculated based on various metrics. +The ranks are then used to filter and select the peers to be evicted. +The module also contains predefined constants, compare and weight strategy functions to be used in the eviction logic. +*/ + +/// constants +pub mod constants { + /// to be used as the ratio for "top performing" lowest ranked peers to retain during eviction. + pub const RETAIN_RATIO: f64 = 0.4; // inspired from btc +} + +/// Predefined compare strategy functions +pub mod cmp_strats { + use super::EvictionRanks; + use std::cmp::Ordering; + /// _**Note**: The lowest rank is the "best" rank, as ranks are organized from low ("good") to high ("bad")._ + #[inline] + pub fn by_lowest_rank(ranks1: &EvictionRanks, ranks2: &EvictionRanks) -> Ordering { + ranks1.lowest_rank().partial_cmp(&ranks2.lowest_rank()).unwrap() + } + + #[cfg(test)] + mod test { + use super::{by_lowest_rank, EvictionRanks}; + use std::cmp::Ordering; + + #[test] + fn test_by_lowest_rank() { + let ranks1 = EvictionRanks { + last_ping_duration: 0.0, + time_connected: 3.0, + last_block_transfer: 3.0, + last_tx_transfer: 3.0, + ip_prefix_bucket: 3.0, + }; + let ranks2 = EvictionRanks { + last_ping_duration: 1.0, + time_connected: 2.0, + last_block_transfer: 2.0, + last_tx_transfer: 2.0, + ip_prefix_bucket: 2.0, + }; + assert_eq!(by_lowest_rank(&ranks1, &ranks2), Ordering::Less); + assert_eq!(by_lowest_rank(&ranks2, &ranks1), Ordering::Greater); + + let ranks1 = EvictionRanks { + last_ping_duration: 0.0, + time_connected: 0.0, + last_block_transfer: 0.0, + last_tx_transfer: 0.0, + ip_prefix_bucket: 0.0, + }; + let ranks2 = EvictionRanks { + last_ping_duration: 0.0, + time_connected: 0.0, + last_block_transfer: 0.0, + last_tx_transfer: 0.0, + ip_prefix_bucket: 0.0, + }; + assert_eq!(by_lowest_rank(&ranks1, &ranks2), Ordering::Equal); + } + + //TODO: Add tests for the compare strategy functions + } +} + +/// Predefined weight strategy functions +pub mod weight_strats { + use super::EvictionRanks; + /// _**Note**: The highest rank is the "worst" rank, as ranks are organized from low ("good") to high ("bad")._ + #[inline] + pub fn by_highest_none_latency_rank(ranks: &EvictionRanks) -> f64 { + ranks.highest_none_latency_rank() + 1.0 // add 1 to avoid 0 weight + } + + #[cfg(test)] + mod test { + use super::{by_highest_none_latency_rank, EvictionRanks}; + + #[test] + fn test_by_highest_none_latency_rank() { + let ranks = EvictionRanks { + last_ping_duration: 0.0, + time_connected: 2.0, + last_block_transfer: 0.0, + last_tx_transfer: 0.0, + ip_prefix_bucket: 1.0, + }; + assert_eq!(by_highest_none_latency_rank(&ranks), 3.0); + + let ranks = EvictionRanks { + last_ping_duration: 0.0, + time_connected: 1.0, + last_block_transfer: 0.0, + last_tx_transfer: 0.0, + ip_prefix_bucket: 2.0, + }; + assert_eq!(by_highest_none_latency_rank(&ranks), 3.0); + + let ranks = EvictionRanks { + last_ping_duration: 1.0, + time_connected: 0.0, + last_block_transfer: 1.0, + last_tx_transfer: 1.0, + ip_prefix_bucket: 0.0, + }; + + assert_eq!(by_highest_none_latency_rank(&ranks), 1.0); + + let ranks = EvictionRanks { + last_ping_duration: 0.0, + time_connected: 1.0, + last_block_transfer: 0.0, + last_tx_transfer: 0.0, + ip_prefix_bucket: 1.0, + }; + + assert_eq!(by_highest_none_latency_rank(&ranks), 2.0); + } + } +} + +/// Holds Ranks used for eviction logic +/// +/// _**Note**:_ +/// +/// _1) Ranks are organized from low to high, the lower the rank, the better the peer's perf in that metric._ +/// +/// _2) A peer may hold a rank as a multiple of 0.5, due to tie breaks splitting the rank._ +#[derive(Default, Clone, Copy, PartialEq, Debug)] +pub struct EvictionRanks { + ip_prefix_bucket: f64, + time_connected: f64, + last_ping_duration: f64, + last_block_transfer: f64, + last_tx_transfer: f64, +} + +impl EvictionRanks { + /// Returns and defines an array of all ranks that are not latency based. + /// + /// _**Includes:** [`Self::time_connected`], and [`Self::ip_prefix_bucket`]._ + /// + /// _**Excludes:** [`Self::last_ping_duration`], [`Self::last_block_transfer`], and [`Self::last_tx_transfer`]._ + #[inline] + fn none_latency_ranks(&self) -> [f64; 2] { + [self.time_connected, self.ip_prefix_bucket] + } + + /// Returns and defines an array of all ranks in the struct. + /// + /// **Includes:** [`Self::last_ping_duration`], [`Self::time_connected`], [`Self::last_block_transfer`], [`Self::last_tx_transfer`], and [`Self::ip_prefix_bucket`]. + #[inline] + fn all_ranks(&self) -> [f64; 5] { + [self.last_ping_duration, self.time_connected, self.last_block_transfer, self.last_tx_transfer, self.ip_prefix_bucket] + } + + /// Returns the lowest rank of all ranks in the struct. + /// + /// Refer to [`Self::all_ranks`] for the ranks. + /// + /// _**Note**: The lowest rank is the "best" rank, as ranks are organized from low ("good") to high ("bad")._ + /// + /// _**Includes:** [`Self::last_ping_duration`], [`Self::time_connected`], [`Self::last_block_transfer`], [`Self::last_tx_transfer`], and [`Self::ip_prefix_bucket`]._ + #[inline] + pub fn lowest_rank(&self) -> f64 { + self.all_ranks().into_iter().reduce(move |a, b| a.min(b)).expect("expected at least one rank") + } + + /// Returns the highest rank of the non-latency ranks / variables. + /// + /// _**Note**: The highest rank is the "worst" rank, as ranks are organized from low ("good") to high ("bad")._ + /// + /// _**Includes:** [`Self::time_connected`], and [`Self::ip_prefix_bucket`]._ + /// + /// _**Excludes:** [`Self::last_ping_duration`], [`Self::last_block_transfer`], and [`Self::last_tx_transfer`]._ + #[inline] + pub fn highest_none_latency_rank(&self) -> f64 { + self.none_latency_ranks().into_iter().reduce(move |a, b| a.max(b)).expect("expected at least one rank") + } +} + +pub type EvictionIter<'a> = Box + 'a>; +pub type PeerIter<'a> = Box + 'a>; +pub trait EvictionIterExt<'a> { + fn from_peers(peers: &'a [&'a Peer]) -> EvictionIter<'a>; + + fn filter_peers(self, amount: usize, compare_fn: F) -> EvictionIter<'a> + where + F: Fn(&EvictionRanks, &EvictionRanks) -> Ordering; + + fn select_peers_weighted(self, amount: usize, weight_fn: F) -> EvictionIter<'a> + where + F: Fn(&EvictionRanks) -> f64; + + fn iterate_peers(self) -> PeerIter<'a>; +} + +impl<'a> EvictionIterExt<'a> for EvictionIter<'a> { + fn from_peers(peers: &'a [&'a Peer]) -> EvictionIter<'a> { + let ip_prefix_map = build_ip_prefix_map(peers); + let mut ranks = vec![EvictionRanks::default(); peers.len()]; + Box::new(peers.iter().enumerate().map(move |(i1, p1)| { + for (i2, p2) in peers[i1..].iter().enumerate().skip(1) { + match ip_prefix_map[&p1.prefix_bucket()].cmp(&ip_prefix_map[&p2.prefix_bucket()]) { + // low is good, so we add rank to the peer with the greater ordering. + Ordering::Greater => ranks[i1].ip_prefix_bucket += 1.0, + Ordering::Less => ranks[i1 + i2].ip_prefix_bucket += 1.0, + Ordering::Equal => { + ranks[i1].ip_prefix_bucket += 0.5; + ranks[i1 + i2].ip_prefix_bucket += 0.5; + } + }; + + match p1.time_connected().cmp(&p2.time_connected()) { + // high is good, so we add to the peer with the lesser ordering. + Ordering::Greater => ranks[i1 + i2].time_connected += 1.0, + Ordering::Less => ranks[i1].time_connected += 1.0, + Ordering::Equal => { + ranks[i1].time_connected += 0.5; + ranks[i1 + i2].time_connected += 0.5; + } + }; + + match p1.last_ping_duration().cmp(&p2.last_ping_duration()) { + // low is good, so we add to the peer with the greater ordering. + Ordering::Greater => ranks[i1].last_ping_duration += 1.0, + Ordering::Less => ranks[i1 + i2].last_ping_duration += 1.0, + Ordering::Equal => { + ranks[i1].last_ping_duration += 0.5; + ranks[i1 + i2].last_ping_duration += 0.5; + } + }; + + match (p1.last_block_transfer(), p2.last_block_transfer()) { + // Some is good, so we add to the peer with None + (Some(_), None) => ranks[i1 + i2].last_block_transfer += 1.0, + (None, Some(_)) => ranks[i1].last_block_transfer += 1.0, + (None, None) => { + ranks[i1].last_block_transfer += 0.5; + ranks[i1 + i2].last_block_transfer += 0.5; + } + (Some(peer1_last_block_transfer), Some(peer2_last_block_transfer)) => { + match peer1_last_block_transfer.cmp(&peer2_last_block_transfer) { + // low is good, so we add to the peer with the greater ordering. + Ordering::Greater => ranks[i1].last_block_transfer += 1.0, + Ordering::Less => ranks[i1 + i2].last_block_transfer += 1.0, + Ordering::Equal => { + ranks[i1].last_block_transfer += 0.5; + ranks[i1 + i2].last_block_transfer += 0.5; + } + } + } + }; + + match (p1.last_tx_transfer(), p2.last_tx_transfer()) { + // Some is good, so we add to the peer with None + (Some(_), None) => ranks[i1 + i2].last_tx_transfer += 1.0, + (None, Some(_)) => ranks[i1].last_tx_transfer += 1.0, + (None, None) => { + ranks[i1].last_tx_transfer += 0.5; + ranks[i1 + i2].last_tx_transfer += 0.5; + } + (Some(peer1_last_tx_transfer), Some(peer2_last_tx_transfer)) => { + match peer1_last_tx_transfer.cmp(&peer2_last_tx_transfer) { + // low is good, so we add to the peer with the greater ordering. + Ordering::Greater => ranks[i1].last_tx_transfer += 1.0, + Ordering::Less => ranks[i1 + i2].last_tx_transfer += 1.0, + Ordering::Equal => { + ranks[i1].last_tx_transfer += 0.5; + ranks[i1 + i2].last_tx_transfer += 0.5; + } + } + } + }; + } + (peers[i1], ranks[i1]) + })) + } + + fn filter_peers(self, amount: usize, compare_fn: F) -> Self + where + F: Fn(&EvictionRanks, &EvictionRanks) -> Ordering, + { + let rng = &mut thread_rng(); + Box::new( + self.sorted_unstable_by(move |(_, r1), (_, r2)| match compare_fn(r1, r2) { + Ordering::Greater => Ordering::Greater, + Ordering::Less => Ordering::Less, + // we tie break randomly, as to not expose preference due to pre-existing ordering. + Ordering::Equal => { + if rng.gen_bool(0.5) { + Ordering::Greater + } else { + Ordering::Less + } + } + }) + .skip(amount), + ) + } + + fn select_peers_weighted(self, amount: usize, weight_fn: F) -> Self + where + F: Fn(&EvictionRanks) -> f64, + { + let rng = &mut thread_rng(); + Box::new( + self.collect_vec() + .choose_multiple_weighted(rng, amount, |(_, r)| weight_fn(r)) + .unwrap() + .copied() + .collect_vec() + .into_iter(), + ) + } + + fn iterate_peers(self) -> PeerIter<'a> { + Box::new(self.map(|(p, _)| p)) + } +} + +// Abstracted helper functions: + +fn build_ip_prefix_map(peers: &[&Peer]) -> HashMap { + let mut ip_prefix_map = HashMap::new(); + for peer in peers.iter() { + *ip_prefix_map.entry(peer.prefix_bucket()).or_insert(1) += 1; + } + ip_prefix_map +} + +#[cfg(test)] +mod test { + + use super::*; + + use kaspa_core::{debug, info, log::try_init_logger}; + use kaspa_p2p_lib::Peer; + use kaspa_utils::networking::PeerId; + use std::net::SocketAddr; + use std::{ + net::SocketAddrV4, + str::FromStr, + time::{Duration, Instant}, + }; + use uuid::Uuid; + + fn build_test_peers() -> Vec { + let now = Instant::now(); + let instants = Vec::from_iter((0..10).map(|i| now.checked_sub(Duration::from_secs(i)).unwrap())); // `from_secs` is important here, as time_connected has ms granularity, so it most be greater granularity than ms. + // rank 0, 1, 2, 3, 5, => 0, 1 + let peer0 = Peer::new( + PeerId::from(Uuid::from_u128(0u128)), + SocketAddr::V4(SocketAddrV4::from_str("1.0.0.0:1").unwrap()), + Default::default(), + instants[8], + Default::default(), + 2, + Some(instants[4]), + Some(instants[3]), + ); + // rank 1.5, 0, 1, 2, 3 => 0, 1.5 + let peer1 = Peer::new( + PeerId::from(Uuid::from_u128(1u128)), + SocketAddr::V4(SocketAddrV4::from_str("2.0.0.0:1").unwrap()), + Default::default(), + instants[9], + Default::default(), + 1, + Some(instants[5]), + Some(instants[4]), + ); + // rank 1.5, 2, 0, 1, 2 => 0, 2 + let peer2 = Peer::new( + PeerId::from(Uuid::from_u128(2u128)), + SocketAddr::V4(SocketAddrV4::from_str("2.0.0.0:1").unwrap()), + Default::default(), + instants[7], + Default::default(), + 0, + Some(instants[6]), + Some(instants[5]), + ); + // rank 4, 3, 3, 0, 1 => 0, 4 + let peer3 = Peer::new( + PeerId::from(Uuid::from_u128(3u128)), + SocketAddr::V4(SocketAddrV4::from_str("3.0.0.0:1").unwrap()), + Default::default(), + instants[6], + Default::default(), + 3, + Some(instants[7]), + Some(instants[6]), + ); + // rank 4, 4, 4, 4, 0 => 0, 4 + let peer4 = Peer::new( + PeerId::from(Uuid::from_u128(4u128)), + SocketAddr::V4(SocketAddrV4::from_str("3.0.0.0:1").unwrap()), + Default::default(), + instants[5], + Default::default(), + 4, + Some(instants[3]), + Some(instants[7]), + ); + // rank 4, 5, 5, 5, 5 => 4, 5 + let peer5 = Peer::new( + PeerId::from(Uuid::from_u128(5u128)), + SocketAddr::V4(SocketAddrV4::from_str("3.0.0.0:1").unwrap()), + Default::default(), + instants[4], + Default::default(), + 5, + Some(instants[2]), + Some(instants[2]), + ); + // rank 7.5, 6, 6, 6, 8.5 => 6, 7.5 + let peer6 = Peer::new( + PeerId::from(Uuid::from_u128(6u128)), + SocketAddr::V4(SocketAddrV4::from_str("4.0.0.0:1").unwrap()), + Default::default(), + instants[3], + Default::default(), + 6, + Some(instants[1]), + None, + ); + // rank 7.5, 7, 7, 7, 8.5 => 7, 7.5 + let peer7 = Peer::new( + PeerId::from(Uuid::from_u128(7u128)), + SocketAddr::V4(SocketAddrV4::from_str("4.0.0.0:1").unwrap()), + Default::default(), + instants[2], + Default::default(), + 7, + Some(instants[0]), + None, + ); + // rank 7.5, 8, 8, 8.5, 6 => 6, 8 + let peer8 = Peer::new( + PeerId::from(Uuid::from_u128(8u128)), + SocketAddr::V4(SocketAddrV4::from_str("4.0.0.0:1").unwrap()), + Default::default(), + instants[1], + Default::default(), + 8, + None, + Some(instants[1]), + ); + // rank 7.5, 9, 9, 8.5, 7 => 7, 9 + let peer9 = Peer::new( + PeerId::from(Uuid::from_u128(9u128)), + SocketAddr::V4(SocketAddrV4::from_str("4.0.0.0:1").unwrap()), + Default::default(), + instants[0], + Default::default(), + 9, + None, + Some(instants[0]), + ); + + vec![peer0, peer1, peer2, peer3, peer4, peer5, peer6, peer7, peer8, peer9] + } + + #[test] + fn test_eviction_ranks() { + let ranks = EvictionRanks { + ip_prefix_bucket: 4.0, + time_connected: 1.0, + last_ping_duration: 0.0, + last_block_transfer: 2.0, + last_tx_transfer: 3.0, + }; + assert_eq!(ranks.lowest_rank(), 0.0); + assert_eq!(ranks.highest_none_latency_rank(), 4.0); + + let ranks = EvictionRanks { + ip_prefix_bucket: 3.0, + time_connected: 0.0, + last_ping_duration: 4.0, + last_block_transfer: 1.0, + last_tx_transfer: 2.0, + }; + assert_eq!(ranks.lowest_rank(), 0.0); + assert_eq!(ranks.highest_none_latency_rank(), 3.0); + + let ranks = EvictionRanks { + ip_prefix_bucket: 2.0, + time_connected: 4.0, + last_ping_duration: 3.0, + last_block_transfer: 0.0, + last_tx_transfer: 1.0, + }; + assert_eq!(ranks.lowest_rank(), 0.0); + assert_eq!(ranks.highest_none_latency_rank(), 4.0); + + let ranks = EvictionRanks { + ip_prefix_bucket: 1.0, + time_connected: 3.0, + last_ping_duration: 2.0, + last_block_transfer: 4.0, + last_tx_transfer: 0.0, + }; + assert_eq!(ranks.lowest_rank(), 0.0); + assert_eq!(ranks.highest_none_latency_rank(), 3.0); + + let ranks = EvictionRanks { + ip_prefix_bucket: 0.0, + time_connected: 2.0, + last_ping_duration: 1.0, + last_block_transfer: 3.0, + last_tx_transfer: 4.0, + }; + assert_eq!(ranks.lowest_rank(), 0.0); + assert_eq!(ranks.highest_none_latency_rank(), 2.0); + } + + #[test] + fn test_eviction_iter_from_peers() { + let test_peers = build_test_peers(); + let test_peers = test_peers.iter().collect::>(); + let eviction_iter_vec = EvictionIter::from_peers(&test_peers).collect::>(); + + let expected_ranks = vec![ + EvictionRanks { + ip_prefix_bucket: 0.0, + time_connected: 1.0, + last_ping_duration: 2.0, + last_block_transfer: 3.0, + last_tx_transfer: 4.0, + }, + EvictionRanks { + ip_prefix_bucket: 1.5, + time_connected: 0.0, + last_ping_duration: 1.0, + last_block_transfer: 2.0, + last_tx_transfer: 3.0, + }, + EvictionRanks { + ip_prefix_bucket: 1.5, + time_connected: 2.0, + last_ping_duration: 0.0, + last_block_transfer: 1.0, + last_tx_transfer: 2.0, + }, + EvictionRanks { + ip_prefix_bucket: 4.0, + time_connected: 3.0, + last_ping_duration: 3.0, + last_block_transfer: 0.0, + last_tx_transfer: 1.0, + }, + EvictionRanks { + ip_prefix_bucket: 4.0, + time_connected: 4.0, + last_ping_duration: 4.0, + last_block_transfer: 4.0, + last_tx_transfer: 0.0, + }, + EvictionRanks { + ip_prefix_bucket: 4.0, + time_connected: 5.0, + last_ping_duration: 5.0, + last_block_transfer: 5.0, + last_tx_transfer: 5.0, + }, + EvictionRanks { + ip_prefix_bucket: 7.5, + time_connected: 6.0, + last_ping_duration: 6.0, + last_block_transfer: 6.0, + last_tx_transfer: 8.5, + }, + EvictionRanks { + ip_prefix_bucket: 7.5, + time_connected: 7.0, + last_ping_duration: 7.0, + last_block_transfer: 7.0, + last_tx_transfer: 8.5, + }, + EvictionRanks { + ip_prefix_bucket: 7.5, + time_connected: 8.0, + last_ping_duration: 8.0, + last_block_transfer: 8.5, + last_tx_transfer: 6.0, + }, + EvictionRanks { + ip_prefix_bucket: 7.5, + time_connected: 9.0, + last_ping_duration: 9.0, + last_block_transfer: 8.5, + last_tx_transfer: 7.0, + }, + ]; + + assert_eq!(eviction_iter_vec.len(), expected_ranks.len()); + for (i, (_, ranks)) in eviction_iter_vec.iter().enumerate() { + assert_eq!(ranks, &expected_ranks[i]); + } + } + + #[test] + fn test_eviction_iter_filter_peers() { + let test_peers = build_test_peers(); + let test_peers = test_peers.iter().collect::>(); + let iterations = test_peers.len(); + let eviction_iter_vec = EvictionIter::from_peers(&test_peers).collect::>(); + + for i in 0..iterations + 1 { + let mut removed_counter = HashMap::::new(); + let mut filtered_counter = HashMap::::new(); + let eviction_candidates_iter = Box::new(eviction_iter_vec.clone().into_iter()) as EvictionIter; + let filtered_eviction_set = eviction_candidates_iter.filter_peers(i, cmp_strats::by_lowest_rank).collect_vec(); + let removed_eviction_set = + eviction_iter_vec.clone().into_iter().filter(|item| !filtered_eviction_set.contains(item)).collect_vec(); + assert_eq!(filtered_eviction_set.len(), iterations - i); + assert_eq!(removed_eviction_set.len(), i); + for (_, er) in &removed_eviction_set { + *removed_counter.entry(er.lowest_rank().to_bits()).or_insert(0) += 1; + } + for (_, er) in &filtered_eviction_set { + *filtered_counter.entry(er.lowest_rank().to_bits()).or_insert(0) += 1; + } + match i { + 0 => { + assert_eq!(removed_counter.len(), 0); + + assert_eq!(filtered_counter[&0.0_f64.to_bits()], 5); + assert_eq!(filtered_counter[&4.0_f64.to_bits()], 1); + assert_eq!(filtered_counter[&6.0_f64.to_bits()], 2); + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 4); + } + 1 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 1); + assert_eq!(removed_counter.len(), 1); + + assert_eq!(filtered_counter[&0.0_f64.to_bits()], 4); + assert_eq!(filtered_counter[&4.0_f64.to_bits()], 1); + assert_eq!(filtered_counter[&6.0_f64.to_bits()], 2); + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 4); + } + 2 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 2); + assert_eq!(removed_counter.len(), 1); + + assert_eq!(filtered_counter[&0.0_f64.to_bits()], 3); + assert_eq!(filtered_counter[&4.0_f64.to_bits()], 1); + assert_eq!(filtered_counter[&6.0_f64.to_bits()], 2); + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 4); + } + 3 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 3); + assert_eq!(removed_counter.len(), 1); + + assert_eq!(filtered_counter[&0.0_f64.to_bits()], 2); + assert_eq!(filtered_counter[&4.0_f64.to_bits()], 1); + assert_eq!(filtered_counter[&6.0_f64.to_bits()], 2); + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 4); + } + 4 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 4); + assert_eq!(removed_counter.len(), 1); + + assert_eq!(filtered_counter[&0.0_f64.to_bits()], 1); + assert_eq!(filtered_counter[&4.0_f64.to_bits()], 1); + assert_eq!(filtered_counter[&6.0_f64.to_bits()], 2); + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 4); + } + 5 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 5); + assert_eq!(removed_counter.len(), 1); + + assert_eq!(filtered_counter[&4.0_f64.to_bits()], 1); + assert_eq!(filtered_counter[&6.0_f64.to_bits()], 2); + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 3); + } + 6 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 5); + assert_eq!(removed_counter[&4.0_f64.to_bits()], 1); + assert_eq!(removed_counter.len(), 2); + + assert_eq!(filtered_counter[&6.0_f64.to_bits()], 2); + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 2); + } + 7 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 5); + assert_eq!(removed_counter[&4.0_f64.to_bits()], 1); + assert_eq!(removed_counter[&6.0_f64.to_bits()], 1); + assert_eq!(removed_counter.len(), 3); + + assert_eq!(filtered_counter[&6.0_f64.to_bits()], 1); + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 2); + } + 8 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 5); + assert_eq!(removed_counter[&4.0_f64.to_bits()], 1); + assert_eq!(removed_counter[&6.0_f64.to_bits()], 2); + assert_eq!(removed_counter.len(), 3); + + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 2); + assert_eq!(filtered_counter.len(), 1); + } + 9 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 5); + assert_eq!(removed_counter[&4.0_f64.to_bits()], 1); + assert_eq!(removed_counter[&6.0_f64.to_bits()], 2); + assert_eq!(removed_counter[&7.0_f64.to_bits()], 1); + assert_eq!(removed_counter.len(), 4); + + assert_eq!(filtered_counter[&7.0_f64.to_bits()], 1); + assert_eq!(filtered_counter.len(), 1); + } + 10 => { + assert_eq!(removed_counter[&0.0_f64.to_bits()], 5); + assert_eq!(removed_counter[&4.0_f64.to_bits()], 1); + assert_eq!(removed_counter[&6.0_f64.to_bits()], 2); + assert_eq!(removed_counter[&7.0_f64.to_bits()], 2); + assert_eq!(removed_counter.len(), 4); + + assert_eq!(filtered_counter.len(), 0); + } + _ => panic!("unexpected i value"), + } + } + } + + #[test] + fn test_eviction_iter_select_peers_weighted() { + try_init_logger("info"); + let test_peers = build_test_peers(); + let test_peers = test_peers.iter().collect::>(); + let eviction_iter_vec = EvictionIter::from_peers(&test_peers).collect::>(); + let total_weight = 59.5; + let expected_probabilities = vec![ + // we add one to avoid 0, and nan numbers.. `weight_strats::by_highest_none_latency_rank` adds 1 to the rank for these hypothetical situation. + (1.0 + 1.0) / total_weight, + (1.5 + 1.0) / total_weight, + (2.0 + 1.0) / total_weight, + (4.0 + 1.0) / total_weight * 2.0, // we have two 4.0 ranks + (5.0 + 1.0) / total_weight, + (7.5 + 1.0) / total_weight * 2.0, // we have two 7.5 ranks + (8.0 + 1.0) / total_weight, + (9.0 + 1.0) / total_weight, + ]; + assert_eq!(expected_probabilities.iter().sum::(), 1.0); + assert_eq!(expected_probabilities.len(), 8); + + let mut selected_counter = HashMap::::new(); + let num_of_trials = 2054; + for _ in 0..num_of_trials { + //println!("sample_size: {}", sample_size); + let eviction_iter = Box::new(eviction_iter_vec.clone().into_iter()) as EvictionIter; + let selected_eviction_set = + eviction_iter.select_peers_weighted(1, weight_strats::by_highest_none_latency_rank).collect_vec(); + assert_eq!(selected_eviction_set.len(), 1); + for (_, er) in &selected_eviction_set { + let highest_none_latency_rank = er.highest_none_latency_rank(); + *selected_counter.entry(highest_none_latency_rank.to_bits()).or_insert(0.0) += 1.0; + } + } + let mut actual_probabilities = vec![0.0; expected_probabilities.len()]; + for (rank, count) in selected_counter { + let rank = f64::from_bits(rank); + if rank == 1.0 { + actual_probabilities[0] = count / num_of_trials as f64; + } else if rank == 1.5 { + actual_probabilities[1] = count / num_of_trials as f64; + } else if rank == 2.0 { + actual_probabilities[2] = count / num_of_trials as f64; + } else if rank == 4.0 { + actual_probabilities[3] = count / num_of_trials as f64; + } else if rank == 5.0 { + actual_probabilities[4] = count / num_of_trials as f64; + } else if rank == 7.5 { + actual_probabilities[5] = count / num_of_trials as f64; + } else if rank == 8.0 { + actual_probabilities[6] = count / num_of_trials as f64; + } else if rank == 9.0 { + actual_probabilities[7] = count / num_of_trials as f64; + } else { + panic!("unexpected rank value: {}", rank); + } + } + debug!("expected_probabilities: \n {:?}", expected_probabilities); + debug!("actual_probabilities: \n {:?}", actual_probabilities); + let p = 1.0 + - rv::misc::ks_two_sample( + &expected_probabilities, + &actual_probabilities, + rv::misc::KsMode::Exact, + rv::misc::KsAlternative::TwoSided, + ) + .unwrap() + .1; + assert!(p < 0.05); + info!("Kolmogorov–Smirnov test result for `EvictionIter.select_peers_weighted`: p = {0:.3}, p < 0.5", p); + } +} diff --git a/components/connectionmanager/src/lib.rs b/components/connectionmanager/src/lib.rs index 1509df6bf..183fd673d 100644 --- a/components/connectionmanager/src/lib.rs +++ b/components/connectionmanager/src/lib.rs @@ -1,3 +1,6 @@ +mod eviction; +use eviction::{cmp_strats, constants::RETAIN_RATIO, weight_strats, EvictionIter, EvictionIterExt}; + use std::{ cmp::min, collections::{HashMap, HashSet}, @@ -243,8 +246,30 @@ impl ConnectionManager { return; } - let mut futures = Vec::with_capacity(active_inbound_len - self.inbound_limit); - for peer in active_inbound.choose_multiple(&mut thread_rng(), active_inbound_len - self.inbound_limit) { + let peer_overflow_amount = active_inbound_len - self.inbound_limit; + + let mut futures = Vec::with_capacity(peer_overflow_amount); + + // the following peer selection strategy is designed to ensure that an eclipse attacker most outperform + // the best performing peers in any independent metric in order to perform a total eclipse. + // while keeping a bias to disconnect from newer peers, and those with concentrated prefix buckets. + for peer in EvictionIter::from_peers(&active_inbound) + .filter_peers( + // We retain a number of peers proportional to the inbound limit. + (self.inbound_limit as f64 / RETAIN_RATIO.floor()) as usize, + // Based on their lowest (i.e. best performing) independent rank. + cmp_strats::by_lowest_rank, + ) + .select_peers_weighted( + // then we select the overflowing amount from the remaining peers, + peer_overflow_amount, + // weighted by their highest (i.e. worst performing) none-latency rank. + // we only select by none latency as to ensure that we do not overly penalize disadvantaged (in terms of latency) peers. + // this strategy also slows down flooding (via time connected weighting), and multiple inbounds from a localized origin (via prefix bucket weighting). + weight_strats::by_highest_none_latency_rank, + ) + .iterate_peers() + { debug!("Disconnecting from {} because we're above the inbound limit", peer.net_address()); futures.push(self.p2p_adaptor.terminate(peer.key())); } diff --git a/protocol/flows/src/v5/blockrelay/flow.rs b/protocol/flows/src/v5/blockrelay/flow.rs index 49353c286..a5d8c2e9e 100644 --- a/protocol/flows/src/v5/blockrelay/flow.rs +++ b/protocol/flows/src/v5/blockrelay/flow.rs @@ -14,7 +14,7 @@ use kaspa_p2p_lib::{ IncomingRoute, Router, SharedIncomingRoute, }; use kaspa_utils::channel::{JobSender, JobTrySendError as TrySendError}; -use std::{collections::VecDeque, sync::Arc}; +use std::{collections::VecDeque, sync::Arc, time::Instant}; pub struct RelayInvMessage { hash: Hash, @@ -91,6 +91,7 @@ impl HandleRelayInvsFlow { loop { // Loop over incoming block inv messages let inv = self.invs_route.dequeue().await?; + let last_block_transfer = Instant::now(); let session = self.ctx.consensus().unguarded_session(); match session.async_get_block_status(inv.hash).await { @@ -188,6 +189,7 @@ impl HandleRelayInvsFlow { Err(rule_error) => return Err(rule_error.into()), }; + self.router.set_last_block_transfer(last_block_transfer); // As a policy, we only relay blocks who stand a chance to enter past(virtual). // The only mining rule which permanently excludes a block is the merge depth bound // (as opposed to "max parents" and "mergeset size limit" rules) diff --git a/protocol/flows/src/v5/txrelay/flow.rs b/protocol/flows/src/v5/txrelay/flow.rs index b824872bf..fa437ccbb 100644 --- a/protocol/flows/src/v5/txrelay/flow.rs +++ b/protocol/flows/src/v5/txrelay/flow.rs @@ -21,7 +21,7 @@ use kaspa_p2p_lib::{ pb::{kaspad_message::Payload, RequestTransactionsMessage, TransactionNotFoundMessage}, IncomingRoute, Router, }; -use std::sync::Arc; +use std::{sync::Arc, time::Instant}; use tokio::time::timeout; pub(crate) const MAX_TPS_THRESHOLD: u64 = 3000; @@ -201,6 +201,7 @@ impl RelayTransactionsFlow { requests: Vec>, should_throttle: bool, ) -> Result<(), ProtocolError> { + let last_transactions_transfer = Instant::now(); let mut transactions: Vec = Vec::with_capacity(requests.len()); for request in requests { let response = self.read_response().await?; @@ -249,6 +250,8 @@ impl RelayTransactionsFlow { ) .await; + self.router.set_last_tx_transfer(last_transactions_transfer); + Ok(()) } } diff --git a/protocol/p2p/src/core/peer.rs b/protocol/p2p/src/core/peer.rs index 90b52e9ee..5dc0d941d 100644 --- a/protocol/p2p/src/core/peer.rs +++ b/protocol/p2p/src/core/peer.rs @@ -1,8 +1,8 @@ use kaspa_consensus_core::subnets::SubnetworkId; -use kaspa_utils::networking::{IpAddress, PeerId}; +use kaspa_utils::networking::{IpAddress, PeerId, PrefixBucket}; use std::{fmt::Display, net::SocketAddr, sync::Arc, time::Instant}; -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, Hash, PartialEq, Eq)] pub struct PeerProperties { pub user_agent: String, // TODO: add services @@ -13,7 +13,7 @@ pub struct PeerProperties { pub time_offset: i64, } -#[derive(Debug)] +#[derive(Debug, Eq, PartialEq, Hash)] pub struct Peer { identity: PeerId, net_address: SocketAddr, @@ -21,6 +21,8 @@ pub struct Peer { connection_started: Instant, properties: Arc, last_ping_duration: u64, + last_block_transfer: Option, // TODO: add this to rpc, currently sidelined due to ongoing RPC development + last_tx_transfer: Option, // TODO: add this to rpc, currently sidelined due to ongoing RPC development } impl Peer { @@ -31,8 +33,19 @@ impl Peer { connection_started: Instant, properties: Arc, last_ping_duration: u64, + last_block_transfer: Option, + last_tx_transfer: Option, ) -> Self { - Self { identity, net_address, is_outbound, connection_started, properties, last_ping_duration } + Self { + identity, + net_address, + is_outbound, + connection_started, + properties, + last_ping_duration, + last_block_transfer, + last_tx_transfer, + } } /// Internal identity of this peer @@ -45,6 +58,10 @@ impl Peer { self.net_address } + pub fn prefix_bucket(&self) -> PrefixBucket { + self.net_address.ip().into() + } + pub fn key(&self) -> PeerKey { self.into() } @@ -65,6 +82,14 @@ impl Peer { pub fn last_ping_duration(&self) -> u64 { self.last_ping_duration } + + pub fn last_block_transfer(&self) -> Option { + self.last_block_transfer + } + + pub fn last_tx_transfer(&self) -> Option { + self.last_tx_transfer + } } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] diff --git a/protocol/p2p/src/core/router.rs b/protocol/p2p/src/core/router.rs index 6cd63bb14..83acf2674 100644 --- a/protocol/p2p/src/core/router.rs +++ b/protocol/p2p/src/core/router.rs @@ -102,6 +102,14 @@ struct RouterMutableState { /// Duration of the last ping to this peer last_ping_duration: u64, + + /// Time of the last block transfer + /// This corresponds to the last full block transfer, not the last Block Invoice message. + last_block_transfer: Option, + + /// Time of the last transaction transfer + /// This corresponds to the last full transaction(s) transfer(ed), not the last Transaction Invoice message. + last_tx_transfer: Option, } impl RouterMutableState { @@ -162,6 +170,8 @@ impl From<&Router> for Peer { router.connection_started, router.properties(), router.last_ping_duration(), + router.last_block_transfer(), + router.last_tx_transfer(), ) } } @@ -290,10 +300,26 @@ impl Router { self.mutable_state.lock().last_ping_duration = last_ping_duration; } + pub fn set_last_block_transfer(&self, last_block_transfer: Instant) { + self.mutable_state.lock().last_block_transfer = Some(last_block_transfer); + } + + pub fn set_last_tx_transfer(&self, last_tx_transfer: Instant) { + self.mutable_state.lock().last_tx_transfer = Some(last_tx_transfer); + } + pub fn last_ping_duration(&self) -> u64 { self.mutable_state.lock().last_ping_duration } + pub fn last_block_transfer(&self) -> Option { + self.mutable_state.lock().last_block_transfer + } + + pub fn last_tx_transfer(&self) -> Option { + self.mutable_state.lock().last_tx_transfer + } + pub fn incoming_flow_baseline_channel_size() -> usize { 256 } diff --git a/utils/src/networking.rs b/utils/src/networking.rs index cb1d26208..8e4dc471e 100644 --- a/utils/src/networking.rs +++ b/utils/src/networking.rs @@ -17,34 +17,62 @@ use uuid::Uuid; pub struct PrefixBucket(u64); impl PrefixBucket { + #[inline] + /// get ip prefix encoded as u64 value pub fn as_u64(&self) -> u64 { self.0 } } -impl From<&IpAddress> for PrefixBucket { - fn from(ip_address: &IpAddress) -> Self { - match ip_address.0 { - IpAddr::V4(ipv4) => { - let prefix_bytes = ipv4.octets(); - Self(u64::from_be_bytes([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, prefix_bytes[0], prefix_bytes[1]])) - } +impl From for PrefixBucket { + #[inline] + fn from(ipv4: Ipv4Addr) -> Self { + Self(u64::from_be_bytes([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, ipv4.octets()[0], ipv4.octets()[1]])) + } +} + +impl From for PrefixBucket { + #[inline] + fn from(ipv6: Ipv6Addr) -> Self { + // ipv6 prefix is the first 8 octets, hostnetwork + subnet + Self(u64::from_be_bytes(ipv6.octets().as_slice()[..8].try_into().expect("Slice with incorrect length"))) + } +} + +impl From for PrefixBucket { + #[inline] + fn from(ip: IpAddr) -> Self { + match ip { + IpAddr::V4(ipv4) => Self::from(ipv4), IpAddr::V6(ipv6) => { if let Some(ipv4) = ipv6.to_ipv4() { - let prefix_bytes = ipv4.octets(); - Self(u64::from_be_bytes([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, prefix_bytes[0], prefix_bytes[1]])) + Self::from(ipv4) } else { - // Else use first 8 bytes (routing prefix + subnetwork id) of ipv6 - Self(u64::from_be_bytes(ipv6.octets().as_slice()[..8].try_into().expect("Slice with incorrect length"))) + Self::from(ipv6) } } } } } -impl From<&NetAddress> for PrefixBucket { - fn from(net_address: &NetAddress) -> Self { - Self::from(&net_address.ip) +impl From for PrefixBucket { + #[inline] + fn from(ip_address: IpAddress) -> Self { + Self::from(ip_address.0) + } +} + +impl From for PrefixBucket { + #[inline] + fn from(net_address: NetAddress) -> Self { + Self::from(net_address.ip) + } +} + +impl From for PrefixBucket { + #[inline] + fn from(socket_addr: SocketAddr) -> Self { + Self::from(socket_addr.ip()) } } @@ -103,27 +131,32 @@ impl IpAddress { true } + #[inline] pub fn prefix_bucket(&self) -> PrefixBucket { - PrefixBucket::from(self) + PrefixBucket::from(self.0) } } impl From for IpAddress { + #[inline] fn from(ip: IpAddr) -> Self { Self(ip) } } impl From for IpAddress { + #[inline] fn from(value: Ipv4Addr) -> Self { Self(value.into()) } } impl From for IpAddress { + #[inline] fn from(value: Ipv6Addr) -> Self { Self(value.into()) } } impl From for IpAddr { + #[inline] fn from(value: IpAddress) -> Self { value.0 } @@ -226,7 +259,7 @@ impl NetAddress { } pub fn prefix_bucket(&self) -> PrefixBucket { - PrefixBucket::from(self) + PrefixBucket::from(self.ip) } } From ada69ff2c16f3556e37b9fc45981cc740d589a60 Mon Sep 17 00:00:00 2001 From: D-Stacks <78099568+D-Stacks@users.noreply.github.com> Date: Wed, 13 Mar 2024 01:24:14 +0100 Subject: [PATCH 02/11] address point 2 and 3 of reveiw. --- Cargo.lock | 56 ++++++++++++++++++++++++- components/connectionmanager/src/lib.rs | 4 +- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 29641baca..72a2b473c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3331,9 +3331,11 @@ dependencies = [ "num_cpus", "rand 0.8.5", "rayon", + "serde", "tempfile", "thiserror", "tokio", + "toml 0.8.11", "workflow-log", ] @@ -4366,7 +4368,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] @@ -4973,6 +4975,15 @@ dependencies = [ "syn 2.0.49", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_yaml" version = "0.8.26" @@ -5493,6 +5504,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tonic" version = "0.10.2" @@ -6199,6 +6244,15 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + [[package]] name = "workflow-async-trait" version = "0.1.68" diff --git a/components/connectionmanager/src/lib.rs b/components/connectionmanager/src/lib.rs index 183fd673d..3d806acef 100644 --- a/components/connectionmanager/src/lib.rs +++ b/components/connectionmanager/src/lib.rs @@ -250,13 +250,13 @@ impl ConnectionManager { let mut futures = Vec::with_capacity(peer_overflow_amount); - // the following peer selection strategy is designed to ensure that an eclipse attacker most outperform + // the following peer selection strategy is designed to ensure that an eclipse attacker must outperform // the best performing peers in any independent metric in order to perform a total eclipse. // while keeping a bias to disconnect from newer peers, and those with concentrated prefix buckets. for peer in EvictionIter::from_peers(&active_inbound) .filter_peers( // We retain a number of peers proportional to the inbound limit. - (self.inbound_limit as f64 / RETAIN_RATIO.floor()) as usize, + (self.inbound_limit as f64 / RETAIN_RATIO).floor() as usize, // Based on their lowest (i.e. best performing) independent rank. cmp_strats::by_lowest_rank, ) From fb779476fbc7248f4607c4f01427c0ffde56abbc Mon Sep 17 00:00:00 2001 From: max143672 Date: Wed, 13 Mar 2024 18:44:54 +0300 Subject: [PATCH 03/11] rework trait, make it more general, remove unnecessary boxing --- components/connectionmanager/src/eviction.rs | 239 +++++++++---------- components/connectionmanager/src/lib.rs | 5 +- 2 files changed, 113 insertions(+), 131 deletions(-) diff --git a/components/connectionmanager/src/eviction.rs b/components/connectionmanager/src/eviction.rs index 60a601594..32f8b64e0 100644 --- a/components/connectionmanager/src/eviction.rs +++ b/components/connectionmanager/src/eviction.rs @@ -190,146 +190,127 @@ impl EvictionRanks { } } -pub type EvictionIter<'a> = Box + 'a>; -pub type PeerIter<'a> = Box + 'a>; -pub trait EvictionIterExt<'a> { - fn from_peers(peers: &'a [&'a Peer]) -> EvictionIter<'a>; - - fn filter_peers(self, amount: usize, compare_fn: F) -> EvictionIter<'a> - where - F: Fn(&EvictionRanks, &EvictionRanks) -> Ordering; - - fn select_peers_weighted(self, amount: usize, weight_fn: F) -> EvictionIter<'a> - where - F: Fn(&EvictionRanks) -> f64; - - fn iterate_peers(self) -> PeerIter<'a>; -} - -impl<'a> EvictionIterExt<'a> for EvictionIter<'a> { - fn from_peers(peers: &'a [&'a Peer]) -> EvictionIter<'a> { - let ip_prefix_map = build_ip_prefix_map(peers); - let mut ranks = vec![EvictionRanks::default(); peers.len()]; - Box::new(peers.iter().enumerate().map(move |(i1, p1)| { - for (i2, p2) in peers[i1..].iter().enumerate().skip(1) { - match ip_prefix_map[&p1.prefix_bucket()].cmp(&ip_prefix_map[&p2.prefix_bucket()]) { - // low is good, so we add rank to the peer with the greater ordering. - Ordering::Greater => ranks[i1].ip_prefix_bucket += 1.0, - Ordering::Less => ranks[i1 + i2].ip_prefix_bucket += 1.0, - Ordering::Equal => { - ranks[i1].ip_prefix_bucket += 0.5; - ranks[i1 + i2].ip_prefix_bucket += 0.5; - } - }; - - match p1.time_connected().cmp(&p2.time_connected()) { - // high is good, so we add to the peer with the lesser ordering. - Ordering::Greater => ranks[i1 + i2].time_connected += 1.0, - Ordering::Less => ranks[i1].time_connected += 1.0, - Ordering::Equal => { - ranks[i1].time_connected += 0.5; - ranks[i1 + i2].time_connected += 0.5; - } - }; - - match p1.last_ping_duration().cmp(&p2.last_ping_duration()) { - // low is good, so we add to the peer with the greater ordering. - Ordering::Greater => ranks[i1].last_ping_duration += 1.0, - Ordering::Less => ranks[i1 + i2].last_ping_duration += 1.0, - Ordering::Equal => { - ranks[i1].last_ping_duration += 0.5; - ranks[i1 + i2].last_ping_duration += 0.5; - } - }; - - match (p1.last_block_transfer(), p2.last_block_transfer()) { - // Some is good, so we add to the peer with None - (Some(_), None) => ranks[i1 + i2].last_block_transfer += 1.0, - (None, Some(_)) => ranks[i1].last_block_transfer += 1.0, - (None, None) => { - ranks[i1].last_block_transfer += 0.5; - ranks[i1 + i2].last_block_transfer += 0.5; - } - (Some(peer1_last_block_transfer), Some(peer2_last_block_transfer)) => { - match peer1_last_block_transfer.cmp(&peer2_last_block_transfer) { - // low is good, so we add to the peer with the greater ordering. - Ordering::Greater => ranks[i1].last_block_transfer += 1.0, - Ordering::Less => ranks[i1 + i2].last_block_transfer += 1.0, - Ordering::Equal => { - ranks[i1].last_block_transfer += 0.5; - ranks[i1 + i2].last_block_transfer += 0.5; - } - } - } - }; - - match (p1.last_tx_transfer(), p2.last_tx_transfer()) { - // Some is good, so we add to the peer with None - (Some(_), None) => ranks[i1 + i2].last_tx_transfer += 1.0, - (None, Some(_)) => ranks[i1].last_tx_transfer += 1.0, - (None, None) => { - ranks[i1].last_tx_transfer += 0.5; - ranks[i1 + i2].last_tx_transfer += 0.5; - } - (Some(peer1_last_tx_transfer), Some(peer2_last_tx_transfer)) => { - match peer1_last_tx_transfer.cmp(&peer2_last_tx_transfer) { - // low is good, so we add to the peer with the greater ordering. - Ordering::Greater => ranks[i1].last_tx_transfer += 1.0, - Ordering::Less => ranks[i1 + i2].last_tx_transfer += 1.0, - Ordering::Equal => { - ranks[i1].last_tx_transfer += 0.5; - ranks[i1 + i2].last_tx_transfer += 0.5; - } - } - } - }; - } - (peers[i1], ranks[i1]) - })) - } - - fn filter_peers(self, amount: usize, compare_fn: F) -> Self +pub trait EvictionIterExt<'a, T: Iterator + 'a>: IntoIterator{ + fn filter_peers(self, amount: usize, compare_fn: F) -> impl Iterator + 'a where F: Fn(&EvictionRanks, &EvictionRanks) -> Ordering, + Self: Sized, { let rng = &mut thread_rng(); - Box::new( - self.sorted_unstable_by(move |(_, r1), (_, r2)| match compare_fn(r1, r2) { - Ordering::Greater => Ordering::Greater, - Ordering::Less => Ordering::Less, - // we tie break randomly, as to not expose preference due to pre-existing ordering. - Ordering::Equal => { - if rng.gen_bool(0.5) { - Ordering::Greater - } else { - Ordering::Less - } + self.into_iter().sorted_unstable_by(move |(_, r1), (_, r2)| match compare_fn(r1, r2) { + Ordering::Greater => Ordering::Greater, + Ordering::Less => Ordering::Less, + // we tie break randomly, as to not expose preference due to pre-existing ordering. + Ordering::Equal => { + if rng.gen_bool(0.5) { + Ordering::Greater + } else { + Ordering::Less } - }) - .skip(amount), - ) + } + }) + .skip(amount) } - fn select_peers_weighted(self, amount: usize, weight_fn: F) -> Self + fn select_peers_weighted(self, amount: usize, weight_fn: F) -> impl Iterator + 'a where F: Fn(&EvictionRanks) -> f64, + Self: Sized, { let rng = &mut thread_rng(); - Box::new( - self.collect_vec() - .choose_multiple_weighted(rng, amount, |(_, r)| weight_fn(r)) - .unwrap() - .copied() - .collect_vec() - .into_iter(), - ) + self.into_iter().collect_vec().choose_multiple_weighted(rng, amount, |(_, r)| weight_fn(r)).unwrap().copied().collect_vec().into_iter() } - fn iterate_peers(self) -> PeerIter<'a> { - Box::new(self.map(|(p, _)| p)) + fn iterate_peers(self) -> impl Iterator + 'a + where + Self: Sized, + { + self.into_iter().map(|(p, _)| p) } } +impl<'a, T: Iterator + 'a, IntoIter: IntoIterator> EvictionIterExt<'a, T> for IntoIter {} + +pub fn from_peers<'a>(peers: &'a [&'a Peer]) -> impl Iterator + 'a { + let ip_prefix_map = build_ip_prefix_map(peers); + let mut ranks = vec![EvictionRanks::default(); peers.len()]; + Box::new(peers.iter().enumerate().map(move |(i1, p1)| { + for (i2, p2) in peers[i1..].iter().enumerate().skip(1) { + match ip_prefix_map[&p1.prefix_bucket()].cmp(&ip_prefix_map[&p2.prefix_bucket()]) { + // low is good, so we add rank to the peer with the greater ordering. + Ordering::Greater => ranks[i1].ip_prefix_bucket += 1.0, + Ordering::Less => ranks[i1 + i2].ip_prefix_bucket += 1.0, + Ordering::Equal => { + ranks[i1].ip_prefix_bucket += 0.5; + ranks[i1 + i2].ip_prefix_bucket += 0.5; + } + }; + + match p1.time_connected().cmp(&p2.time_connected()) { + // high is good, so we add to the peer with the lesser ordering. + Ordering::Greater => ranks[i1 + i2].time_connected += 1.0, + Ordering::Less => ranks[i1].time_connected += 1.0, + Ordering::Equal => { + ranks[i1].time_connected += 0.5; + ranks[i1 + i2].time_connected += 0.5; + } + }; + + match p1.last_ping_duration().cmp(&p2.last_ping_duration()) { + // low is good, so we add to the peer with the greater ordering. + Ordering::Greater => ranks[i1].last_ping_duration += 1.0, + Ordering::Less => ranks[i1 + i2].last_ping_duration += 1.0, + Ordering::Equal => { + ranks[i1].last_ping_duration += 0.5; + ranks[i1 + i2].last_ping_duration += 0.5; + } + }; + + match (p1.last_block_transfer(), p2.last_block_transfer()) { + // Some is good, so we add to the peer with None + (Some(_), None) => ranks[i1 + i2].last_block_transfer += 1.0, + (None, Some(_)) => ranks[i1].last_block_transfer += 1.0, + (None, None) => { + ranks[i1].last_block_transfer += 0.5; + ranks[i1 + i2].last_block_transfer += 0.5; + } + (Some(peer1_last_block_transfer), Some(peer2_last_block_transfer)) => { + match peer1_last_block_transfer.cmp(&peer2_last_block_transfer) { + // low is good, so we add to the peer with the greater ordering. + Ordering::Greater => ranks[i1].last_block_transfer += 1.0, + Ordering::Less => ranks[i1 + i2].last_block_transfer += 1.0, + Ordering::Equal => { + ranks[i1].last_block_transfer += 0.5; + ranks[i1 + i2].last_block_transfer += 0.5; + } + } + } + }; + + match (p1.last_tx_transfer(), p2.last_tx_transfer()) { + // Some is good, so we add to the peer with None + (Some(_), None) => ranks[i1 + i2].last_tx_transfer += 1.0, + (None, Some(_)) => ranks[i1].last_tx_transfer += 1.0, + (None, None) => { + ranks[i1].last_tx_transfer += 0.5; + ranks[i1 + i2].last_tx_transfer += 0.5; + } + (Some(peer1_last_tx_transfer), Some(peer2_last_tx_transfer)) => { + match peer1_last_tx_transfer.cmp(&peer2_last_tx_transfer) { + // low is good, so we add to the peer with the greater ordering. + Ordering::Greater => ranks[i1].last_tx_transfer += 1.0, + Ordering::Less => ranks[i1 + i2].last_tx_transfer += 1.0, + Ordering::Equal => { + ranks[i1].last_tx_transfer += 0.5; + ranks[i1 + i2].last_tx_transfer += 0.5; + } + } + } + }; + } + (peers[i1], ranks[i1]) + })) +} // Abstracted helper functions: fn build_ip_prefix_map(peers: &[&Peer]) -> HashMap { @@ -530,7 +511,7 @@ mod test { fn test_eviction_iter_from_peers() { let test_peers = build_test_peers(); let test_peers = test_peers.iter().collect::>(); - let eviction_iter_vec = EvictionIter::from_peers(&test_peers).collect::>(); + let eviction_iter_vec = from_peers(&test_peers).collect::>(); let expected_ranks = vec![ EvictionRanks { @@ -616,12 +597,12 @@ mod test { let test_peers = build_test_peers(); let test_peers = test_peers.iter().collect::>(); let iterations = test_peers.len(); - let eviction_iter_vec = EvictionIter::from_peers(&test_peers).collect::>(); + let eviction_iter_vec = from_peers(&test_peers).collect::>(); for i in 0..iterations + 1 { let mut removed_counter = HashMap::::new(); let mut filtered_counter = HashMap::::new(); - let eviction_candidates_iter = Box::new(eviction_iter_vec.clone().into_iter()) as EvictionIter; + let eviction_candidates_iter = eviction_iter_vec.clone().into_iter(); let filtered_eviction_set = eviction_candidates_iter.filter_peers(i, cmp_strats::by_lowest_rank).collect_vec(); let removed_eviction_set = eviction_iter_vec.clone().into_iter().filter(|item| !filtered_eviction_set.contains(item)).collect_vec(); @@ -749,7 +730,7 @@ mod test { try_init_logger("info"); let test_peers = build_test_peers(); let test_peers = test_peers.iter().collect::>(); - let eviction_iter_vec = EvictionIter::from_peers(&test_peers).collect::>(); + let eviction_iter_vec = from_peers(&test_peers).collect::>(); let total_weight = 59.5; let expected_probabilities = vec![ // we add one to avoid 0, and nan numbers.. `weight_strats::by_highest_none_latency_rank` adds 1 to the rank for these hypothetical situation. @@ -769,7 +750,7 @@ mod test { let num_of_trials = 2054; for _ in 0..num_of_trials { //println!("sample_size: {}", sample_size); - let eviction_iter = Box::new(eviction_iter_vec.clone().into_iter()) as EvictionIter; + let eviction_iter = eviction_iter_vec.clone().into_iter(); let selected_eviction_set = eviction_iter.select_peers_weighted(1, weight_strats::by_highest_none_latency_rank).collect_vec(); assert_eq!(selected_eviction_set.len(), 1); diff --git a/components/connectionmanager/src/lib.rs b/components/connectionmanager/src/lib.rs index 3d806acef..68dbcffed 100644 --- a/components/connectionmanager/src/lib.rs +++ b/components/connectionmanager/src/lib.rs @@ -1,5 +1,5 @@ mod eviction; -use eviction::{cmp_strats, constants::RETAIN_RATIO, weight_strats, EvictionIter, EvictionIterExt}; +use eviction::{cmp_strats, constants::RETAIN_RATIO, weight_strats, EvictionIterExt}; use std::{ cmp::min, @@ -26,6 +26,7 @@ use tokio::{ }, time::{interval, MissedTickBehavior}, }; +use crate::eviction::from_peers; pub struct ConnectionManager { p2p_adaptor: Arc, @@ -253,7 +254,7 @@ impl ConnectionManager { // the following peer selection strategy is designed to ensure that an eclipse attacker must outperform // the best performing peers in any independent metric in order to perform a total eclipse. // while keeping a bias to disconnect from newer peers, and those with concentrated prefix buckets. - for peer in EvictionIter::from_peers(&active_inbound) + for peer in from_peers(&active_inbound) .filter_peers( // We retain a number of peers proportional to the inbound limit. (self.inbound_limit as f64 / RETAIN_RATIO).floor() as usize, From 18a0b60ad1a27d301ba238e5914355a91b914fd5 Mon Sep 17 00:00:00 2001 From: max143672 Date: Wed, 13 Mar 2024 18:50:45 +0300 Subject: [PATCH 04/11] move constraints to `where` clause, rename constraints, remove unnecessary boxing in `from_peers` fn --- components/connectionmanager/src/eviction.rs | 49 +++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/components/connectionmanager/src/eviction.rs b/components/connectionmanager/src/eviction.rs index 32f8b64e0..9e67fb2ac 100644 --- a/components/connectionmanager/src/eviction.rs +++ b/components/connectionmanager/src/eviction.rs @@ -190,26 +190,30 @@ impl EvictionRanks { } } -pub trait EvictionIterExt<'a, T: Iterator + 'a>: IntoIterator{ +pub trait EvictionIterExt<'a, Iter>: IntoIterator +where + Iter: Iterator + 'a, +{ fn filter_peers(self, amount: usize, compare_fn: F) -> impl Iterator + 'a where F: Fn(&EvictionRanks, &EvictionRanks) -> Ordering, Self: Sized, { let rng = &mut thread_rng(); - self.into_iter().sorted_unstable_by(move |(_, r1), (_, r2)| match compare_fn(r1, r2) { - Ordering::Greater => Ordering::Greater, - Ordering::Less => Ordering::Less, - // we tie break randomly, as to not expose preference due to pre-existing ordering. - Ordering::Equal => { - if rng.gen_bool(0.5) { - Ordering::Greater - } else { - Ordering::Less + self.into_iter() + .sorted_unstable_by(move |(_, r1), (_, r2)| match compare_fn(r1, r2) { + Ordering::Greater => Ordering::Greater, + Ordering::Less => Ordering::Less, + // we tie break randomly, as to not expose preference due to pre-existing ordering. + Ordering::Equal => { + if rng.gen_bool(0.5) { + Ordering::Greater + } else { + Ordering::Less + } } - } - }) - .skip(amount) + }) + .skip(amount) } fn select_peers_weighted(self, amount: usize, weight_fn: F) -> impl Iterator + 'a @@ -218,7 +222,13 @@ pub trait EvictionIterExt<'a, T: Iterator + 'a Self: Sized, { let rng = &mut thread_rng(); - self.into_iter().collect_vec().choose_multiple_weighted(rng, amount, |(_, r)| weight_fn(r)).unwrap().copied().collect_vec().into_iter() + self.into_iter() + .collect_vec() + .choose_multiple_weighted(rng, amount, |(_, r)| weight_fn(r)) + .unwrap() + .copied() + .collect_vec() + .into_iter() } fn iterate_peers(self) -> impl Iterator + 'a @@ -229,12 +239,17 @@ pub trait EvictionIterExt<'a, T: Iterator + 'a } } -impl<'a, T: Iterator + 'a, IntoIter: IntoIterator> EvictionIterExt<'a, T> for IntoIter {} +impl<'a, Iter, IntoIter> EvictionIterExt<'a, Iter> for IntoIter +where + Iter: Iterator + 'a, + IntoIter: IntoIterator, +{ +} pub fn from_peers<'a>(peers: &'a [&'a Peer]) -> impl Iterator + 'a { let ip_prefix_map = build_ip_prefix_map(peers); let mut ranks = vec![EvictionRanks::default(); peers.len()]; - Box::new(peers.iter().enumerate().map(move |(i1, p1)| { + peers.iter().enumerate().map(move |(i1, p1)| { for (i2, p2) in peers[i1..].iter().enumerate().skip(1) { match ip_prefix_map[&p1.prefix_bucket()].cmp(&ip_prefix_map[&p2.prefix_bucket()]) { // low is good, so we add rank to the peer with the greater ordering. @@ -309,7 +324,7 @@ pub fn from_peers<'a>(peers: &'a [&'a Peer]) -> impl Iterator Date: Wed, 13 Mar 2024 19:49:50 +0300 Subject: [PATCH 05/11] fmt --- components/connectionmanager/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/connectionmanager/src/lib.rs b/components/connectionmanager/src/lib.rs index 68dbcffed..5400dadfe 100644 --- a/components/connectionmanager/src/lib.rs +++ b/components/connectionmanager/src/lib.rs @@ -9,6 +9,7 @@ use std::{ time::{Duration, SystemTime}, }; +use crate::eviction::from_peers; use duration_string::DurationString; use futures_util::future::join_all; use itertools::Itertools; @@ -26,7 +27,6 @@ use tokio::{ }, time::{interval, MissedTickBehavior}, }; -use crate::eviction::from_peers; pub struct ConnectionManager { p2p_adaptor: Arc, From 21c930e5471e87137c0dd2a9818928ce3198ba76 Mon Sep 17 00:00:00 2001 From: D-Stacks <78099568+D-Stacks@users.noreply.github.com> Date: Thu, 14 Mar 2024 22:45:17 +0100 Subject: [PATCH 06/11] some clean-up, rename from_peers (as it lost context). --- components/connectionmanager/src/eviction.rs | 8 ++++---- components/connectionmanager/src/lib.rs | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/components/connectionmanager/src/eviction.rs b/components/connectionmanager/src/eviction.rs index 9e67fb2ac..e112f74df 100644 --- a/components/connectionmanager/src/eviction.rs +++ b/components/connectionmanager/src/eviction.rs @@ -246,7 +246,7 @@ where { } -pub fn from_peers<'a>(peers: &'a [&'a Peer]) -> impl Iterator + 'a { +pub fn eviction_iter_from_peers<'a>(peers: &'a [&'a Peer]) -> impl Iterator + 'a { let ip_prefix_map = build_ip_prefix_map(peers); let mut ranks = vec![EvictionRanks::default(); peers.len()]; peers.iter().enumerate().map(move |(i1, p1)| { @@ -526,7 +526,7 @@ mod test { fn test_eviction_iter_from_peers() { let test_peers = build_test_peers(); let test_peers = test_peers.iter().collect::>(); - let eviction_iter_vec = from_peers(&test_peers).collect::>(); + let eviction_iter_vec = eviction_iter_from_peers(&test_peers).collect::>(); let expected_ranks = vec![ EvictionRanks { @@ -612,7 +612,7 @@ mod test { let test_peers = build_test_peers(); let test_peers = test_peers.iter().collect::>(); let iterations = test_peers.len(); - let eviction_iter_vec = from_peers(&test_peers).collect::>(); + let eviction_iter_vec = eviction_iter_from_peers(&test_peers).collect::>(); for i in 0..iterations + 1 { let mut removed_counter = HashMap::::new(); @@ -745,7 +745,7 @@ mod test { try_init_logger("info"); let test_peers = build_test_peers(); let test_peers = test_peers.iter().collect::>(); - let eviction_iter_vec = from_peers(&test_peers).collect::>(); + let eviction_iter_vec = eviction_iter_from_peers(&test_peers).collect::>(); let total_weight = 59.5; let expected_probabilities = vec![ // we add one to avoid 0, and nan numbers.. `weight_strats::by_highest_none_latency_rank` adds 1 to the rank for these hypothetical situation. diff --git a/components/connectionmanager/src/lib.rs b/components/connectionmanager/src/lib.rs index 5400dadfe..50073628f 100644 --- a/components/connectionmanager/src/lib.rs +++ b/components/connectionmanager/src/lib.rs @@ -1,5 +1,5 @@ mod eviction; -use eviction::{cmp_strats, constants::RETAIN_RATIO, weight_strats, EvictionIterExt}; +use crate::eviction::{cmp_strats, constants::RETAIN_RATIO, eviction_iter_from_peers, weight_strats, EvictionIterExt}; use std::{ cmp::min, @@ -9,7 +9,6 @@ use std::{ time::{Duration, SystemTime}, }; -use crate::eviction::from_peers; use duration_string::DurationString; use futures_util::future::join_all; use itertools::Itertools; @@ -254,7 +253,7 @@ impl ConnectionManager { // the following peer selection strategy is designed to ensure that an eclipse attacker must outperform // the best performing peers in any independent metric in order to perform a total eclipse. // while keeping a bias to disconnect from newer peers, and those with concentrated prefix buckets. - for peer in from_peers(&active_inbound) + for peer in eviction_iter_from_peers(&active_inbound) .filter_peers( // We retain a number of peers proportional to the inbound limit. (self.inbound_limit as f64 / RETAIN_RATIO).floor() as usize, From a4e98bbbba456f9408553e8bbe0a3e35a9221f7d Mon Sep 17 00:00:00 2001 From: D-Stacks <78099568+D-Stacks@users.noreply.github.com> Date: Tue, 12 Mar 2024 22:01:25 +0100 Subject: [PATCH 07/11] eviction_logic. --- Cargo.lock | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index a39d058d4..fcf45d7f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1982,6 +1982,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.6", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -5358,7 +5367,7 @@ dependencies = [ name = "rustversion" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "rv" From 1c6132282c593505478fe4242ed656cf1a6e0ee1 Mon Sep 17 00:00:00 2001 From: D-Stacks <78099568+D-Stacks@users.noreply.github.com> Date: Wed, 13 Mar 2024 01:24:14 +0100 Subject: [PATCH 08/11] address point 2 and 3 of reveiw. --- Cargo.lock | 43 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcf45d7f2..661bbb07c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5588,6 +5588,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -6184,40 +6193,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" -dependencies = [ - "indexmap 2.2.6", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - [[package]] name = "tonic" version = "0.10.2" From 7ffe1b69ebed887d701215e467343404034de7dc Mon Sep 17 00:00:00 2001 From: D-Stacks <78099568+D-Stacks@users.noreply.github.com> Date: Tue, 2 Jul 2024 21:11:37 +0200 Subject: [PATCH 09/11] fix cargo.lock --- Cargo.lock | 727 +++++++++++++++++++++++++++-------------------------- 1 file changed, 364 insertions(+), 363 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 661bbb07c..b78aacc0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,21 +4,21 @@ version = 3 [[package]] name = "accessory" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "850bb534b9dc04744fbbb71d30ad6d25a7e4cf6dc33e223c81ef3a92ebab4e0b" +checksum = "87537f9ae7cfa78d5b8ebd1a1db25959f5e737126be4d8eb44a5452fc4b63cde" dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -56,7 +56,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", "once_cell", "version_check", ] @@ -68,7 +68,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if 1.0.0", - "getrandom 0.2.14", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -156,9 +156,9 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] @@ -175,9 +175,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "approx" @@ -241,22 +241,21 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.2.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d4d23bcc79e27423727b36823d86233aad06dfea531837b038394d11e9928" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 5.3.0", - "event-listener-strategy 0.5.2", + "event-listener-strategy", "futures-core", "pin-project-lite", ] [[package]] name = "async-executor" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b10202063978b3351199d68f8b22c4e47e4b1b822f8d43fd862d5ea8c006b29a" +checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" dependencies = [ "async-task", "concurrent-queue", @@ -271,10 +270,10 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-executor", - "async-io 2.3.2", - "async-lock 3.3.0", + "async-io 2.3.3", + "async-lock 3.4.0", "blocking", "futures-lite 2.3.0", "once_cell", @@ -302,17 +301,17 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if 1.0.0", "concurrent-queue", "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.7.0", + "polling 3.7.2", "rustix 0.38.34", "slab", "tracing", @@ -330,12 +329,12 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", + "event-listener 5.3.1", + "event-listener-strategy", "pin-project-lite", ] @@ -385,7 +384,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -402,7 +401,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -461,7 +460,7 @@ dependencies = [ "futures-util", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.28", + "hyper 0.14.29", "itoa", "matchit", "memchr", @@ -489,7 +488,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.0", "http-body-util", - "hyper 1.3.1", + "hyper 1.4.0", "hyper-util", "itoa", "matchit", @@ -550,9 +549,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -631,7 +630,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -642,9 +641,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "blake2" @@ -677,12 +676,11 @@ dependencies = [ [[package]] name = "blocking" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "495f7104e962b7356f0aeb34247aca1fe7d2e783b346582db7f2904cb5717e88" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel 2.2.1", - "async-lock 3.3.0", + "async-channel 2.3.1", "async-task", "futures-io", "futures-lite 2.3.0", @@ -775,9 +773,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] @@ -813,9 +811,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.96" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" dependencies = [ "jobserver", "libc", @@ -949,9 +947,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -975,9 +973,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" dependencies = [ "clap_builder", "clap_derive", @@ -985,9 +983,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" dependencies = [ "anstream", "anstyle", @@ -997,21 +995,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "colorchoice" @@ -1105,9 +1103,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if 1.0.0", ] @@ -1121,7 +1119,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.4", + "clap 4.5.8", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -1154,9 +1152,9 @@ checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -1182,9 +1180,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crossterm" @@ -1192,7 +1190,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm_winapi", "libc", "mio", @@ -1271,15 +1269,14 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if 1.0.0", "cpufeatures", "curve25519-dalek-derive", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -1293,14 +1290,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] name = "darling" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ "darling_core", "darling_macro", @@ -1308,27 +1305,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 2.0.60", + "strsim 0.11.1", + "syn 2.0.68", ] [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -1359,7 +1356,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -1401,7 +1398,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -1411,20 +1408,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.68", ] [[package]] @@ -1435,9 +1432,9 @@ checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7" [[package]] name = "deunicode" -version = "1.4.4" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" +checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00" [[package]] name = "dhat" @@ -1513,9 +1510,9 @@ checksum = "6fcc1d9ae294a15ed05aeae8e11ee5f2b3fe971c077d45a42fb20825fba6ee13" [[package]] name = "either" -version = "1.11.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" @@ -1564,9 +1561,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1580,43 +1577,22 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "5.3.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9944b8ca13534cdfb2800775f8dd4902ff3fc75a50101466decadfdf322a24" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", "pin-project-lite", ] -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.3", - "pin-project-lite", -] - [[package]] name = "event-listener-strategy" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 5.3.0", + "event-listener 5.3.1", "pin-project-lite", ] @@ -1638,7 +1614,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -1673,9 +1649,9 @@ checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fiat-crypto" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" @@ -1697,9 +1673,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "fixedstr" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4e4dfef7b590ab7d11e531d602fdfb6a3413b09924db1428902bbc4410a9a8" +checksum = "54e049f021908beff8f8c430a99f5c136d3be69f1667346e581f446b173bc012" dependencies = [ "serde", ] @@ -1828,7 +1804,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -1894,9 +1870,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1907,9 +1883,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -1988,7 +1964,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", ] [[package]] @@ -2034,6 +2010,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -2122,12 +2104,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http 1.1.0", "http-body 1.0.0", "pin-project-lite", @@ -2141,9 +2123,9 @@ checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -2159,9 +2141,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" dependencies = [ "bytes", "futures-channel", @@ -2183,9 +2165,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" dependencies = [ "bytes", "futures-channel", @@ -2206,7 +2188,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.28", + "hyper 0.14.29", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -2219,7 +2201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.28", + "hyper 0.14.29", "native-tls", "tokio", "tokio-native-tls", @@ -2227,17 +2209,16 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" dependencies = [ "bytes", "futures-util", "http 1.1.0", "http-body 1.0.0", - "hyper 1.3.1", + "hyper 1.4.0", "pin-project-lite", - "socket2 0.5.7", "tokio", ] @@ -2291,7 +2272,7 @@ dependencies = [ "bytes", "futures", "http 0.2.12", - "hyper 0.14.28", + "hyper 0.14.29", "log", "rand 0.8.5", "tokio", @@ -2349,9 +2330,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -2521,7 +2502,7 @@ dependencies = [ "borsh", "bs58", "faster-hex 0.6.1", - "getrandom 0.2.14", + "getrandom 0.2.15", "hmac", "js-sys", "kaspa-utils", @@ -2609,7 +2590,7 @@ name = "kaspa-consensus" version = "0.14.1" dependencies = [ "arc-swap", - "async-channel 2.2.1", + "async-channel 2.3.1", "bincode", "criterion", "crossbeam-channel", @@ -2686,7 +2667,7 @@ dependencies = [ "criterion", "faster-hex 0.6.1", "futures-util", - "getrandom 0.2.14", + "getrandom 0.2.15", "itertools 0.11.0", "js-sys", "kaspa-addresses", @@ -2716,7 +2697,7 @@ dependencies = [ name = "kaspa-consensus-notify" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "cfg-if 1.0.0", "derive_more", "futures", @@ -2839,7 +2820,7 @@ dependencies = [ name = "kaspa-grpc-client" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-stream", "async-trait", "faster-hex 0.6.1", @@ -2870,7 +2851,7 @@ dependencies = [ name = "kaspa-grpc-core" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-stream", "async-trait", "faster-hex 0.6.1", @@ -2899,7 +2880,7 @@ dependencies = [ name = "kaspa-grpc-server" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-stream", "async-trait", "faster-hex 0.6.1", @@ -2955,7 +2936,7 @@ dependencies = [ name = "kaspa-index-core" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-trait", "derive_more", "futures", @@ -2974,7 +2955,7 @@ dependencies = [ name = "kaspa-index-processor" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-trait", "derive_more", "futures", @@ -3093,7 +3074,7 @@ dependencies = [ name = "kaspa-notify" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-trait", "borsh", "criterion", @@ -3221,7 +3202,7 @@ dependencies = [ "ahash 0.8.11", "axum 0.7.5", "cfg-if 1.0.0", - "clap 4.5.4", + "clap 4.5.8", "console", "convert_case 0.6.0", "futures", @@ -3234,7 +3215,7 @@ dependencies = [ "serde_json", "thiserror", "tokio", - "toml 0.8.12", + "toml 0.8.14", "tower", "tower-http 0.5.2", "tracing-subscriber", @@ -3248,7 +3229,7 @@ dependencies = [ name = "kaspa-rpc-core" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-trait", "borsh", "cfg-if 1.0.0", @@ -3329,11 +3310,11 @@ dependencies = [ name = "kaspa-testing-integration" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-trait", "bincode", "chrono", - "clap 4.5.4", + "clap 4.5.8", "criterion", "crossbeam-channel", "dhat", @@ -3423,7 +3404,7 @@ dependencies = [ name = "kaspa-utils" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-trait", "bincode", "borsh", @@ -3454,7 +3435,7 @@ version = "0.14.1" dependencies = [ "cfg-if 1.0.0", "futures", - "hyper 0.14.28", + "hyper 0.14.29", "log", "pin-project-lite", "tokio", @@ -3516,7 +3497,7 @@ dependencies = [ "aes", "ahash 0.8.11", "argon2", - "async-channel 2.2.1", + "async-channel 2.3.1", "async-std", "async-trait", "base64 0.21.7", @@ -3712,7 +3693,7 @@ dependencies = [ "serde-wasm-bindgen", "serde_json", "thiserror", - "toml 0.8.12", + "toml 0.8.14", "wasm-bindgen", "wasm-bindgen-futures", "workflow-core", @@ -3743,7 +3724,7 @@ name = "kaspa-wrpc-proxy" version = "0.14.1" dependencies = [ "async-trait", - "clap 4.5.4", + "clap 4.5.8", "kaspa-consensus-core", "kaspa-grpc-client", "kaspa-rpc-core", @@ -3817,8 +3798,8 @@ dependencies = [ name = "kaspad" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", - "clap 4.5.4", + "async-channel 2.3.1", + "clap 4.5.8", "dhat", "dirs", "futures-util", @@ -3854,7 +3835,7 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "toml 0.8.12", + "toml 0.8.14", "workflow-log", ] @@ -3878,9 +3859,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -3890,15 +3871,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" dependencies = [ "cfg-if 1.0.0", "windows-targets 0.52.5", @@ -3912,9 +3893,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libmimalloc-sys" -version = "0.1.37" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81eb4061c0582dedea1cbc7aff2240300dd6982e0239d1c99e65c1dbf4a30ba7" +checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" dependencies = [ "cc", "libc", @@ -3926,7 +3907,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -3948,9 +3929,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.16" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "pkg-config", @@ -3985,9 +3966,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-ip-address" @@ -4013,9 +3994,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" dependencies = [ "serde", "value-bag", @@ -4067,9 +4048,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3" dependencies = [ "cc", "libc", @@ -4104,7 +4085,7 @@ dependencies = [ "cfg-if 1.0.0", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -4115,7 +4096,7 @@ checksum = "13198c120864097a565ccb3ff947672d969932b7975ebd4085732c9f09435e55" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -4128,14 +4109,14 @@ dependencies = [ "macroific_core", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] name = "malachite-base" -version = "0.4.7" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d073a3d1e4e037975af5ef176a2632672e25e8ddbe8e1811745c2e0726b6ad94" +checksum = "44c817c713ff9f16e06cfdc23baa3fecf1b71eaaac714816a98a560f4e350aa6" dependencies = [ "hashbrown 0.14.5", "itertools 0.11.0", @@ -4145,9 +4126,9 @@ dependencies = [ [[package]] name = "malachite-nz" -version = "0.4.7" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2546fc6ae29728079e87a2a0f011509e6060713b65e62ee46ba5d413b495ebc7" +checksum = "603729facf62429736ac17a9fc9fe1bf7e0eb8bde3da3b18cc2b6153150464d5" dependencies = [ "itertools 0.11.0", "libm", @@ -4203,15 +4184,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mimalloc" -version = "0.1.41" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f41a2280ded0da56c8cf898babb86e8f10651a34adcfff190ae9a1159c6908d" +checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" dependencies = [ "libmimalloc-sys", ] @@ -4230,9 +4211,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -4290,11 +4271,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -4350,7 +4330,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if 1.0.0", "cfg_aliases", "libc", @@ -4391,25 +4371,24 @@ dependencies = [ [[package]] name = "num" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", - "num-complex 0.4.5", + "num-complex 0.4.6", "num-integer", "num-iter", - "num-rational 0.4.1", + "num-rational 0.4.2", "num-traits", ] [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -4426,9 +4405,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -4472,11 +4451,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -4532,9 +4510,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] @@ -4563,7 +4541,7 @@ version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if 1.0.0", "foreign-types", "libc", @@ -4580,7 +4558,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -4591,9 +4569,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.3+3.2.1" +version = "300.3.1+3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" dependencies = [ "cc", ] @@ -4655,9 +4633,9 @@ checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -4671,7 +4649,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.5.1", + "redox_syscall 0.5.2", "smallvec", "windows-targets 0.52.5", ] @@ -4693,7 +4671,7 @@ checksum = "70df726c43c645ef1dde24c7ae14692036ebe5457c92c5f0ec4cfceb99634ff6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -4709,9 +4687,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pbkdf2" @@ -4761,9 +4739,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap 2.2.6", @@ -4786,7 +4764,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -4803,9 +4781,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", "fastrand 2.1.0", @@ -4818,12 +4796,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "polling" version = "2.8.0" @@ -4842,13 +4814,13 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if 1.0.0", "concurrent-queue", - "hermit-abi 0.3.9", + "hermit-abi 0.4.0", "pin-project-lite", "rustix 0.38.34", "tracing", @@ -4886,12 +4858,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -4928,18 +4900,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", "prost-derive", @@ -4947,9 +4919,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" +checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck", @@ -4962,37 +4934,37 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.60", + "syn 2.0.68", "tempfile", ] [[package]] name = "prost-derive" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] name = "prost-types" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ "prost", ] [[package]] name = "puruspe" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6778a7ae74b21f07fc5b9d550b1fdc212d719ec76d03cd2940c41002247c8a" +checksum = "06a1eed715f625eaa95fba5e049dcf7bc06fa396d6d2e55015b3764e234dfd3f" [[package]] name = "quote" @@ -5062,7 +5034,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", ] [[package]] @@ -5130,11 +5102,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -5143,16 +5115,16 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -5162,9 +5134,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -5173,9 +5145,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" @@ -5191,7 +5163,7 @@ dependencies = [ "h2", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.28", + "hyper 0.14.29", "hyper-tls", "ipnet", "js-sys", @@ -5225,7 +5197,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if 1.0.0", - "getrandom 0.2.14", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -5264,8 +5236,8 @@ dependencies = [ name = "rothschild" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", - "clap 4.5.4", + "async-channel 2.3.1", + "clap 4.5.8", "criterion", "faster-hex 0.6.1", "itertools 0.11.0", @@ -5286,9 +5258,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -5325,10 +5297,10 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] @@ -5365,19 +5337,20 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rv" -version = "0.16.4" +version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a650cc227f4eb01b043fb7580097d6830c688a8f33cd9eabbced2026d11abf5" +checksum = "c07e0a3b756794c7ea2f05d93760ffb946ff4f94b255d92444d94c19fd71f4ab" dependencies = [ "doc-comment", "lru", "num", + "num-traits", "peroxide", "rand 0.8.5", "rand_distr 0.4.3", @@ -5386,9 +5359,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "salsa20" @@ -5465,7 +5438,7 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -5484,9 +5457,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -5508,9 +5481,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.200" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -5538,20 +5511,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -5576,23 +5549,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", -] - -[[package]] -name = "serde_spanned" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" -dependencies = [ - "serde", + "syn 2.0.68", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -5611,9 +5575,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.1" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "079f3a42cd87588d924ed95b533f8d30a483388c4e400ab736a7058e34f16169" dependencies = [ "base64 0.22.1", "chrono", @@ -5629,14 +5593,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "bc03aad67c1d26b7de277d51c86892e7d9a0110a2fe44bf6b26cc569fba302d6" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -5733,8 +5697,8 @@ dependencies = [ name = "simpa" version = "0.14.1" dependencies = [ - "async-channel 2.2.1", - "clap 4.5.4", + "async-channel 2.3.1", + "clap 4.5.8", "dhat", "futures", "futures-util", @@ -5869,12 +5833,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -5883,9 +5841,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -5900,9 +5858,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" dependencies = [ "proc-macro2", "quote", @@ -5985,22 +5943,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -6019,6 +5977,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "thread-tree" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbd370cb847953a25954d9f63e14824a36113f8c72eecf6eccef5dc4b45d630" +dependencies = [ + "crossbeam-channel", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -6074,9 +6041,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" dependencies = [ "tinyvec_macros", ] @@ -6089,9 +6056,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", @@ -6117,13 +6084,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -6193,6 +6160,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tonic" version = "0.10.2" @@ -6208,7 +6209,7 @@ dependencies = [ "h2", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.28", + "hyper 0.14.29", "hyper-timeout", "percent-encoding", "pin-project", @@ -6234,7 +6235,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -6263,7 +6264,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "bytes", "futures-core", "futures-util", @@ -6281,7 +6282,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "bytes", "http 1.1.0", "http-body 1.0.0", @@ -6323,7 +6324,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -6443,9 +6444,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "universal-hash" @@ -6480,9 +6481,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -6497,9 +6498,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -6507,7 +6508,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", ] [[package]] @@ -6516,7 +6517,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", "rand 0.8.5", "serde", "wasm-bindgen", @@ -6569,9 +6570,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" @@ -6627,7 +6628,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", "wasm-bindgen-shared", ] @@ -6661,7 +6662,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6694,7 +6695,7 @@ checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] @@ -6900,9 +6901,9 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.6.7" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -6938,7 +6939,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcea01cb6122ac3f20dc14f8e4104e2c0cd9c718c17ddb3fc115f9b2ed99f9ae" dependencies = [ - "async-channel 2.2.1", + "async-channel 2.3.1", "async-std", "borsh", "bs58", @@ -6947,7 +6948,7 @@ dependencies = [ "dirs", "faster-hex 0.9.0", "futures", - "getrandom 0.2.14", + "getrandom 0.2.15", "instant", "js-sys", "rand 0.8.5", @@ -7126,7 +7127,7 @@ dependencies = [ "downcast-rs", "futures", "futures-util", - "getrandom 0.2.14", + "getrandom 0.2.15", "manual_future", "rand 0.8.5", "serde", @@ -7299,7 +7300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6967baf2bd85deb2a014a32d34c1664ded9333e10d11d43ffc179fa09cc55db8" dependencies = [ "ahash 0.8.11", - "async-channel 2.2.1", + "async-channel 2.3.1", "async-std", "async-trait", "cfg-if 1.0.0", @@ -7344,35 +7345,35 @@ checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" [[package]] name = "zerocopy" -version = "0.7.33" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.33" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4b6c273f496d8fd4eaf18853e6b448760225dc030ff2c485a786859aea6393" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.68", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.11+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4" dependencies = [ "cc", "pkg-config", From ade2582d10c2d436aebc90110b9be204fa5ec713 Mon Sep 17 00:00:00 2001 From: D-Stacks <78099568+D-Stacks@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:53:31 +0200 Subject: [PATCH 10/11] add some more debug for in-the-wild testing. --- components/connectionmanager/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/components/connectionmanager/src/lib.rs b/components/connectionmanager/src/lib.rs index 50073628f..f4e5afa43 100644 --- a/components/connectionmanager/src/lib.rs +++ b/components/connectionmanager/src/lib.rs @@ -6,7 +6,7 @@ use std::{ collections::{HashMap, HashSet}, net::{IpAddr, SocketAddr, ToSocketAddrs}, sync::Arc, - time::{Duration, SystemTime}, + time::{Duration, Instant, SystemTime}, }; use duration_string::DurationString; @@ -243,6 +243,10 @@ impl ConnectionManager { let active_inbound = peer_by_address.values().filter(|peer| !peer.is_outbound()).collect_vec(); let active_inbound_len = active_inbound.len(); if self.inbound_limit >= active_inbound_len { + debug!( + "Connection manager: has {} incoming P2P connections, inbound limit is {}, keeping new peers..", + active_inbound_len, self.inbound_limit + ); return; } @@ -253,6 +257,8 @@ impl ConnectionManager { // the following peer selection strategy is designed to ensure that an eclipse attacker must outperform // the best performing peers in any independent metric in order to perform a total eclipse. // while keeping a bias to disconnect from newer peers, and those with concentrated prefix buckets. + let instant = Instant::now(); //TODO: Remove this instant, it's only for in-the-wild testing. + debug!("Connection manager: has {} incoming P2P connections, disconnecting {}...", active_inbound_len, peer_overflow_amount); for peer in eviction_iter_from_peers(&active_inbound) .filter_peers( // We retain a number of peers proportional to the inbound limit. @@ -273,6 +279,7 @@ impl ConnectionManager { debug!("Disconnecting from {} because we're above the inbound limit", peer.net_address()); futures.push(self.p2p_adaptor.terminate(peer.key())); } + debug!("Connection manager: disconnecting peers took {}", instant.elapsed().as_millis()); join_all(futures).await; } From f01fe1ddae2b549d1bb36ca4c92bd83f5c5ed024 Mon Sep 17 00:00:00 2001 From: D-Stacks <78099568+D-Stacks@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:53:35 +0200 Subject: [PATCH 11/11] multiply, not div. --- components/connectionmanager/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/connectionmanager/src/lib.rs b/components/connectionmanager/src/lib.rs index f4e5afa43..ee904dbc2 100644 --- a/components/connectionmanager/src/lib.rs +++ b/components/connectionmanager/src/lib.rs @@ -262,7 +262,7 @@ impl ConnectionManager { for peer in eviction_iter_from_peers(&active_inbound) .filter_peers( // We retain a number of peers proportional to the inbound limit. - (self.inbound_limit as f64 / RETAIN_RATIO).floor() as usize, + (self.inbound_limit as f64 * RETAIN_RATIO).floor() as usize, // Based on their lowest (i.e. best performing) independent rank. cmp_strats::by_lowest_rank, )