diff --git a/CHANGELOG.md b/CHANGELOG.md index 04bd252..54aef6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added MSRV, set to rust version `1.85` + +### Changed + +- Change rust edition to 2024 +- Change rust toolchain to stable + ## [0.7.0] - 2024-10-21 ### Added diff --git a/Cargo.toml b/Cargo.toml index 8fb5a70..78f04d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,8 @@ name = "kadcast" authors = ["herr-seppia "] version = "0.7.0" -edition = "2018" +edition = "2024" +rust-version = "1.85" description = "Implementation of the Kadcast Network Protocol." categories = ["network-programming"] keywords = ["p2p", "network", "kad", "peer-to-peer", "kadcast"] @@ -20,7 +21,6 @@ tokio = { version = "1", features = ["rt", "net", "sync", "time", "io-std", "rt- raptorq = { version = "2.0", optional = true } tracing = "0.1" itertools = "0.10" -konst = "0.2" socket2 = "0.4" serde_derive = "1" serde = "1" diff --git a/examples/main.rs b/examples/main.rs index 918b2dd..324083a 100644 --- a/examples/main.rs +++ b/examples/main.rs @@ -10,7 +10,7 @@ use std::io::{self, BufRead}; use clap::{App, Arg}; use kadcast::config::Config; use kadcast::{MessageInfo, NetworkListen, Peer}; -use rustc_tools_util::{get_version_info, VersionInfo}; +use rustc_tools_util::{VersionInfo, get_version_info}; use serde_derive::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index aecbe3c..73cb934 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-05-22" +channel = "stable" components = ["rustfmt", "clippy"] diff --git a/rustfmt.toml b/rustfmt.toml index 2b1ff3b..9a2d1e7 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,3 +1,2 @@ max_width = 80 newline_style = "Unix" -wrap_comments = true diff --git a/src/encoding/header.rs b/src/encoding/header.rs index 7bca372..74d3757 100644 --- a/src/encoding/header.rs +++ b/src/encoding/header.rs @@ -4,10 +4,10 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. -use std::io::{self, Error, ErrorKind, Read, Write}; +use std::io::{self, Error, Read, Write}; use super::Marshallable; -use crate::{kbucket::BinaryID, K_ID_LEN_BYTES, K_NONCE_LEN}; +use crate::{K_ID_LEN_BYTES, K_NONCE_LEN, kbucket::BinaryID}; #[derive(Debug, PartialEq, Clone, Copy)] pub struct Header { @@ -26,7 +26,7 @@ impl Header { impl Marshallable for Header { fn marshal_binary(&self, writer: &mut W) -> io::Result<()> { if !self.binary_id.verify_nonce() { - return Err(Error::new(ErrorKind::Other, "Invalid Nonce")); + return Err(Error::other("Invalid Nonce")); } writer.write_all(self.binary_id.as_binary())?; writer.write_all(self.binary_id.nonce())?; diff --git a/src/encoding/message.rs b/src/encoding/message.rs index e5c3bb8..578a5f0 100644 --- a/src/encoding/message.rs +++ b/src/encoding/message.rs @@ -4,12 +4,12 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. -use std::io::{self, Error, ErrorKind, Read, Write}; +use std::io::{self, Error, Read, Write}; use semver::Version; pub(crate) use super::payload::{BroadcastPayload, NodePayload}; -pub use super::{header::Header, Marshallable}; +pub use super::{Marshallable, header::Header}; use crate::kbucket::BinaryKey; // PingMsg wire Ping message id. @@ -159,10 +159,10 @@ impl Marshallable for Message { let payload = BroadcastPayload::unmarshal_binary(reader)?; Ok(Message::broadcast(header, payload)) } - unknown => Err(Error::new( - ErrorKind::Other, - format!("Invalid message type: '{}'", unknown), - )), + unknown => Err(Error::other(format!( + "Invalid message type: '{}'", + unknown + ))), } } } diff --git a/src/encoding/payload/nodes.rs b/src/encoding/payload/nodes.rs index c4aab15..8a85918 100644 --- a/src/encoding/payload/nodes.rs +++ b/src/encoding/payload/nodes.rs @@ -8,7 +8,7 @@ use std::convert::TryInto; use std::io::{self, Read, Write}; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; -use crate::{encoding::Marshallable, kbucket::BinaryKey, K_ID_LEN_BYTES}; +use crate::{K_ID_LEN_BYTES, encoding::Marshallable, kbucket::BinaryKey}; #[derive(Debug, PartialEq)] pub(crate) struct NodePayload { diff --git a/src/handling.rs b/src/handling.rs index 508d354..e0378ac 100644 --- a/src/handling.rs +++ b/src/handling.rs @@ -17,7 +17,7 @@ use crate::encoding::message::{ use crate::kbucket::{BinaryKey, NodeInsertError, NodeInsertOk, Tree}; use crate::peer::{PeerInfo, PeerNode}; use crate::transport::{MessageBeanIn, MessageBeanOut}; -use crate::{RwLock, K_K}; +use crate::{K_K, RwLock}; /// Message metadata for incoming message notifications #[derive(Debug)] diff --git a/src/kbucket.rs b/src/kbucket.rs index b50149d..70fa74f 100644 --- a/src/kbucket.rs +++ b/src/kbucket.rs @@ -12,7 +12,7 @@ pub use bucket::InsertOk; pub use bucket::{NodeInsertError, NodeInsertOk}; use itertools::Itertools; pub use key::MAX_BUCKET_HEIGHT; -pub use key::{BinaryID, BinaryKey, BinaryNonce}; +pub use key::{BinaryID, BinaryKey}; pub use node::Node; use std::collections::hash_map::Entry; use tracing::info; @@ -20,8 +20,8 @@ use tracing::info; mod bucket; mod key; mod node; -use crate::config::BucketConfig; use crate::K_BETA; +use crate::config::BucketConfig; pub type BucketHeight = u8; @@ -35,7 +35,7 @@ impl Tree { pub fn insert( &mut self, node: Node, - ) -> Result, InsertError> { + ) -> Result, InsertError> { if self.root().network_id != node.network_id { return Err(NodeInsertError::MismatchNetwork(node)); } @@ -48,7 +48,7 @@ impl Tree { pub fn refresh( &mut self, node: Node, - ) -> Result, InsertError> { + ) -> Result, InsertError> { if self.root().network_id != node.network_id { return Err(NodeInsertError::MismatchNetwork(node)); } @@ -59,10 +59,10 @@ impl Tree { } fn get_or_create_bucket(&mut self, height: BucketHeight) -> &mut Bucket { - return match self.buckets.entry(height) { + match self.buckets.entry(height) { Entry::Occupied(o) => o.into_mut(), Entry::Vacant(v) => v.insert(Bucket::new(self.config)), - }; + } } // iter the buckets (up to max_height, inclusive) and pick at most Beta @@ -75,7 +75,7 @@ impl Tree { let max_h = max_h.unwrap_or(BucketHeight::MAX); self.buckets .iter() - .filter(move |(&height, _)| height <= max_h) + .filter(move |&(&height, _)| height <= max_h) .map(|(&height, bucket)| (height, bucket.pick::())) } @@ -86,7 +86,7 @@ impl Tree { pub(crate) fn closest_peers( &self, other: &BinaryKey, - ) -> impl Iterator> { + ) -> impl Iterator> + use<'_, ITEM_COUNT, V> { self.buckets .iter() .flat_map(|(_, b)| b.peers()) @@ -162,7 +162,7 @@ impl Tree { pub(crate) fn is_bucket_full(&self, height: BucketHeight) -> bool { self.buckets .get(&height) - .map_or(false, |bucket| bucket.is_full()) + .is_some_and(|bucket| bucket.is_full()) } pub(crate) fn bucket_size(&self, height: BucketHeight) -> usize { diff --git a/src/kbucket/bucket.rs b/src/kbucket/bucket.rs index 10890bf..475bec8 100644 --- a/src/kbucket/bucket.rs +++ b/src/kbucket/bucket.rs @@ -9,10 +9,10 @@ use rand::seq::SliceRandom; use rand::thread_rng; use semver::Version; -use super::node::{Node, NodeEvictionStatus}; use super::BinaryKey; -use crate::config::BucketConfig; +use super::node::{Node, NodeEvictionStatus}; use crate::K_K; +use crate::config::BucketConfig; /// Represents a bucket for storing nodes in a Kademlia routing table. pub(super) struct Bucket { @@ -153,7 +153,7 @@ impl Bucket { pub fn insert( &mut self, node: Node, - ) -> Result, InsertError> { + ) -> Result, InsertError> { if !node.id().verify_nonce() { return Err(NodeInsertError::Invalid(node)); } @@ -199,7 +199,7 @@ impl Bucket { pub fn refresh( &mut self, node: Node, - ) -> Result, InsertError> { + ) -> Result, InsertError> { if !node.id().verify_nonce() { return Err(NodeInsertError::Invalid(node)); } @@ -243,7 +243,7 @@ impl Bucket { /// Checks if the bucket has at least one idle node. pub(crate) fn has_idle(&self) -> bool { - self.nodes.first().map_or(false, |n| { + self.nodes.first().is_some_and(|n| { n.seen_at.elapsed() > self.bucket_config.bucket_ttl }) } @@ -286,13 +286,12 @@ impl Bucket { let node_idx = self.nodes.iter().position(|s| s.id().as_binary() == id)?; - self.nodes.pop_at(node_idx).map(|removed| { + self.nodes.pop_at(node_idx).inspect(|_removed| { if let Some(pending) = self.pending_node.take() { if pending.is_alive(self.bucket_config.node_ttl) { self.nodes.push(pending); } } - removed }) } } @@ -303,10 +302,10 @@ mod tests { use std::time::Duration; use super::*; + use crate::K_BETA; use crate::kbucket::Tree; use crate::peer::PeerNode; use crate::tests::Result; - use crate::K_BETA; impl Bucket { pub fn last_id(&self) -> Option<&BinaryKey> { diff --git a/src/kbucket/key.rs b/src/kbucket/key.rs index c8bc744..17d41be 100644 --- a/src/kbucket/key.rs +++ b/src/kbucket/key.rs @@ -6,9 +6,9 @@ use std::io; -use crate::encoding::Marshallable; use crate::K_ID_LEN_BYTES; use crate::K_NONCE_LEN; +use crate::encoding::Marshallable; pub type BinaryKey = [u8; K_ID_LEN_BYTES]; pub type BinaryNonce = [u8; K_NONCE_LEN]; @@ -127,7 +127,7 @@ impl BinaryID { if ret.verify_nonce() { Ok(ret) } else { - Err(io::Error::new(io::ErrorKind::Other, "Invalid Nonce")) + Err(io::Error::other("Invalid Nonce")) } } @@ -177,7 +177,7 @@ impl BinaryID { where I: Iterator, { - bytes.next().map_or(false, |b| { + bytes.next().is_some_and(|b| { if difficulty <= 8 { b.trailing_zeros() as usize >= difficulty } else if b != &0 { diff --git a/src/kbucket/node.rs b/src/kbucket/node.rs index f8bb606..f332de6 100644 --- a/src/kbucket/node.rs +++ b/src/kbucket/node.rs @@ -6,8 +6,8 @@ use std::time::{Duration, Instant}; -use super::key::BinaryID; use super::BucketHeight; +use super::key::BinaryID; /// A struct representing a node in the network with an associated ID, value, /// and eviction status. diff --git a/src/lib.rs b/src/lib.rs index 9da3380..03621fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,7 @@ const K_DIFF_PRODUCED_BIT: usize = 8; const fn get_k_k() -> usize { match option_env!("KADCAST_K") { - Some(v) => match konst::primitive::parse_usize(v) { + Some(v) => match usize::from_str_radix(v, 10) { Ok(e) => e, Err(_) => DEFAULT_K_K, }, @@ -243,7 +243,9 @@ impl Peer { const LAST_BUCKET_IDX: u8 = MAX_BUCKET_HEIGHT as u8 - 1; let ktable = self.ktable.read().await; if height.is_none() && ktable.bucket_size(LAST_BUCKET_IDX) == 0 { - warn!("Broadcasting a new message with empty bucket height {LAST_BUCKET_IDX}") + warn!( + "Broadcasting a new message with empty bucket height {LAST_BUCKET_IDX}" + ) } ktable .extract(height) diff --git a/src/maintainer.rs b/src/maintainer.rs index 00be55f..0aaeac8 100644 --- a/src/maintainer.rs +++ b/src/maintainer.rs @@ -15,7 +15,7 @@ use crate::encoding::message::{Header, Message}; use crate::kbucket::Tree; use crate::peer::PeerInfo; use crate::transport::MessageBeanOut; -use crate::{RwLock, K_ALPHA}; +use crate::{K_ALPHA, RwLock}; pub(crate) struct TableMaintainer { bootstrapping_nodes: Vec, diff --git a/src/peer.rs b/src/peer.rs index 21d3548..9d136de 100644 --- a/src/peer.rs +++ b/src/peer.rs @@ -11,10 +11,10 @@ use blake2::{Blake2s256, Digest}; use crate::kbucket::{BinaryID, BinaryKey}; pub type PeerNode = Node; +use crate::K_ID_LEN_BYTES; use crate::encoding::message::Header; use crate::encoding::payload::{IpInfo, PeerEncodedInfo}; use crate::kbucket::Node; -use crate::K_ID_LEN_BYTES; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct PeerInfo { address: SocketAddr, diff --git a/src/transport.rs b/src/transport.rs index 383bdaf..440fbea 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -15,8 +15,8 @@ use tokio::sync::mpsc::{self, Receiver, Sender}; use tracing::{debug, error, info, trace, warn}; use crate::config::Config; -use crate::encoding::message::Message; use crate::encoding::Marshallable; +use crate::encoding::message::Message; use crate::rwlock::RwLock; use crate::transport::encoding::{ Configurable, Decoder, Encoder, TransportDecoder, TransportEncoder, diff --git a/src/transport/encoding/raptorq.rs b/src/transport/encoding/raptorq.rs index e030fc0..3144046 100644 --- a/src/transport/encoding/raptorq.rs +++ b/src/transport/encoding/raptorq.rs @@ -10,7 +10,7 @@ use std::io::{self, ErrorKind}; use blake2::{Blake2s256, Digest}; use safe::{SafeObjectTransmissionInformation, TransmissionInformationError}; -use crate::encoding::{payload::BroadcastPayload, Marshallable}; +use crate::encoding::{Marshallable, payload::BroadcastPayload}; mod decoder; mod encoder; @@ -116,7 +116,7 @@ mod tests { let mut data = vec![0; 100_000]; for i in 0..data.len() { - data[i] = rand::Rng::gen(&mut rand::thread_rng()); + data[i] = rand::Rng::r#gen(&mut rand::thread_rng()); } let peer = PeerNode::generate("192.168.0.1:666", 0)?; let header = peer.to_header(); @@ -173,7 +173,7 @@ mod tests { let mut data = vec![0; DATA_LEN]; for i in 0..DATA_LEN { - data[i] = rand::Rng::gen(&mut rand::thread_rng()); + data[i] = rand::Rng::r#gen(&mut rand::thread_rng()); } let peer = PeerNode::generate("192.168.0.1:666", 0)?; let header = peer.to_header(); @@ -201,7 +201,7 @@ mod tests { for _ in 0..junks_messages { let mut gossip_frame = vec![]; for _ in 0..DATA_LEN { - gossip_frame.push(rand::Rng::gen(&mut rand::thread_rng())); + gossip_frame.push(rand::Rng::r#gen(&mut rand::thread_rng())); } let msg = Message::broadcast( header, @@ -258,7 +258,7 @@ mod tests { c.seek(std::io::SeekFrom::Start(0))?; c.read_to_end(&mut bytes)?; for i in 44..bytes.len() { - bytes[i] = rand::Rng::gen(&mut rand::thread_rng()); + bytes[i] = rand::Rng::r#gen(&mut rand::thread_rng()); } let c = Cursor::new(bytes); let mut reader = BufReader::new(c); diff --git a/src/transport/encoding/raptorq/decoder.rs b/src/transport/encoding/raptorq/decoder.rs index 68c7d6d..f052e90 100644 --- a/src/transport/encoding/raptorq/decoder.rs +++ b/src/transport/encoding/raptorq/decoder.rs @@ -16,8 +16,8 @@ use tracing::{debug, trace, warn}; use super::{ChunkedPayload, RAY_ID_SIZE, TRANSMISSION_INFO_SIZE}; use crate::encoding::message::Message; use crate::encoding::payload::BroadcastPayload; -use crate::transport::encoding::Configurable; use crate::transport::Decoder; +use crate::transport::encoding::Configurable; const DEFAULT_CACHE_TTL: Duration = Duration::from_secs(60); const DEFAULT_CACHE_PRUNE_EVERY: Duration = Duration::from_secs(30); @@ -157,12 +157,9 @@ impl Decoder for RaptorQDecoder { }) } Err(e) => { - return Err(io::Error::new( - io::ErrorKind::Other, - format!( - "Invalid transmission info {e:?}", - ), - )); + return Err(io::Error::other(format!( + "Invalid transmission info {e:?}", + ))); } } } @@ -213,7 +210,7 @@ impl Decoder for RaptorQDecoder { // cache with new status. This // will drop useless Decoder and avoid // to propagate already processed messages - .map(|decoded| { + .inspect(|_decoded| { self.cache.insert( ray_id, CacheStatus::Processed( @@ -221,7 +218,6 @@ impl Decoder for RaptorQDecoder { ), ); trace!("> Broadcast message decoded!"); - decoded }) } }; @@ -253,8 +249,8 @@ mod tests { use super::*; use crate::peer::PeerNode; use crate::tests::Result; - use crate::transport::encoding::raptorq::RaptorQEncoder; use crate::transport::encoding::Encoder; + use crate::transport::encoding::raptorq::RaptorQEncoder; impl RaptorQDecoder { fn cache_size(&self) -> usize { diff --git a/src/transport/encoding/raptorq/encoder.rs b/src/transport/encoding/raptorq/encoder.rs index a3cb3e0..a9a19ec 100644 --- a/src/transport/encoding/raptorq/encoder.rs +++ b/src/transport/encoding/raptorq/encoder.rs @@ -8,8 +8,8 @@ use std::io; use crate::encoding::message::Message; use crate::encoding::payload::BroadcastPayload; -use crate::transport::encoding::Configurable; use crate::transport::Encoder; +use crate::transport::encoding::Configurable; const DEFAULT_MIN_REPAIR_PACKETS_PER_BLOCK: u32 = 5; const DEFAULT_MTU: u16 = 1300; diff --git a/src/transport/encoding/raptorq/safe.rs b/src/transport/encoding/raptorq/safe.rs index 7b07851..9dbe473 100644 --- a/src/transport/encoding/raptorq/safe.rs +++ b/src/transport/encoding/raptorq/safe.rs @@ -34,7 +34,7 @@ use std::convert::TryFrom; use raptorq::ObjectTransmissionInformation; -use super::{encoder::MAX_MTU, TRANSMISSION_INFO_SIZE}; +use super::{TRANSMISSION_INFO_SIZE, encoder::MAX_MTU}; // This should eventually become // when it gets stabilized, and this function should be removed. diff --git a/src/transport/sockets.rs b/src/transport/sockets.rs index 20d0e43..cf6c5fd 100644 --- a/src/transport/sockets.rs +++ b/src/transport/sockets.rs @@ -11,7 +11,7 @@ use std::time::Duration; use tokio::net::UdpSocket; use tokio::runtime::Handle; use tokio::task::block_in_place; -use tokio::time::{self, timeout, Interval}; +use tokio::time::{self, Interval, timeout}; use tracing::{info, warn}; use super::encoding::Configurable; @@ -82,7 +82,7 @@ impl MultipleOutSocket { let send = timeout(self.udp_send_retry_interval, send_fn) .await - .map_err(|_| io::Error::new(io::ErrorKind::Other, "TIMEOUT")); + .map_err(|_| io::Error::other("TIMEOUT")); match send { Ok(Ok(_)) => { @@ -93,7 +93,9 @@ impl MultipleOutSocket { } Ok(Err(e)) | Err(e) => { if i < max_retry { - warn!("Unable to send msg, temptative {i}/{max_retry} - {e}"); + warn!( + "Unable to send msg, temptative {i}/{max_retry} - {e}" + ); tokio::time::sleep(self.udp_send_retry_interval).await } else { return Err(e); diff --git a/tests/lib.rs b/tests/lib.rs index 7960a7e..9941aba 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -72,7 +72,7 @@ mod tests { tokio::time::sleep(Duration::from_millis(2000)).await; let mut data: Vec = vec![0; MESSAGE_SIZE]; for i in 0..data.len() { - data[i] = rand::Rng::gen(&mut rand::thread_rng()); + data[i] = rand::Rng::r#gen(&mut rand::thread_rng()); } for i in 0..NODES { info!("ROUTING TABLE PEER #{}", i); @@ -134,7 +134,11 @@ mod tests { let removed = missing.remove(&(receiver_port as i32)); info!( "RECEIVER PORT: {} - Message N° {} got from {:?} - Left {} - Removed {:?}", - receiver_port, i, message.1, missing.len(), removed + receiver_port, + i, + message.1, + missing.len(), + removed ); } }