From e8d12e90db9ca80b8b7c10793d59b281274dfea9 Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:10:49 +0200 Subject: [PATCH 01/10] fix: some of clippy pedantic warnings --- Cargo.lock | 1 + crates/core/src/version.rs | 4 + crates/p2p/src/behaviours/pluto.rs | 15 ++- crates/p2p/src/behaviours/pluto_mdns.rs | 17 ++- crates/p2p/src/config.rs | 38 +++++- crates/p2p/src/conn_logger.rs | 14 +-- crates/p2p/src/gater.rs | 10 +- crates/p2p/src/k1.rs | 22 +++- crates/p2p/src/manet.rs | 16 ++- crates/p2p/src/metrics.rs | 8 +- crates/p2p/src/name.rs | 8 ++ crates/p2p/src/p2p.rs | 42 ++++++- crates/p2p/src/peer.rs | 96 ++++++++++++-- crates/p2p/src/utils.rs | 6 +- crates/peerinfo/examples/peerinfo.rs | 29 +++-- crates/relay-server/examples/relay_server.rs | 2 +- crates/relay-server/src/p2p.rs | 4 +- crates/tracing/Cargo.toml | 1 + crates/tracing/examples/basic.rs | 8 +- crates/tracing/src/config.rs | 125 +------------------ crates/tracing/src/init.rs | 6 + 21 files changed, 284 insertions(+), 188 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74d6a92f..df675cda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5619,6 +5619,7 @@ dependencies = [ name = "pluto-tracing" version = "1.7.1" dependencies = [ + "bon", "thiserror 2.0.18", "tokio", "tracing", diff --git a/crates/core/src/version.rs b/crates/core/src/version.rs index 67891bca..a33a1b0d 100644 --- a/crates/core/src/version.rs +++ b/crates/core/src/version.rs @@ -118,6 +118,10 @@ impl SemVer { } /// Try to parse a semantic version from a string. + /// + /// # Errors + /// + /// - [`SemVerError::InvalidFormat`] if the version string is invalid. pub fn parse>(value: T) -> Result { let matches = SEMVER_REGEX .captures(value.as_ref()) diff --git a/crates/p2p/src/behaviours/pluto.rs b/crates/p2p/src/behaviours/pluto.rs index 80665067..80632ff0 100644 --- a/crates/p2p/src/behaviours/pluto.rs +++ b/crates/p2p/src/behaviours/pluto.rs @@ -16,7 +16,7 @@ use crate::{config::default_ping_config, gater::ConnGater}; /// - **Relay client**: Enables NAT traversal via relay servers /// - **Identify**: Exchanges peer information and supported protocols /// - **Ping**: Measures latency and keeps connections alive -/// - **AutoNAT**: Detects NAT status and public reachability +/// - **`AutoNAT`**: Detects NAT status and public reachability #[derive(NetworkBehaviour)] pub struct PlutoBehaviour { /// Connection gater behaviour. @@ -27,17 +27,19 @@ pub struct PlutoBehaviour { pub identify: identify::Behaviour, /// Ping behaviour. pub ping: ping::Behaviour, - /// AutoNAT behaviour for NAT detection. + /// `AutoNAT` behaviour for NAT detection. pub autonat: autonat::Behaviour, } impl PlutoBehaviour { /// Creates a new Pluto behaviour with default configuration. + #[must_use] pub fn new(key: &Keypair, relay_client: relay::client::Behaviour) -> Self { PlutoBehaviourBuilder::default().build(key, relay_client) } - /// Returns a new builder for configuring a PlutoBehaviour. + /// Returns a new builder for configuring a `PlutoBehaviour`. + #[must_use] pub fn builder() -> PlutoBehaviourBuilder { PlutoBehaviourBuilder::default() } @@ -73,29 +75,34 @@ impl Default for PlutoBehaviourBuilder { impl PlutoBehaviourBuilder { /// Creates a new builder with default configuration. + #[must_use] pub fn new() -> Self { Self::default() } /// Sets the connection gater. + #[must_use] pub fn with_gater(mut self, gater: ConnGater) -> Self { self.gater = Some(gater); self } /// Sets the identify protocol string. + #[must_use] pub fn with_identify_protocol(mut self, protocol: impl Into) -> Self { self.identify_protocol = protocol.into(); self } /// Sets the user agent string. + #[must_use] pub fn with_user_agent(mut self, user_agent: impl Into) -> Self { self.user_agent = user_agent.into(); self } - /// Sets the AutoNAT configuration. + /// Sets the `AutoNAT` configuration. + #[must_use] pub fn with_autonat_config(mut self, config: autonat::Config) -> Self { self.autonat_config = Some(config); self diff --git a/crates/p2p/src/behaviours/pluto_mdns.rs b/crates/p2p/src/behaviours/pluto_mdns.rs index 3d919c2d..2f005ac7 100644 --- a/crates/p2p/src/behaviours/pluto_mdns.rs +++ b/crates/p2p/src/behaviours/pluto_mdns.rs @@ -15,11 +15,16 @@ pub struct PlutoMdnsBehaviour { impl PlutoMdnsBehaviour { /// Creates a new Pluto Mdns behaviour with default configuration. + /// + /// # Panics + /// - If the mDNS behaviour cannot be created. + #[must_use] pub fn new(key: &Keypair, relay_client: relay::client::Behaviour) -> Self { PlutoMdnsBehaviourBuilder::default().build(key, relay_client) } - /// Returns a new builder for configuring a PlutoMdnsBehaviour. + /// Returns a new builder for configuring a `PlutoMdnsBehaviour`. + #[must_use] pub fn builder() -> PlutoMdnsBehaviourBuilder { PlutoMdnsBehaviourBuilder::default() } @@ -34,11 +39,13 @@ pub struct PlutoMdnsBehaviourBuilder { impl PlutoMdnsBehaviourBuilder { /// Creates a new builder with default configuration. + #[must_use] pub fn new() -> Self { Self::default() } /// Replaces the inner [`PlutoBehaviourBuilder`] entirely. + #[must_use] pub fn with_pluto(mut self, pluto: PlutoBehaviourBuilder) -> Self { self.pluto = pluto; self @@ -52,6 +59,7 @@ impl PlutoMdnsBehaviourBuilder { /// .configure_pluto(|p| p.with_ping_interval(Duration::from_secs(5))) /// .build(&key, relay_client) /// ``` + #[must_use] pub fn configure_pluto( mut self, f: impl FnOnce(PlutoBehaviourBuilder) -> PlutoBehaviourBuilder, @@ -61,6 +69,7 @@ impl PlutoMdnsBehaviourBuilder { } /// Sets the mDNS configuration. + #[must_use] pub fn with_mdns_config(mut self, config: mdns::Config) -> Self { self.mdns_config = config; self @@ -68,6 +77,12 @@ impl PlutoMdnsBehaviourBuilder { /// Builds the [`PlutoMdnsBehaviour`] with the provided keypair and relay /// client. + /// + /// # Panics + /// + /// - If the mDNS behaviour cannot be created (this is okay since we use + /// mdns only for examples). + #[must_use] pub fn build( self, key: &Keypair, diff --git a/crates/p2p/src/config.rs b/crates/p2p/src/config.rs index e6aa6b8a..541e026b 100644 --- a/crates/p2p/src/config.rs +++ b/crates/p2p/src/config.rs @@ -77,16 +77,33 @@ pub struct P2PConfig { impl P2PConfig { /// Returns the TCP addresses of the node. + /// + /// # Errors + /// + /// - [`P2PConfigError::FailedToParseTcpAddresses`] if the TCP addresses + /// cannot be parsed. + /// - [`P2PConfigError::UnspecifiedIP`] if the IP address is unspecified. pub fn parse_tcp_addrs(&self) -> Result> { self.tcp_addrs.iter().map(resolve_listen_tcp_addr).collect() } /// Returns the UDP addresses of the node. + /// + /// # Errors + /// + /// - [`P2PConfigError::FailedToParseUdpAddresses`] if the UDP addresses + /// cannot be parsed. + /// - [`P2PConfigError::UnspecifiedIP`] if the IP address is unspecified. pub fn parse_udp_addrs(&self) -> Result> { self.udp_addrs.iter().map(resolve_listen_udp_addr).collect() } /// Returns the UDP multiaddresses of the node. + /// + /// # Errors + /// + /// - [`P2PConfigError::FailedToParseUdpAddresses`] if the UDP addresses + /// cannot be parsed. pub fn udp_multiaddrs(&self) -> Result> { let addrs = self.parse_udp_addrs()?; @@ -94,6 +111,11 @@ impl P2PConfig { } /// Returns the TCP multiaddresses of the node. + /// + /// # Errors + /// + /// - [`P2PConfigError::FailedToParseTcpAddresses`] if the TCP addresses + /// cannot be parsed. pub fn tcp_multiaddrs(&self) -> Result> { let addrs = self.parse_tcp_addrs()?; @@ -101,6 +123,7 @@ impl P2PConfig { } /// Returns a new builder for configuring a P2P configuration. + #[must_use] pub fn builder() -> P2PConfigBuilder { P2PConfigBuilder::new() } @@ -114,6 +137,7 @@ pub struct P2PConfigBuilder { impl P2PConfigBuilder { /// Creates a new builder with default configuration. + #[must_use] pub fn new() -> Self { Self { config: P2PConfig::default(), @@ -121,42 +145,49 @@ impl P2PConfigBuilder { } /// Sets the relay multiaddrs. + #[must_use] pub fn with_relays(mut self, relays: Vec) -> Self { self.config.relays = relays; self } /// Sets the external IP address. + #[must_use] pub fn with_external_ip(mut self, external_ip: String) -> Self { self.config.external_ip = Some(external_ip); self } /// Sets the external host. + #[must_use] pub fn with_external_host(mut self, external_host: String) -> Self { self.config.external_host = Some(external_host); self } /// Sets the TCP addresses. + #[must_use] pub fn with_tcp_addrs(mut self, tcp_addrs: Vec) -> Self { self.config.tcp_addrs = tcp_addrs; self } /// Sets the UDP addresses. + #[must_use] pub fn with_udp_addrs(mut self, udp_addrs: Vec) -> Self { self.config.udp_addrs = udp_addrs; self } /// Sets whether to disable the reuse port. + #[must_use] pub fn with_disable_reuse_port(mut self, disable_reuse_port: bool) -> Self { self.config.disable_reuse_port = disable_reuse_port; self } /// Builds the [`P2PConfig`]. + #[must_use] pub fn build(self) -> P2PConfig { self.config } @@ -168,13 +199,15 @@ pub const DEFAULT_PING_INTERVAL: Duration = Duration::from_secs(1); pub const DEFAULT_PING_TIMEOUT: Duration = Duration::from_secs(10); /// Returns the default ping configuration. +#[must_use] pub fn default_ping_config() -> ping::Config { ping::Config::new() .with_interval(DEFAULT_PING_INTERVAL) .with_timeout(DEFAULT_PING_TIMEOUT) } -/// Resolves a TCP address string to a SocketAddr, ensuring the IP is specified. +/// Resolves a TCP address string to a [`SocketAddr`], ensuring the IP is +/// specified. fn resolve_listen_tcp_addr(addr: impl AsRef) -> Result { let socket_addr: SocketAddr = addr .as_ref() @@ -189,7 +222,8 @@ fn resolve_listen_tcp_addr(addr: impl AsRef) -> Result { Ok(socket_addr) } -/// Resolves a UDP address string to a SocketAddr, ensuring the IP is specified. +/// Resolves a UDP address string to a [`SocketAddr`], ensuring the IP is +/// specified. fn resolve_listen_udp_addr(addr: impl AsRef) -> Result { let socket_addr: SocketAddr = addr .as_ref() diff --git a/crates/p2p/src/conn_logger.rs b/crates/p2p/src/conn_logger.rs index 70dc4f74..ada832da 100644 --- a/crates/p2p/src/conn_logger.rs +++ b/crates/p2p/src/conn_logger.rs @@ -215,12 +215,12 @@ impl NetworkBehaviour for ConnectionLogger type ConnectionHandler = dummy_handler::Handler; type ToSwarm = (); - #[instrument(skip(self, _local_addr, remote_addr), fields(peer = %peer_name(&peer), addr = %remote_addr))] + #[instrument(skip(self), fields(peer = %peer_name(&peer), addr = %remote_addr))] fn handle_established_inbound_connection( &mut self, - _connection_id: ConnectionId, + _: ConnectionId, peer: PeerId, - _local_addr: &Multiaddr, + _: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { debug!( @@ -234,14 +234,14 @@ impl NetworkBehaviour for ConnectionLogger Ok(dummy_handler::Handler) } - #[instrument(skip(self, _role_override, _port_use), fields(peer = %peer_name(&peer), addr = %addr))] + #[instrument(skip(self), fields(peer = %peer_name(&peer), addr = %addr))] fn handle_established_outbound_connection( &mut self, - _connection_id: ConnectionId, + _: ConnectionId, peer: PeerId, addr: &Multiaddr, - _role_override: libp2p::core::Endpoint, - _port_use: libp2p::core::transport::PortUse, + _: libp2p::core::Endpoint, + _: libp2p::core::transport::PortUse, ) -> Result, ConnectionDenied> { debug!( peer = %peer_name(&peer), diff --git a/crates/p2p/src/gater.rs b/crates/p2p/src/gater.rs index 2bef94b4..6e029862 100644 --- a/crates/p2p/src/gater.rs +++ b/crates/p2p/src/gater.rs @@ -34,6 +34,7 @@ pub struct Config { impl Config { /// Creates a new open gater configuration that does not gate any /// connections. + #[must_use] pub fn open() -> Self { Self { peer_ids: HashSet::new(), @@ -44,6 +45,7 @@ impl Config { /// Creates a new closed gater configuration that gates all connections /// except those explicitly allowed. + #[must_use] pub fn closed() -> Self { Self { peer_ids: HashSet::new(), @@ -53,19 +55,21 @@ impl Config { } /// Sets the allowed peer IDs. + #[must_use] pub fn with_peer_ids(mut self, peer_ids: Vec) -> Self { self.peer_ids = peer_ids.into_iter().collect(); self } /// Sets the relay peers. + #[must_use] pub fn with_relays(mut self, relays: Vec>) -> Self { self.relays = relays; self } } -/// ConnGater filters incoming and outgoing connections by the cluster peers. +/// `ConnGater` filters incoming and outgoing connections by the cluster peers. #[derive(Debug, Clone, Default)] pub struct ConnGater { config: Config, @@ -74,6 +78,7 @@ pub struct ConnGater { impl ConnGater { /// Creates a new connection gater with the given configuration. + #[must_use] pub fn new(config: Config) -> Self { Self { config, @@ -83,6 +88,7 @@ impl ConnGater { /// Creates a new connection gater that limits access to the cluster peers /// and relays. + #[must_use] pub fn new_conn_gater(peers: Vec, relays: Vec>) -> Self { Self { config: Config::closed().with_peer_ids(peers).with_relays(relays), @@ -91,6 +97,7 @@ impl ConnGater { } /// Creates a new open gater that does not gate any connections. + #[must_use] pub fn new_open_gater() -> Self { Self { config: Config::open(), @@ -99,6 +106,7 @@ impl ConnGater { } /// Returns true if the gater is open (not gating any connections). + #[must_use] pub fn is_open(&self) -> bool { self.config.open } diff --git a/crates/p2p/src/k1.rs b/crates/p2p/src/k1.rs index f475201a..2f9eee15 100644 --- a/crates/p2p/src/k1.rs +++ b/crates/p2p/src/k1.rs @@ -17,22 +17,34 @@ pub enum K1Error { #[error("K1 utility error: {0}")] K1UtilError(#[from] pluto_k1util::K1UtilError), - /// IOError. + /// `IOError`. #[error("IO error: {0}")] IoError(#[from] std::io::Error), } /// Returns the charon-enr-private-key path relative to the data dir. +#[must_use] pub fn key_path(data_dir: &Path) -> PathBuf { data_dir.join(KEY_FILE_NAME) } /// Loads the private key from the data dir. +/// +/// # Errors +/// +/// - [`K1Error::K1UtilError`] if the private key cannot be loaded. pub fn load_priv_key(data_dir: &Path) -> Result { pluto_k1util::load(&key_path(data_dir)).map_err(K1Error::K1UtilError) } /// Generates a new private key and saves it to the data dir. +/// +/// # Errors +/// +/// - [`K1Error::K1UtilError`] if the private key cannot be saved. +/// - [`K1Error::IoError`] if the backup directory cannot be created. +/// - [`K1Error::IoError`] if the private key cannot be copied to the backup +/// directory. pub fn new_saved_priv_key(data_dir: &Path) -> Result { backup_priv_key(data_dir)?; @@ -69,9 +81,11 @@ fn backup_priv_key(data_dir: &Path) -> Result<()> { .expect("Backup path parent should exist"), ) .map_err(K1Error::IoError)?; - if backup_path.is_dir() { - panic!("Backup path is a directory: {:?}", backup_path); - } + assert!( + !backup_path.is_dir(), + "Backup path is a directory: {}", + backup_path.display() + ); std::fs::copy(key_path, backup_path).map_err(K1Error::IoError)?; Ok(()) } diff --git a/crates/p2p/src/manet.rs b/crates/p2p/src/manet.rs index ecb1a1cd..9f77965a 100644 --- a/crates/p2p/src/manet.rs +++ b/crates/p2p/src/manet.rs @@ -25,7 +25,7 @@ const PRIVATE_CIDR4: &[(&str, Ipv4Addr, u8)] = &[ /// Private IPv6 CIDR ranges. const PRIVATE_CIDR6: &[(&str, Ipv6Addr, u8)] = &[ // localhost - ("::1/128", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 128), + ("::1/128", Ipv6Addr::LOCALHOST, 128), // ULA reserved ("fc00::/7", Ipv6Addr::new(0xfc00, 0, 0, 0, 0, 0, 0, 0), 7), // link local @@ -34,7 +34,7 @@ const PRIVATE_CIDR6: &[(&str, Ipv6Addr, u8)] = &[ /// Unroutable IPv4 CIDR ranges. const UNROUTABLE_CIDR4: &[(&str, Ipv4Addr, u8)] = &[ - ("0.0.0.0/8", Ipv4Addr::new(0, 0, 0, 0), 8), + ("0.0.0.0/8", Ipv4Addr::UNSPECIFIED, 8), ("192.0.0.0/26", Ipv4Addr::new(192, 0, 0, 0), 26), ("192.0.2.0/24", Ipv4Addr::new(192, 0, 2, 0), 24), ("192.88.99.0/24", Ipv4Addr::new(192, 88, 99, 0), 24), @@ -43,7 +43,7 @@ const UNROUTABLE_CIDR4: &[(&str, Ipv4Addr, u8)] = &[ ("203.0.113.0/24", Ipv4Addr::new(203, 0, 113, 0), 24), ("224.0.0.0/4", Ipv4Addr::new(224, 0, 0, 0), 4), ("240.0.0.0/4", Ipv4Addr::new(240, 0, 0, 0), 4), - ("255.255.255.255/32", Ipv4Addr::new(255, 255, 255, 255), 32), + ("255.255.255.255/32", Ipv4Addr::BROADCAST, 32), ]; /// Unroutable IPv6 CIDR ranges. @@ -79,7 +79,7 @@ const NAT64_CIDRS: &[(&str, Ipv6Addr, u8)] = &[ ]; /// Unresolvable domains that do not resolve to an IP address. -/// Ref: https://en.wikipedia.org/wiki/Special-use_domain_name#Reserved_domain_names +/// Ref: const UNRESOLVABLE_DOMAINS: &[&str] = &[ // Reverse DNS Lookup ".in-addr.arpa", @@ -89,7 +89,7 @@ const UNRESOLVABLE_DOMAINS: &[&str] = &[ ]; /// Private use domains reserved for private use with no central authority. -/// Ref: https://en.wikipedia.org/wiki/Special-use_domain_name#Reserved_domain_names +/// Ref: const PRIVATE_USE_DOMAINS: &[&str] = &[ // RFC 8375: Reserved for home networks ".home.arpa", @@ -116,11 +116,10 @@ pub trait Manet { impl Manet for Multiaddr { fn is_public(&self) -> bool { - for proto in self.iter() { + for proto in self { match proto { Protocol::Ip6zone(_) => { // Skip zone identifier, continue checking - continue; } Protocol::Ip4(ip) => { return !in_ipv4_range(ip, PRIVATE_CIDR4) @@ -173,11 +172,10 @@ impl Manet for Multiaddr { } fn is_private(&self) -> bool { - for proto in self.iter() { + for proto in self { match proto { Protocol::Ip6zone(_) => { // Skip zone identifier, continue checking - continue; } Protocol::Ip4(ip) => { return in_ipv4_range(ip, PRIVATE_CIDR4); diff --git a/crates/p2p/src/metrics.rs b/crates/p2p/src/metrics.rs index 19f7c63e..dc281c57 100644 --- a/crates/p2p/src/metrics.rs +++ b/crates/p2p/src/metrics.rs @@ -1,4 +1,7 @@ -use vise::*; +use vise::{ + Counter, EncodeLabelSet, EncodeLabelValue, Family, Gauge, Global, Histogram, LabeledFamily, + Metrics, +}; /// Buckets for the ping latency histogram. pub const BUCKETS: [f64; 11] = [ @@ -99,6 +102,7 @@ pub struct PeerConnectionLabels { impl PeerConnectionLabels { /// Creates a new peer connection labels. + #[must_use] pub fn new(peer: &str, r#type: ConnectionType, protocol: Protocol) -> Self { Self { peer: peer.to_string(), @@ -121,6 +125,7 @@ pub struct PeerStreamLabels { impl PeerStreamLabels { /// Creates a new peer stream labels. + #[must_use] pub fn new(peer: &str, direction: Direction, protocol: Protocol) -> Self { Self { peer: peer.to_string(), @@ -139,6 +144,7 @@ pub struct PeerNetworkLabels { impl PeerNetworkLabels { /// Creates a new peer network labels. + #[must_use] pub fn new(peer: &str, protocol: Protocol) -> Self { Self { peer: peer.to_string(), diff --git a/crates/p2p/src/name.rs b/crates/p2p/src/name.rs index b2e285d7..dc144a81 100644 --- a/crates/p2p/src/name.rs +++ b/crates/p2p/src/name.rs @@ -352,6 +352,14 @@ const ADJECTIVES: &[&str] = &[ /// /// The name is generated using a polynomial rolling hash of the base58-encoded /// peer ID, then selecting an adjective and noun from predefined lists. +/// +/// # Panics +/// +/// - Panic could occur if the hash value is not less than `u64::MAX`, but this +/// is unlikely. +/// - Panic could occur if the `NOUNS` or `ADJECTIVES` length is not less than +/// `u64::MAX`, but this is unlikely. +#[must_use] pub fn peer_name(id: &PeerId) -> String { // p is chosen to be 59 because it's prime and roughly equal to the number of // different characters you can have in base58 encoded strings. Base58 diff --git a/crates/p2p/src/p2p.rs b/crates/p2p/src/p2p.rs index 807c1f17..2605392c 100644 --- a/crates/p2p/src/p2p.rs +++ b/crates/p2p/src/p2p.rs @@ -104,9 +104,17 @@ pub struct Node { impl Node { /// Creates a new node. + /// + /// # Errors + /// + /// - [`P2PError::FailedToBuildSwarm`] if the swarm cannot be built. + /// - [`P2PError::FailedToDecodeLibp2pKeypair`] if the libp2p keypair cannot + /// be decoded. + /// - [`P2PError::FailedToConvertSecretKeyToLibp2pKeypair`] if the secret + /// key cannot be converted to a libp2p keypair. pub fn new( - cfg: P2PConfig, - key: k256::SecretKey, + cfg: &P2PConfig, + key: &k256::SecretKey, filter_private_addrs: bool, node_type: NodeType, behaviour_fn: F, @@ -121,7 +129,7 @@ impl Node { NodeType::QUIC => Self::new_with_quic(keypair, behaviour_fn), }?; - node.apply_config(&cfg, filter_private_addrs)?; + node.apply_config(cfg, filter_private_addrs)?; Ok(node) } @@ -151,7 +159,7 @@ impl Node { } let filtered_addrs = - utils::filter_advertised_addresses(addrs, external_addrs, filter_private_addrs)?; + utils::filter_advertised_addresses(addrs, external_addrs, filter_private_addrs); for addr in filtered_addrs { self.swarm.listen_on(addr)?; @@ -161,6 +169,14 @@ impl Node { } /// Creates a new node with QUIC and TCP. + /// + /// # Errors + /// + /// - [`P2PError::FailedToBuildSwarm`] if the swarm cannot be built. + /// - [`P2PError::FailedToDecodeLibp2pKeypair`] if the libp2p keypair cannot + /// be decoded. + /// - [`P2PError::FailedToConvertSecretKeyToLibp2pKeypair`] if the secret + /// key cannot be converted to a libp2p keypair. fn new_with_quic(keypair: Keypair, behaviour_fn: F) -> Result where F: Fn(&Keypair, relay::client::Behaviour) -> B, @@ -191,6 +207,14 @@ impl Node { } /// Creates a new node with TCP. + /// + /// # Errors + /// + /// - [`P2PError::FailedToBuildSwarm`] if the swarm cannot be built. + /// - [`P2PError::FailedToDecodeLibp2pKeypair`] if the libp2p keypair cannot + /// be decoded. + /// - [`P2PError::FailedToConvertSecretKeyToLibp2pKeypair`] if the secret + /// key cannot be converted to a libp2p keypair. fn new_with_tcp(keypair: Keypair, behaviour_fn: F) -> Result where F: Fn(&Keypair, relay::client::Behaviour) -> B, @@ -220,9 +244,17 @@ impl Node { } /// Creates a new node with relay server. + /// + /// # Errors + /// + /// - [`P2PError::FailedToBuildSwarm`] if the swarm cannot be built. + /// - [`P2PError::FailedToDecodeLibp2pKeypair`] if the libp2p keypair cannot + /// be decoded. + /// - [`P2PError::FailedToConvertSecretKeyToLibp2pKeypair`] if the secret + /// key cannot be converted to a libp2p keypair. pub fn new_relay_server( _cfg: &P2PConfig, - key: k256::SecretKey, + key: &k256::SecretKey, behaviour_fn: F, ) -> Result where diff --git a/crates/p2p/src/peer.rs b/crates/p2p/src/peer.rs index ac1dd26f..415e136a 100644 --- a/crates/p2p/src/peer.rs +++ b/crates/p2p/src/peer.rs @@ -60,10 +60,10 @@ pub struct AddrInfo { /// relay. #[derive(Clone, Debug)] pub struct Peer { - /// LibP2P peer identity. + /// `LibP2P` peer identity. pub id: PeerId, - /// List of libp2p multiaddresses of the peer. + /// List of `libp2p` multiaddresses of the peer. pub addresses: Vec, /// Index is the order of this node in the cluster. @@ -76,6 +76,7 @@ pub struct Peer { impl Peer { /// Creates a new relay peer from address information. + #[must_use] pub fn new_relay_peer(info: &AddrInfo) -> Peer { Peer { id: info.id, @@ -86,6 +87,17 @@ impl Peer { } /// Creates a Peer from a ENR. + /// + /// # Errors + /// + /// - [`PeerError::MissingPublicKeyInEnr`] if the public key is missing in + /// the ENR. + /// - [`PeerError::FailedToDecodeProtobuf`] if libp2p public key cannot be + /// decoded. + /// - [`PeerError::FailedToParseSecp256k1PublicKey`] if secp256k1 public key + /// cannot be parsed. + /// - [`PeerError::FailedToParseLibp2pPublicKey`] if libp2p public key + /// cannot be parsed. pub fn from_enr(enr: &Record, index: usize) -> Result { let id = peer_id_from_key(enr.public_key.ok_or(PeerError::MissingPublicKeyInEnr)?)?; @@ -97,18 +109,29 @@ impl Peer { }) } - /// Returns share index of this Peer. ShareIdx is 1-indexed while peer index - /// is 0-indexed. + /// Returns share index of this `Peer`. `ShareIdx` is 1-indexed while peer + /// index is 0-indexed. + #[must_use] pub fn share_idx(&self) -> usize { self.index.wrapping_add(1) } /// Returns the public key of the peer. + /// + /// # Errors + /// + /// - [`PeerError::FailedToDecodeProtobuf`] if libp2p public key cannot be + /// decoded. + /// - [`PeerError::FailedToParseSecp256k1PublicKey`] if secp256k1 public key + /// cannot be parsed. + /// - [`PeerError::FailedToParseLibp2pPublicKey`] if libp2p public key + /// cannot be parsed. pub fn public_key(&self) -> Result { peer_id_to_public_key(&self.id) } /// Returns the libp2p peer address info (peer ID and multiaddrs). + #[must_use] pub fn addr_info(&self) -> AddrInfo { AddrInfo { id: self.id, @@ -125,7 +148,7 @@ pub enum MutablePeerError { PoisonError, } -/// MutablePeer is a mutable peer that can be updated. +/// `MutablePeer` is a mutable peer that can be updated. #[derive(Debug, Clone)] pub struct MutablePeer { /// Inner state of the mutable peer. @@ -135,7 +158,7 @@ pub struct MutablePeer { /// Subscriber is a function that is called when the peer is updated. pub type Subscriber = Box; -/// MutablePeerInner is the inner state of a MutablePeer. +/// `MutablePeerInner` is the inner state of a `MutablePeer`. pub struct MutablePeerInner { /// Peer. peer: Option, @@ -157,6 +180,7 @@ type MutablePeerResult = std::result::Result; impl MutablePeer { /// Creates a new mutable peer with an initial value. + #[must_use] pub fn new(peer: Peer) -> Self { Self { inner: Arc::new(Mutex::new(MutablePeerInner { @@ -167,7 +191,12 @@ impl MutablePeer { } /// Updates the mutable peer and calls all subscribers. - pub fn set(&self, peer: Peer) -> MutablePeerResult<()> { + /// + /// # Errors + /// + /// - [`MutablePeerError::PoisonError`] if the mutable peer cannot be + /// locked. + pub fn set(&self, peer: &Peer) -> MutablePeerResult<()> { let mut inner = self .inner .lock() @@ -178,6 +207,11 @@ impl MutablePeer { } /// Returns the current peer or None if not available. + /// + /// # Errors + /// + /// - [`MutablePeerError::PoisonError`] if the mutable peer cannot be + /// locked. pub fn peer(&self) -> MutablePeerResult> { let inner = self .inner @@ -187,6 +221,11 @@ impl MutablePeer { } /// Registers a function that is called when the peer is updated. + /// + /// # Errors + /// + /// - [`MutablePeerError::PoisonError`] if the mutable peer cannot be + /// locked. pub fn subscribe(&self, sub: Subscriber) -> MutablePeerResult<()> { let mut inner = self .inner @@ -197,26 +236,52 @@ impl MutablePeer { } } -/// Converts a PeerId to a K256PublicKey. +/// Converts a `PeerId` to a `K256PublicKey`. /// Only works for secp256k1 keys. +/// +/// # Errors +/// +/// - [`PeerError::FailedToDecodeProtobuf`] if libp2p public key cannot be +/// decoded. +/// - [`PeerError::FailedToParseSecp256k1PublicKey`] if secp256k1 public key +/// cannot be parsed. +/// - [`PeerError::FailedToParseLibp2pPublicKey`] if libp2p public key cannot be +/// parsed. pub fn peer_id_to_public_key(peer_id: &PeerId) -> Result { let libp2p_pk = peer_id_to_libp2p_pk(peer_id)?; pluto_k1util::public_key_from_libp2p(&libp2p_pk).map_err(Into::into) } -/// Extracts the libp2p PublicKey from a PeerId. +/// Extracts the libp2p `PublicKey` from a `PeerId`. +/// +/// # Errors +/// +/// - [`PeerError::FailedToDecodeProtobuf`] if libp2p public key cannot be +/// decoded. pub fn peer_id_to_libp2p_pk(peer_id: &PeerId) -> Result { Libp2pPublicKey::try_decode_protobuf(peer_id.as_ref().digest()).map_err(Into::into) } -/// Converts a K256PublicKey to a libp2p PublicKey. +/// Converts a `K256PublicKey` to a libp2p `PublicKey`. +/// +/// # Errors +/// +/// - [`PeerError::FailedToParseLibp2pPublicKey`] if libp2p public key cannot be +/// parsed. fn k256_pk_to_libp2p_pk(pk: &K256PublicKey) -> Result { let sec1_bytes = pk.to_sec1_bytes(); let secp_key = libp2p::identity::secp256k1::PublicKey::try_from_bytes(&sec1_bytes)?; Ok(Libp2pPublicKey::from(secp_key)) } -/// Converts a K256PublicKey to a PeerId. +/// Converts a `K256PublicKey` to a `PeerId`. +/// +/// # Errors +/// +/// - [`PeerError::FailedToParseSecp256k1PublicKey`] if secp256k1 public key +/// cannot be parsed. +/// - [`PeerError::FailedToParseLibp2pPublicKey`] if libp2p public key cannot be +/// parsed. pub fn peer_id_from_key(key: K256PublicKey) -> Result { let libp2p_pk = k256_pk_to_libp2p_pk(&key)?; Ok(PeerId::from_public_key(&libp2p_pk)) @@ -224,6 +289,15 @@ pub fn peer_id_from_key(key: K256PublicKey) -> Result { /// `verify_p2p_key` returns an error if the p2p key doesn't match any lock /// operator ENR. +/// +/// # Errors +/// +/// - [`PeerError::UnknownPublicKey`] if the p2p key doesn't match any lock +/// operator ENR. +/// - [`PeerError::FailedToParseSecp256k1PublicKey`] if secp256k1 public key +/// cannot be parsed. +/// - [`PeerError::FailedToParseLibp2pPublicKey`] if libp2p public key cannot be +/// parsed. pub fn verify_p2p_key(peers: &[Peer], key: &SecretKey) -> Result<()> { let want = key.public_key(); diff --git a/crates/p2p/src/utils.rs b/crates/p2p/src/utils.rs index f81cad1e..d2252422 100644 --- a/crates/p2p/src/utils.rs +++ b/crates/p2p/src/utils.rs @@ -96,7 +96,7 @@ pub(crate) fn filter_advertised_addresses( mut external_addrs: Vec, mut internal_addrs: Vec, exclude_interval_private: bool, -) -> crate::p2p::Result> { +) -> Vec { external_addrs.dedup(); internal_addrs.dedup(); @@ -104,7 +104,7 @@ pub(crate) fn filter_advertised_addresses( internal_addrs.retain(|addr| !addr.is_private()); } - Ok(external_addrs.into_iter().chain(internal_addrs).collect()) + external_addrs.into_iter().chain(internal_addrs).collect() } /// Returns the default swarm configuration. @@ -118,7 +118,7 @@ pub(crate) fn default_tcp_config() -> tcp::Config { } /// Converts a secret key to a libp2p keypair. -pub(crate) fn keypair_from_secret_key(key: k256::SecretKey) -> crate::p2p::Result { +pub(crate) fn keypair_from_secret_key(key: &k256::SecretKey) -> crate::p2p::Result { let mut der = key.to_sec1_der()?; let keypair = Keypair::secp256k1_from_der(&mut der)?; Ok(keypair) diff --git a/crates/peerinfo/examples/peerinfo.rs b/crates/peerinfo/examples/peerinfo.rs index 05dea50a..338b7fc8 100644 --- a/crates/peerinfo/examples/peerinfo.rs +++ b/crates/peerinfo/examples/peerinfo.rs @@ -26,7 +26,7 @@ use pluto_p2p::{ p2p::{Node, NodeType}, }; use pluto_peerinfo::{Behaviour, Config, Event, LocalPeerInfo}; -use pluto_tracing::{LokiConfig, TracingConfig}; +use pluto_tracing::{ConsoleConfig, LokiConfig, TracingConfig}; use tokio::signal; use vise::MetricsCollection; use vise_exporter::MetricsExporter; @@ -167,9 +167,10 @@ fn handle_event(event: SwarmEvent, swarm: &mut Swarm TracingConfig { - let mut builder = TracingConfig::builder() - .with_default_console() - .override_env_filter(&args.log_level); + let builder = TracingConfig::builder() + .console(ConsoleConfig::default()) + .override_env_filter(args.log_level.clone()) + .metrics(true); if let Some(loki_url) = &args.loki_url { let mut labels: HashMap = HashMap::new(); @@ -181,14 +182,16 @@ fn build_tracing_config(args: &Args) -> TracingConfig { labels.insert(key.clone(), value.clone()); } - builder = builder.loki(LokiConfig { - loki_url: loki_url.clone(), - labels, - extra_fields: HashMap::new(), - }); + builder + .loki(LokiConfig { + loki_url: loki_url.clone(), + labels, + extra_fields: HashMap::new(), + }) + .build() + } else { + builder.build() } - - builder.build() } #[tokio::main] @@ -278,8 +281,8 @@ async fn main() -> anyhow::Result<()> { ); let Node { mut swarm, .. } = Node::new( - P2PConfig::default(), - key, + &P2PConfig::default(), + &key, false, NodeType::TCP, |key, relay_client| CombinedBehaviour { diff --git a/crates/relay-server/examples/relay_server.rs b/crates/relay-server/examples/relay_server.rs index dc57bd26..9560d1ed 100644 --- a/crates/relay-server/examples/relay_server.rs +++ b/crates/relay-server/examples/relay_server.rs @@ -33,7 +33,7 @@ async fn main() { let ct = CancellationToken::new(); tokio::select! { - result = run_relay_p2p_node(&config, key, ct.child_token()) => { + result = run_relay_p2p_node(&config, &key, ct.child_token()) => { result.expect("Failed to run relay P2P node"); } _ = tokio::signal::ctrl_c() => { diff --git a/crates/relay-server/src/p2p.rs b/crates/relay-server/src/p2p.rs index 239aee0e..4a9aad86 100644 --- a/crates/relay-server/src/p2p.rs +++ b/crates/relay-server/src/p2p.rs @@ -21,10 +21,10 @@ use pluto_p2p::{gater::ConnGater, p2p::Node}; #[instrument(skip(config, key, ct))] pub async fn run_relay_p2p_node( config: &Config, - key: SecretKey, + key: &SecretKey, ct: CancellationToken, ) -> Result> { - let mut node = Node::new_relay_server(&config.p2p_config, key.clone(), |key| { + let mut node = Node::new_relay_server(&config.p2p_config, key, |key| { RelayServerBehaviour::builder() .with_gater(ConnGater::new_open_gater()) .with_relay_config(create_relay_config(config)) diff --git a/crates/tracing/Cargo.toml b/crates/tracing/Cargo.toml index 18258af8..542a7603 100644 --- a/crates/tracing/Cargo.toml +++ b/crates/tracing/Cargo.toml @@ -7,6 +7,7 @@ license.workspace = true publish.workspace = true [dependencies] +bon.workspace = true tracing.workspace = true tracing-subscriber.workspace = true tracing-loki.workspace = true diff --git a/crates/tracing/examples/basic.rs b/crates/tracing/examples/basic.rs index 946fe3db..3e0eb577 100644 --- a/crates/tracing/examples/basic.rs +++ b/crates/tracing/examples/basic.rs @@ -13,7 +13,7 @@ //! You can see the logs in Grafana at http://localhost:3000. use std::{collections::HashMap, net::SocketAddr}; -use pluto_tracing::{LokiConfig, config::TracingConfig, init::init}; +use pluto_tracing::{ConsoleConfig, LokiConfig, config::TracingConfig, init::init}; use tracing::{debug, error, info, instrument, trace, warn}; use vise_exporter::MetricsExporter; @@ -21,14 +21,14 @@ use vise_exporter::MetricsExporter; async fn main() { // Initialize tracing with default console config let config = TracingConfig::builder() - .with_default_console() - .with_metrics(true) + .console(ConsoleConfig::default()) + .metrics(true) .loki(LokiConfig { loki_url: "http://localhost:3100".to_string(), labels: HashMap::new(), extra_fields: HashMap::new(), }) - .override_env_filter("debug") + .override_env_filter("debug".to_string()) .build(); let background_task = init(&config) diff --git a/crates/tracing/src/config.rs b/crates/tracing/src/config.rs index 5453bcbe..7067b3fe 100644 --- a/crates/tracing/src/config.rs +++ b/crates/tracing/src/config.rs @@ -1,7 +1,9 @@ use std::collections::HashMap; +use bon::Builder; + /// Configuration for the tracing. -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, Builder)] pub struct TracingConfig { /// Loki configuration. Enables loki logging if provided. If not - no loki /// logging is enabled. @@ -20,7 +22,7 @@ pub struct TracingConfig { } /// Configuration for the loki logging. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Builder)] pub struct LokiConfig { /// URL of the Loki instance. pub loki_url: String, @@ -33,7 +35,7 @@ pub struct LokiConfig { } /// Configuration for the console logging. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Builder)] pub struct ConsoleConfig { /// Whether to include the target module in logs. pub with_target: bool, @@ -66,120 +68,3 @@ impl Default for ConsoleConfig { } } } - -/// Builder for [`TracingConfig`]. -#[derive(Debug, Clone, Default)] -pub struct TracingConfigBuilder { - tracing_config: TracingConfig, -} - -impl TracingConfigBuilder { - /// Creates a new builder with default values. - pub fn new() -> Self { - Self::default() - } - - /// Sets the Loki configuration. - pub fn loki(mut self, config: LokiConfig) -> Self { - self.tracing_config.loki = Some(config); - self - } - - /// Sets the console configuration. - pub fn console(mut self, config: ConsoleConfig) -> Self { - self.tracing_config.console = Some(config); - self - } - - /// Enables console logging with default configuration. - pub fn with_default_console(mut self) -> Self { - self.tracing_config.console = Some(ConsoleConfig::default()); - self - } - - /// Enables console logging and configures whether to include the target - /// module. - pub fn console_with_target(mut self, with_target: bool) -> Self { - self.tracing_config - .console - .get_or_insert_with(ConsoleConfig::default) - .with_target = with_target; - self - } - - /// Enables console logging and configures whether to include the log level. - pub fn console_with_level(mut self, with_level: bool) -> Self { - self.tracing_config - .console - .get_or_insert_with(ConsoleConfig::default) - .with_level = with_level; - self - } - - /// Enables console logging and configures whether to include thread IDs. - pub fn console_with_thread_ids(mut self, with_thread_ids: bool) -> Self { - self.tracing_config - .console - .get_or_insert_with(ConsoleConfig::default) - .with_thread_ids = with_thread_ids; - self - } - - /// Enables console logging and configures whether to include the source - /// file name. - pub fn console_with_file(mut self, with_file: bool) -> Self { - self.tracing_config - .console - .get_or_insert_with(ConsoleConfig::default) - .with_file = with_file; - self - } - - /// Enables console logging and configures whether to include line numbers. - pub fn console_with_line_number(mut self, with_line_number: bool) -> Self { - self.tracing_config - .console - .get_or_insert_with(ConsoleConfig::default) - .with_line_number = with_line_number; - self - } - - /// Enables console logging and configures whether to use ANSI colors. - pub fn console_with_ansi(mut self, with_ansi: bool) -> Self { - self.tracing_config - .console - .get_or_insert_with(ConsoleConfig::default) - .with_ansi = with_ansi; - self - } - - /// Enables metrics logging. - pub fn with_metrics(mut self, enabled: bool) -> Self { - self.tracing_config.metrics = enabled; - self - } - - /// Sets whether metrics logging is enabled. - pub fn metrics(mut self, enabled: bool) -> Self { - self.tracing_config.metrics = enabled; - self - } - - /// Sets the environment filter override. - pub fn override_env_filter(mut self, filter: impl Into) -> Self { - self.tracing_config.override_env_filter = Some(filter.into()); - self - } - - /// Builds the [`TracingConfig`]. - pub fn build(self) -> TracingConfig { - self.tracing_config - } -} - -impl TracingConfig { - /// Creates a new builder for [`TracingConfig`]. - pub fn builder() -> TracingConfigBuilder { - TracingConfigBuilder::new() - } -} diff --git a/crates/tracing/src/init.rs b/crates/tracing/src/init.rs index cec0c373..d4390199 100644 --- a/crates/tracing/src/init.rs +++ b/crates/tracing/src/init.rs @@ -26,6 +26,12 @@ pub enum Error { type Result = std::result::Result; /// Initializes the tracing subscriber. +/// +/// # Errors +/// +/// - [`Error::InitError`] if the tracing subscriber cannot be initialized. +/// - [`Error::ParseError`] if the Loki URL cannot be parsed. +/// - [`Error::CreateLayerError`] if the Loki layer cannot be created. pub fn init(config: &TracingConfig) -> Result> { let env_filter = if let Some(override_env_filter) = config.override_env_filter.as_ref() { EnvFilter::from_str(override_env_filter).unwrap_or_else(|_| default_env_filter()) From 96b091ae6e2edbf8e2b898727ccada251179f8d7 Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:21:46 +0200 Subject: [PATCH 02/10] fix: some of clippy pedantic warnings --- crates/app/src/eth2wrap/mod.rs | 2 +- crates/app/src/eth2wrap/valcache.rs | 59 ++++++++++------- crates/app/src/featureset.rs | 20 +++--- crates/app/src/obolapi/client.rs | 34 +++++----- crates/app/src/obolapi/exit.rs | 13 ++-- crates/app/src/retry.rs | 19 +++--- crates/build-proto/src/lib.rs | 17 +++-- crates/cli/src/commands/create_enr.rs | 2 +- crates/cli/src/commands/enr.rs | 2 +- crates/cli/src/commands/version.rs | 5 +- crates/cli/src/error.rs | 2 +- crates/cluster/build.rs | 2 +- crates/cluster/src/definition.rs | 81 +++++++++++++----------- crates/cluster/src/deposit.rs | 6 +- crates/cluster/src/distvalidator.rs | 15 +++-- crates/cluster/src/eip712sigs.rs | 8 +-- crates/cluster/src/helpers.rs | 14 ++-- crates/cluster/src/lock.rs | 8 +-- crates/cluster/src/operator.rs | 2 +- crates/cluster/src/registration.rs | 2 +- crates/cluster/src/ssz.rs | 19 +++--- crates/cluster/src/ssz_hasher.rs | 8 +-- crates/core/src/consensus/protocols.rs | 10 ++- crates/core/src/corepb/v1.rs | 2 +- crates/core/src/qbft/fake_clock.rs | 4 +- crates/core/src/qbft/internal_test.rs | 12 ++-- crates/core/src/qbft/mod.rs | 55 ++++++++-------- crates/core/src/types.rs | 57 ++++++++++++++--- crates/core/src/version.rs | 13 ++-- crates/crypto/src/blst_impl.rs | 56 +++++++++------- crates/crypto/src/tbls.rs | 2 +- crates/crypto/src/types.rs | 2 +- crates/dkg/src/dkgpb/v1.rs | 2 +- crates/eth2api/build.rs | 8 +-- crates/eth2api/src/integration.rs | 4 +- crates/eth2api/src/lib.rs | 2 +- crates/eth2util/src/deposit/constants.rs | 4 +- crates/eth2util/src/deposit/mod.rs | 9 ++- crates/eth2util/src/deposit/types.rs | 18 +++--- crates/eth2util/src/eip712.rs | 10 +-- crates/eth2util/src/enr.rs | 18 ++++-- crates/eth2util/src/helpers.rs | 30 +++++---- crates/eth2util/src/network.rs | 28 ++++---- crates/eth2util/src/rlp.rs | 31 +++++++-- crates/k1util/benches/k1util.rs | 6 +- crates/k1util/src/k1util.rs | 6 +- crates/k1util/src/lib.rs | 2 +- crates/p2p/examples/metrics.rs | 2 +- crates/p2p/examples/p2p.rs | 4 +- crates/p2p/src/config.rs | 4 +- crates/p2p/src/conn_logger.rs | 5 +- crates/p2p/src/k1.rs | 14 ++-- crates/p2p/src/manet.rs | 14 ++-- crates/peerinfo/examples/peerinfo.rs | 4 +- crates/peerinfo/src/behaviour.rs | 2 + crates/peerinfo/src/config.rs | 9 +++ crates/peerinfo/src/handler.rs | 3 +- crates/peerinfo/src/lib.rs | 1 + crates/peerinfo/src/metrics.rs | 4 +- crates/peerinfo/src/protocol.rs | 11 ++-- crates/relay-server/src/behaviour.rs | 10 ++- crates/relay-server/src/config.rs | 2 +- crates/relay-server/src/metrics.rs | 2 +- crates/relay-server/src/p2p.rs | 6 +- crates/relay-server/src/utils.rs | 6 +- crates/relay-server/src/web.rs | 10 +-- crates/testutil/src/random.rs | 1 + crates/tracing/examples/basic.rs | 2 +- 68 files changed, 497 insertions(+), 350 deletions(-) diff --git a/crates/app/src/eth2wrap/mod.rs b/crates/app/src/eth2wrap/mod.rs index cfa28125..feaca08a 100644 --- a/crates/app/src/eth2wrap/mod.rs +++ b/crates/app/src/eth2wrap/mod.rs @@ -4,7 +4,7 @@ pub mod version; /// Cache of Validators retrieved from the Beacon node pub mod valcache; -/// Extensions module to the Eth2Api crate +/// Extensions module to the `Eth2Api` crate /// /// Includes additional data types and functions to reduce the boilerplate when /// interacting with `eth2api`. diff --git a/crates/app/src/eth2wrap/valcache.rs b/crates/app/src/eth2wrap/valcache.rs index e39f7ef6..d297f3bd 100644 --- a/crates/app/src/eth2wrap/valcache.rs +++ b/crates/app/src/eth2wrap/valcache.rs @@ -77,6 +77,7 @@ struct ValidatorCacheInner { impl ValidatorCache { /// Creates a new, empty validator cache. + #[must_use] pub fn new(eth2_cl: EthBeaconNodeApiClient, pubkeys: Vec) -> Self { Self(Arc::new(RwLock::new(ValidatorCacheInner { eth2_cl, @@ -101,14 +102,20 @@ impl ValidatorCache { if let (Some(active), Some(complete)) = (&inner.active, &inner.complete) { return Ok((active.clone(), complete.clone())); - }; + } let request = PostStateValidatorsRequest { path: PostStateValidatorsRequestPath { state_id: "head".into(), }, body: ValidatorRequestBody { - ids: Some(inner.pubkeys.iter().map(|pk| pk.to_string()).collect()), + ids: Some( + inner + .pubkeys + .iter() + .map(std::string::ToString::to_string) + .collect(), + ), ..Default::default() }, }; @@ -148,31 +155,37 @@ impl ValidatorCache { state_id: slot.to_string(), }, body: ValidatorRequestBody { - ids: Some(inner.pubkeys.iter().map(|pk| pk.to_string()).collect()), + ids: Some( + inner + .pubkeys + .iter() + .map(std::string::ToString::to_string) + .collect(), + ), ..Default::default() }, }; - let (response, refreshed_by_slot) = - match inner.eth2_cl.post_state_validators(request.clone()).await { - Ok(PostStateValidatorsResponse::Ok(response)) => (response, true), - _ => { - // Failed to fetch by slot, fall back to head state - request.path.state_id = "head".into(); - - let response = inner - .eth2_cl - .post_state_validators(request) - .await - .map_err(EthBeaconNodeApiClientError::RequestError) - .and_then(|response| match response { - PostStateValidatorsResponse::Ok(response) => Ok(response), - _ => Err(EthBeaconNodeApiClientError::UnexpectedResponse), - })?; - - (response, false) - } - }; + let (response, refreshed_by_slot) = if let Ok(PostStateValidatorsResponse::Ok(response)) = + inner.eth2_cl.post_state_validators(request.clone()).await + { + (response, true) + } else { + // Failed to fetch by slot, fall back to head state + request.path.state_id = "head".into(); + + let response = inner + .eth2_cl + .post_state_validators(request) + .await + .map_err(EthBeaconNodeApiClientError::RequestError) + .and_then(|response| match response { + PostStateValidatorsResponse::Ok(response) => Ok(response), + _ => Err(EthBeaconNodeApiClientError::UnexpectedResponse), + })?; + + (response, false) + }; let (active_validators, complete_validators) = validators_from_response(response)?; diff --git a/crates/app/src/featureset.rs b/crates/app/src/featureset.rs index 4417c6cf..6e553dbe 100644 --- a/crates/app/src/featureset.rs +++ b/crates/app/src/featureset.rs @@ -64,7 +64,7 @@ pub enum Feature { /// gnosis|chiado, unless the user disabled this feature explicitly. GnosisBlockHotfix, /// Enables Linear round timer for consensus rounds. - /// When active has precedence over EagerDoubleLinear round timer. + /// When active has precedence over `EagerDoubleLinear` round timer. Linear, /// Enables Scheduler to refresh duties when reorg occurs. SseReorgDuties, @@ -90,6 +90,7 @@ pub enum Feature { impl Feature { /// Returns the string representation of the feature. + #[must_use] pub fn as_str(self) -> &'static str { match self { Feature::MockAlpha => "mock_alpha", @@ -109,6 +110,7 @@ impl Feature { } /// Returns all known features. + #[must_use] pub fn all() -> &'static [Feature] { &[ Feature::MockAlpha, @@ -142,7 +144,7 @@ impl std::convert::TryFrom<&str> for Feature { .iter() .find(|feature| value.eq_ignore_ascii_case(feature.as_str())) .copied() - .ok_or_else(|| format!("unknown feature: {}", value)) + .ok_or_else(|| format!("unknown feature: {value}")) } } @@ -175,8 +177,9 @@ impl Default for FeatureSet { impl FeatureSet { /// Creates a new feature set with default configuration. + #[must_use] pub fn new() -> Self { - Self::from_config(Default::default()).expect("default config should always be valid") + Self::from_config(Config::default()).expect("default config should always be valid") } /// Creates a feature set from the given configuration. @@ -224,11 +227,11 @@ impl FeatureSet { }) } - /// Enables GnosisBlockHotfix if it was not disabled by the user. + /// Enables `GnosisBlockHotfix` if it was not disabled by the user. /// /// This is still a temporary workaround for the gnosis chain. /// When go-eth2-client is fully supporting custom specs, this function has - /// to be removed with GnosisBlockHotfix feature. + /// to be removed with `GnosisBlockHotfix` feature. pub fn enable_gnosis_block_hotfix_if_not_disabled(&mut self, config: &Config) { let disabled = config.disabled.contains(&Feature::GnosisBlockHotfix); @@ -243,6 +246,7 @@ impl FeatureSet { } /// Returns true if the feature is enabled. + #[must_use] pub fn enabled(&self, feature: Feature) -> bool { // Get feature status, default to Disable (0) if not found let feature_status = self.state.get(&feature).copied().unwrap_or(Status::Disable); @@ -251,6 +255,7 @@ impl FeatureSet { } /// Returns all custom enabled features. + #[must_use] pub fn custom_enabled_all(&self) -> Vec { let mut custom_enabled_features: Vec = Vec::new(); @@ -302,11 +307,10 @@ mod tests { for feature in features { let status = featureset.state.get(feature); - assert!(status.is_some(), "feature {} should have status", feature); + assert!(status.is_some(), "feature {feature} should have status"); assert!( *status.unwrap() != Status::Disable, - "feature {} should have positive status", - feature + "feature {feature} should have positive status" ); } } diff --git a/crates/app/src/obolapi/client.rs b/crates/app/src/obolapi/client.rs index cf7623e1..4f48ed70 100644 --- a/crates/app/src/obolapi/client.rs +++ b/crates/app/src/obolapi/client.rs @@ -29,7 +29,7 @@ pub struct Client { } /// Options for configuring the Obol API client. -#[derive(Debug, Default, Clone, Builder)] +#[derive(Debug, Default, Clone, Copy, Builder)] pub struct ClientOptions { /// Optional HTTP request timeout override (defaults to 10 seconds). pub timeout: Option, @@ -37,7 +37,7 @@ pub struct ClientOptions { impl Client { /// Creates a new Obol API client. - pub fn new(url_str: &str, options: ClientOptions) -> Result { + pub fn new(url_str: &str, options: &ClientOptions) -> Result { let req_timeout = options.timeout.unwrap_or(DEFAULT_TIMEOUT); let http_client = reqwest::Client::builder().timeout(req_timeout).build()?; @@ -46,7 +46,7 @@ impl Client { let normalized_url = if url_str.ends_with('/') { url_str.to_string() } else { - format!("{}/", url_str) + format!("{url_str}/") }; let base_url = Url::parse(&normalized_url)?; @@ -187,7 +187,7 @@ fn launchpad_url_path(lock: &Lock) -> String { #[cfg(test)] mod tests { use super::*; - use pluto_cluster::definition::Definition; + use pluto_cluster::definition::{Creator, Definition}; fn test_lock_with_hash(hash: Vec) -> Lock { Lock { @@ -198,13 +198,13 @@ mod tests { timestamp: "2024-01-01T00:00:00Z".to_string(), num_validators: 0, threshold: 0, - dkg_algorithm: "".to_string(), + dkg_algorithm: String::new(), fork_version: vec![], operators: vec![], - creator: Default::default(), + creator: Creator::default(), validator_addresses: vec![], deposit_amounts: vec![], - consensus_protocol: "".to_string(), + consensus_protocol: String::new(), target_gas_limit: 0, compounding: false, config_hash: vec![], @@ -222,7 +222,7 @@ mod tests { assert!( Client::new( "https://api.obol.tech", - ClientOptions::builder() + &ClientOptions::builder() .timeout(Duration::from_secs(10)) .build() ) @@ -232,27 +232,27 @@ mod tests { #[test] fn test_new_client_invalid_url() { - assert!(Client::new("not-a-url", ClientOptions::default()).is_err()); + assert!(Client::new("not-a-url", &ClientOptions::default()).is_err()); } #[test] fn test_base_url_normalization() { - let c1 = Client::new("https://api.obol.tech", ClientOptions::default()).unwrap(); + let c1 = Client::new("https://api.obol.tech", &ClientOptions::default()).unwrap(); assert_eq!(c1.base_url.as_str(), "https://api.obol.tech/"); - let c2 = Client::new("https://api.obol.tech/", ClientOptions::default()).unwrap(); + let c2 = Client::new("https://api.obol.tech/", &ClientOptions::default()).unwrap(); assert_eq!(c2.base_url.as_str(), "https://api.obol.tech/"); - let c3 = Client::new("https://api.obol.tech/v1", ClientOptions::default()).unwrap(); + let c3 = Client::new("https://api.obol.tech/v1", &ClientOptions::default()).unwrap(); assert_eq!(c3.base_url.as_str(), "https://api.obol.tech/v1/"); - let c4 = Client::new("https://api.obol.tech/v1/", ClientOptions::default()).unwrap(); + let c4 = Client::new("https://api.obol.tech/v1/", &ClientOptions::default()).unwrap(); assert_eq!(c4.base_url.as_str(), "https://api.obol.tech/v1/"); } #[test] fn test_build_url_root_base() { - let client = Client::new("https://api.obol.tech", ClientOptions::default()).unwrap(); + let client = Client::new("https://api.obol.tech", &ClientOptions::default()).unwrap(); assert_eq!( client.build_url("definition").unwrap().as_str(), "https://api.obol.tech/definition" @@ -272,7 +272,7 @@ mod tests { #[test] fn test_build_url_versioned_base() { - let client = Client::new("https://api.obol.tech/v1", ClientOptions::default()).unwrap(); + let client = Client::new("https://api.obol.tech/v1", &ClientOptions::default()).unwrap(); assert_eq!( client.build_url("definition").unwrap().as_str(), "https://api.obol.tech/v1/definition" @@ -300,13 +300,13 @@ mod tests { fn test_launchpad_url_for_lock() { let lock = test_lock_with_hash(vec![0x12, 0x34, 0xab, 0xcd]); - let c1 = Client::new("https://api.obol.tech", ClientOptions::default()).unwrap(); + let c1 = Client::new("https://api.obol.tech", &ClientOptions::default()).unwrap(); assert_eq!( c1.launchpad_url_for_lock(&lock).unwrap(), "https://api.obol.tech/lock/0x1234ABCD/launchpad" ); - let c2 = Client::new("https://api.obol.tech/v1", ClientOptions::default()).unwrap(); + let c2 = Client::new("https://api.obol.tech/v1", &ClientOptions::default()).unwrap(); assert_eq!( c2.launchpad_url_for_lock(&lock).unwrap(), "https://api.obol.tech/v1/lock/0x1234ABCD/launchpad" diff --git a/crates/app/src/obolapi/exit.rs b/crates/app/src/obolapi/exit.rs index a74e3259..216f6a66 100644 --- a/crates/app/src/obolapi/exit.rs +++ b/crates/app/src/obolapi/exit.rs @@ -169,7 +169,7 @@ pub struct PartialExitRequest { pub signature: Vec, } -/// DTO for JSON serialization of PartialExitRequest. +/// DTO for JSON serialization of `PartialExitRequest`. #[derive(Debug, Serialize, Deserialize)] struct PartialExitRequestDto { #[serde(flatten)] @@ -409,20 +409,17 @@ impl Client { /// Returns the partial exit Obol API URL for a given lock hash. fn submit_partial_exit_url(lock_hash: &str) -> String { - format!("/exp/partial_exits/{}", lock_hash) + format!("/exp/partial_exits/{lock_hash}") } /// Returns the delete partial exit Obol API URL. fn delete_partial_exit_url(val_pubkey: &str, lock_hash: &str, share_index: u64) -> String { - format!( - "/exp/partial_exits/{}/{}/{}", - lock_hash, share_index, val_pubkey - ) + format!("/exp/partial_exits/{lock_hash}/{share_index}/{val_pubkey}") } /// Returns the full exit Obol API URL. fn fetch_full_exit_url(val_pubkey: &str, lock_hash: &str, share_index: u64) -> String { - format!("/exp/exit/{}/{}/{}", lock_hash, share_index, val_pubkey) + format!("/exp/exit/{lock_hash}/{share_index}/{val_pubkey}") } #[cfg(test)] @@ -460,7 +457,7 @@ mod tests { let len = bytes.len(); let arr: [u8; 32] = bytes .try_into() - .map_err(|_| format!("expected 32 bytes, got {}", len))?; + .map_err(|_| format!("expected 32 bytes, got {len}"))?; Ok(arr) } diff --git a/crates/app/src/retry.rs b/crates/app/src/retry.rs index d6beeb31..ef5da22e 100644 --- a/crates/app/src/retry.rs +++ b/crates/app/src/retry.rs @@ -14,12 +14,14 @@ pub struct AsyncOptions { impl AsyncOptions { /// Set the backoff strategy. + #[must_use] pub fn with_backoff(mut self, backoff_builder: backon::ExponentialBuilder) -> Self { self.backoff_builder = backoff_builder; self } /// Set the deadline function. + #[must_use] pub fn with_deadline( mut self, deadline_fn: impl Fn(T) -> Option> + Send + Sync + 'static, @@ -31,6 +33,7 @@ impl AsyncOptions { /// Set the time provider function. This function should return the "current /// time", which will be compared with the deadline computed by the /// `deadline_fn`. + #[must_use] pub fn with_time( mut self, time_fn: impl Fn() -> chrono::DateTime + Send + Sync + 'static, @@ -40,6 +43,7 @@ impl AsyncOptions { } /// Set the [`CancellationToken`] if any. By default, no token is used. + #[must_use] pub fn with_cancellation_token(mut self, cancellation_token: CancellationToken) -> Self { self.cancellation_token = Some(cancellation_token); self @@ -84,12 +88,11 @@ impl Iterator for ExhaustedIterator { type Item = I::Item; fn next(&mut self) -> Option { - match self.inner.next() { - Some(item) => Some(item), - None => { - self.is_exhausted = true; - None - } + if let Some(item) = self.inner.next() { + Some(item) + } else { + self.is_exhausted = true; + None } } } @@ -149,7 +152,7 @@ pub async fn do_async< options .cancellation_token .as_ref() - .is_some_and(|t| t.is_cancelled()) + .is_some_and(tokio_util::sync::CancellationToken::is_cancelled) }; let mut attempt = 0u64; @@ -291,7 +294,7 @@ mod tests { options: retry::AsyncOptions::default() .with_backoff(test_backoff()) .with_time(move || now) - .with_deadline(move |_| Some(now)), + .with_deadline(move |()| Some(now)), func: Arc::new(|_| Err(DoAsyncError::RetryableError)), expected_attempts: 1, }) diff --git a/crates/build-proto/src/lib.rs b/crates/build-proto/src/lib.rs index ba42efd1..859fdf17 100644 --- a/crates/build-proto/src/lib.rs +++ b/crates/build-proto/src/lib.rs @@ -7,13 +7,13 @@ use std::{fs, io::Result, path::PathBuf}; /// Compiles the protobuf files in the given directory. pub fn compile_protos(proto_dir: &str) -> Result<()> { let proto_files: Vec = fs::read_dir(proto_dir)? - .filter_map(|entry| entry.ok()) + .filter_map(std::result::Result::ok) .map(|entry| entry.path()) .filter(|path| path.extension().is_some_and(|ext| ext == "proto")) .collect(); if proto_files.is_empty() { - println!("cargo:warning=No .proto files found in {}", proto_dir); + println!("cargo:warning=No .proto files found in {proto_dir}"); return Ok(()); } @@ -21,7 +21,10 @@ pub fn compile_protos(proto_dir: &str) -> Result<()> { config.btree_map(["."]).bytes(["."]).out_dir(proto_dir); config.compile_protos( - &proto_files.iter().map(|p| p.as_path()).collect::>(), + &proto_files + .iter() + .map(std::path::PathBuf::as_path) + .collect::>(), &[proto_dir], )?; @@ -36,16 +39,16 @@ pub fn compile_protos(proto_dir: &str) -> Result<()> { /// Adds file attributes to the generated files. fn add_file_attributes(proto_dir: &str) -> Result<()> { - let header = r#"// This file is @generated by prost-build. + let header = r"// This file is @generated by prost-build. #![allow(dead_code)] #![allow(missing_docs)] #![allow(clippy::all)] #![allow(rustdoc::all)] -"#; +"; let generated_files: Vec = fs::read_dir(proto_dir)? - .filter_map(|entry| entry.ok()) + .filter_map(std::result::Result::ok) .map(|entry| entry.path()) .filter(|path| { path.extension().is_some_and(|ext| ext == "rs") @@ -69,7 +72,7 @@ fn add_file_attributes(proto_dir: &str) -> Result<()> { } else { String::new() }; - let new_content = format!("{}{}", header, rest); + let new_content = format!("{header}{rest}"); fs::write(&file_path, new_content)?; } diff --git a/crates/cli/src/commands/create_enr.rs b/crates/cli/src/commands/create_enr.rs index 852991d8..430028eb 100644 --- a/crates/cli/src/commands/create_enr.rs +++ b/crates/cli/src/commands/create_enr.rs @@ -42,7 +42,7 @@ pub fn run(args: CreateEnrArgs) -> Result<()> { let mut writer = io::stdout(); writeln!(writer, "Created ENR private key: {}", key_path.display())?; - writeln!(writer, "{}", record)?; + writeln!(writer, "{record}")?; write_enr_warning(&mut writer, &key_path)?; Ok(()) diff --git a/crates/cli/src/commands/enr.rs b/crates/cli/src/commands/enr.rs index e7ec6feb..abcead86 100644 --- a/crates/cli/src/commands/enr.rs +++ b/crates/cli/src/commands/enr.rs @@ -49,7 +49,7 @@ pub fn run(args: EnrArgs) -> Result<()> { let record = Record::new(key.clone(), vec![])?; - writeln!(writer, "{}", record)?; + writeln!(writer, "{record}")?; if args.verbose { write_expanded_enr(&mut writer, &record, &key)?; diff --git a/crates/cli/src/commands/version.rs b/crates/cli/src/commands/version.rs index 16b3a6a9..18e26c30 100644 --- a/crates/cli/src/commands/version.rs +++ b/crates/cli/src/commands/version.rs @@ -41,7 +41,7 @@ fn run_with_writer(args: VersionArgs, writer: &mut W) -> Result<()> { writeln!(writer, "Consensus protocols:")?; for protocol in pluto_core::consensus::protocols::protocols() { - writeln!(writer, "\t{}", protocol)?; + writeln!(writer, "\t{protocol}")?; } Ok(()) @@ -137,8 +137,7 @@ mod tests { let first_protocol = protocols[0].to_string(); assert!( output.contains(&first_protocol), - "Verbose output should contain the first protocol: {}", - first_protocol + "Verbose output should contain the first protocol: {first_protocol}" ); } } diff --git a/crates/cli/src/error.rs b/crates/cli/src/error.rs index 6821f855..98925ec6 100644 --- a/crates/cli/src/error.rs +++ b/crates/cli/src/error.rs @@ -17,7 +17,7 @@ impl Termination for ExitResult { match self.0 { Ok(()) => ExitCode::SUCCESS, Err(err) => { - eprintln!("Error: {}", err); + eprintln!("Error: {err}"); ExitCode::FAILURE } } diff --git a/crates/cluster/build.rs b/crates/cluster/build.rs index 322a19d9..f86d0456 100644 --- a/crates/cluster/build.rs +++ b/crates/cluster/build.rs @@ -16,7 +16,7 @@ fn main() -> Result<()> { .out_dir(&out_dir) .compile_protos(&[proto_file], &["src/"])?; - println!("cargo:rerun-if-changed={}", proto_file); + println!("cargo:rerun-if-changed={proto_file}"); println!("cargo:rerun-if-changed=build.rs"); Ok(()) diff --git a/crates/cluster/src/definition.rs b/crates/cluster/src/definition.rs index 192bf6d0..d76dea4b 100644 --- a/crates/cluster/src/definition.rs +++ b/crates/cluster/src/definition.rs @@ -5,7 +5,10 @@ use crate::{ operator::{Operator, OperatorV1X1, OperatorV1X2OrLater}, ssz::{SSZError, hash_definition}, ssz_hasher::Hasher, - version::{CURRENT_VERSION, DKG_ALGO, versions::*}, + version::{ + CURRENT_VERSION, DKG_ALGO, + versions::{V1_0, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V1_9, V1_10}, + }, }; use chrono::{DateTime, Utc}; use libp2p::PeerId; @@ -25,8 +28,8 @@ pub const FORK_VERSION_LEN: usize = 4; /// Length of the address in bytes. pub const ADDRESS_LEN: usize = 20; -/// NodeIdx represents the index of a node/peer/share in the cluster as operator -/// order in cluster definition. +/// `NodeIdx` represents the index of a node/peer/share in the cluster as +/// operator order in cluster definition. #[derive(Debug, Clone, PartialEq, Eq)] pub struct NodeIdx { /// Index of a peer in the peer list (it's 0-indexed). @@ -94,13 +97,13 @@ impl Serialize for Definition { { match self.version.as_str() { V1_0 | V1_1 => DefinitionV1x0or1::try_from(self.clone()) - .map_err(|e| serde::ser::Error::custom(format!("Conversion error: {:?}", e)))? + .map_err(|e| serde::ser::Error::custom(format!("Conversion error: {e:?}")))? .serialize(serializer), V1_2 | V1_3 => DefinitionV1x2or3::try_from(self.clone()) - .map_err(|e| serde::ser::Error::custom(format!("Conversion error: {:?}", e)))? + .map_err(|e| serde::ser::Error::custom(format!("Conversion error: {e:?}")))? .serialize(serializer), V1_4 => DefinitionV1x4::try_from(self.clone()) - .map_err(|e| serde::ser::Error::custom(format!("Conversion error: {:?}", e)))? + .map_err(|e| serde::ser::Error::custom(format!("Conversion error: {e:?}")))? .serialize(serializer), V1_5 | V1_6 | V1_7 => DefinitionV1x5to7::from(self.clone()).serialize(serializer), V1_8 => DefinitionV1x8::from(self.clone()).serialize(serializer), @@ -134,21 +137,21 @@ impl<'de> Deserialize<'de> for Definition { serde_json::from_value(value).map_err(Error::custom)?; definition .try_into() - .map_err(|e| Error::custom(format!("Conversion error: {:?}", e))) + .map_err(|e| Error::custom(format!("Conversion error: {e:?}"))) } V1_2 | V1_3 => { let definition: DefinitionV1x2or3 = serde_json::from_value(value).map_err(Error::custom)?; definition .try_into() - .map_err(|e| Error::custom(format!("Conversion error: {:?}", e))) + .map_err(|e| Error::custom(format!("Conversion error: {e:?}"))) } V1_4 => { let definition: DefinitionV1x4 = serde_json::from_value(value).map_err(Error::custom)?; definition .try_into() - .map_err(|e| Error::custom(format!("Conversion error: {:?}", e))) + .map_err(|e| Error::custom(format!("Conversion error: {e:?}"))) } V1_5 | V1_6 | V1_7 => { let definition: DefinitionV1x5to7 = @@ -170,12 +173,12 @@ impl<'de> Deserialize<'de> for Definition { serde_json::from_value(value).map_err(Error::custom)?; Ok(definition.into()) } - _ => Err(Error::custom(format!("Unsupported version: {}", version))), + _ => Err(Error::custom(format!("Unsupported version: {version}"))), } } } -/// DefinitionError is an error type for definition errors. +/// `DefinitionError` is an error type for definition errors. #[derive(Debug, thiserror::Error)] pub enum DefinitionError { /// Multiple withdrawal or fee recipient addresses found @@ -257,7 +260,7 @@ pub enum DefinitionError { FailedToConvertTimestamp(#[from] serde_json::Error), } -/// InvalidGasLimitError is an error type for invalid gas limit errors. +/// `InvalidGasLimitError` is an error type for invalid gas limit errors. #[derive(Debug, thiserror::Error)] pub enum InvalidGasLimitError { /// The version does not support custom target gas limit @@ -385,7 +388,7 @@ impl Definition { Err(DefinitionError::PeerNotFound { peer_id: *pid }) } - /// VerifySignatures returns nil if all config signatures are fully + /// `VerifySignatures` returns nil if all config signatures are fully /// populated and valid. A verified definition is ready for use in DKG. pub fn verify_signatures(&self) -> Result<(), DefinitionError> { todo!("implement this after eth1wrap.EthClientRunner is implemented"); @@ -439,6 +442,7 @@ impl Definition { /// `withdrawal_addresses` is a convenience function to return all /// withdrawal address from the validator addresses slice. + #[must_use] pub fn withdrawal_addresses(&self) -> Vec { self.validator_addresses .iter() @@ -448,6 +452,7 @@ impl Definition { /// `fee_recipient_addresses` is a convenience function to return all fee /// recipient address from the validator addresses slice. + #[must_use] pub fn fee_recipient_addresses(&self) -> Vec { self.validator_addresses .iter() @@ -551,7 +556,7 @@ pub struct ValidatorAddresses { pub withdrawal_address: String, } -/// DefinitionV1x0or1 is a cluster definition for version 1.0.0 or 1.1.0 +/// `DefinitionV1x0or1` is a cluster definition for version 1.0.0 or 1.1.0 #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DefinitionV1x0or1 { @@ -662,7 +667,7 @@ impl TryFrom for Definition { } } -/// DefinitionV1x2or3 is a cluster definition for version 1.2.0 or 1.3.0 +/// `DefinitionV1x2or3` is a cluster definition for version 1.2.0 or 1.3.0 #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DefinitionV1x2or3 { @@ -691,7 +696,7 @@ pub struct DefinitionV1x2or3 { /// Withdrawal address for the /// validator. pub withdrawal_address: String, - /// DKGAlgorithm to use for key generation. Max 32 chars. + /// `DKGAlgorithm` to use for key generation. Max 32 chars. pub dkg_algorithm: String, /// Cluster's 4 byte beacon chain fork version /// (network/chain identifier). @@ -773,7 +778,7 @@ impl TryFrom for Definition { } } -/// DefinitionV1x4 is a cluster definition for version 1.4.0 +/// `DefinitionV1x4` is a cluster definition for version 1.4.0 #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DefinitionV1x4 { @@ -888,7 +893,7 @@ impl TryFrom for Definition { } } -/// DefinitionV1x5 is a cluster definition for version 1.5.0-1.7.0 +/// `DefinitionV1x5` is a cluster definition for version 1.5.0-1.7.0 #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DefinitionV1x5to7 { @@ -985,7 +990,7 @@ impl From for Definition { } } -/// DefinitionV1x8 is a cluster definition for version 1.8.0 +/// `DefinitionV1x8` is a cluster definition for version 1.8.0 #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DefinitionV1x8 { @@ -1005,30 +1010,30 @@ pub struct DefinitionV1x8 { /// chars. Note that this was added in v1.1.0, so may be empty for older /// versions. pub timestamp: String, - /// NumValidators is the number of DVs to be created in the cluster lock + /// `NumValidators` is the number of DVs to be created in the cluster lock /// file. pub num_validators: u64, /// Threshold required for signature reconstruction. Defaults to safe value /// for number of nodes/peers. pub threshold: u64, - /// ValidatorAddresses define addresses of each validator. + /// `ValidatorAddresses` define addresses of each validator. #[serde(rename = "validators")] pub validator_addresses: Vec, - /// DKGAlgorithm to use for key generation. Max 32 chars. + /// `DKGAlgorithm` to use for key generation. Max 32 chars. pub dkg_algorithm: String, - /// ForkVersion defines the cluster's 4 byte beacon chain fork version + /// `ForkVersion` defines the cluster's 4 byte beacon chain fork version /// (network/chain identifier). #[serde_as(as = "EthHex")] pub fork_version: Vec, - /// DepositAmounts specifies partial deposit amounts that sum up to at least - /// 32ETH. + /// `DepositAmounts` specifies partial deposit amounts that sum up to at + /// least 32ETH. #[serde_as(as = "DefaultOnNull>>")] pub deposit_amounts: Vec, - /// ConfigHash uniquely identifies a cluster definition excluding operator + /// `ConfigHash` uniquely identifies a cluster definition excluding operator /// ENRs and signatures. #[serde_as(as = "EthHex")] pub config_hash: Vec, - /// DefinitionHash uniquely identifies a cluster definition including + /// `DefinitionHash` uniquely identifies a cluster definition including /// operator ENRs and signatures. #[serde_as(as = "EthHex")] pub definition_hash: Vec, @@ -1087,7 +1092,7 @@ impl From for Definition { } } -/// DefinitionV1x9 is a cluster definition for version 1.9.0 +/// `DefinitionV1x9` is a cluster definition for version 1.9.0 #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DefinitionV1x9 { @@ -1107,33 +1112,33 @@ pub struct DefinitionV1x9 { /// chars. Note that this was added in v1.1.0, so may be empty for older /// versions. pub timestamp: String, - /// NumValidators is the number of DVs to be created in the cluster lock + /// `NumValidators` is the number of DVs to be created in the cluster lock /// file. pub num_validators: u64, /// Threshold required for signature reconstruction. Defaults to safe value /// for number of nodes/peers. pub threshold: u64, - /// ValidatorAddresses define addresses of each validator. + /// `ValidatorAddresses` define addresses of each validator. #[serde(rename = "validators")] pub validator_addresses: Vec, - /// DKGAlgorithm to use for key generation. Max 32 chars. + /// `DKGAlgorithm` to use for key generation. Max 32 chars. pub dkg_algorithm: String, - /// ForkVersion defines the cluster's 4 byte beacon chain fork version + /// `ForkVersion` defines the cluster's 4 byte beacon chain fork version /// (network/chain identifier). #[serde_as(as = "EthHex")] pub fork_version: Vec, - /// DepositAmounts specifies partial deposit amounts that sum up to at least - /// 32ETH. + /// `DepositAmounts` specifies partial deposit amounts that sum up to at + /// least 32ETH. #[serde_as(as = "DefaultOnNull>>")] pub deposit_amounts: Vec, - /// ConsensusProtocol is the consensus protocol name preferred by the + /// `ConsensusProtocol` is the consensus protocol name preferred by the /// cluster, e.g. "abft". pub consensus_protocol: String, - /// ConfigHash uniquely identifies a cluster definition excluding operator + /// `ConfigHash` uniquely identifies a cluster definition excluding operator /// ENRs and signatures. #[serde_as(as = "EthHex")] pub config_hash: Vec, - /// DefinitionHash uniquely identifies a cluster definition including + /// `DefinitionHash` uniquely identifies a cluster definition including /// operator ENRs and signatures. #[serde_as(as = "EthHex")] pub definition_hash: Vec, @@ -1193,7 +1198,7 @@ impl From for Definition { } } -/// DefinitionV1x10 is a cluster definition for version 1.10.0 +/// `DefinitionV1x10` is a cluster definition for version 1.10.0 #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DefinitionV1x10 { diff --git a/crates/cluster/src/deposit.rs b/crates/cluster/src/deposit.rs index ce6a43c4..fb3fe8e6 100644 --- a/crates/cluster/src/deposit.rs +++ b/crates/cluster/src/deposit.rs @@ -2,8 +2,8 @@ use crate::helpers::EthHex; use serde::{Deserialize, Serialize}; use serde_with::{DisplayFromStr, serde_as}; -/// DepositData defines the deposit data to activate a validator. -/// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#depositdata +/// `DepositData` defines the deposit data to activate a validator. +/// #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] pub struct DepositData { @@ -17,7 +17,7 @@ pub struct DepositData { pub withdrawal_credentials: Vec, /// Amount in Gwei to be deposited [1ETH..2048ETH]. - /// We use DisplayFromStr to allow for easy conversion from string to u64. + /// We use `DisplayFromStr` to allow for easy conversion from string to u64. #[serde_as(as = "DisplayFromStr")] pub amount: u64, diff --git a/crates/cluster/src/distvalidator.rs b/crates/cluster/src/distvalidator.rs index 54cbfe94..4c130f07 100644 --- a/crates/cluster/src/distvalidator.rs +++ b/crates/cluster/src/distvalidator.rs @@ -7,7 +7,7 @@ use serde_with::{ serde_as, }; -/// DistValidator is a distributed validator managed by the cluster. +/// `DistValidator` is a distributed validator managed by the cluster. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DistValidator { @@ -31,7 +31,7 @@ pub struct DistValidator { pub builder_registration: BuilderRegistration, } -/// DistValidatorError is an error type for DistValidator operations. +/// `DistValidatorError` is an error type for `DistValidator` operations. #[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] pub enum DistValidatorError { /// Invalid public key length. @@ -83,6 +83,7 @@ impl DistValidator { /// True if the validator has zero valued registration. /// registration. + #[must_use] pub fn zero_registration(&self) -> bool { self.builder_registration.signature.is_empty() && self.builder_registration.message.fee_recipient.is_empty() @@ -99,7 +100,7 @@ impl DistValidator { } } -/// DistValidatorV1x1 is a distributed validator managed by the cluster for +/// `DistValidatorV1x1` is a distributed validator managed by the cluster for /// version v1.0.0 or v1.1.0. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -142,7 +143,7 @@ impl From for DistValidator { } } } -/// DistValidatorV1x2to5 is a distributed validator managed by the cluster for +/// `DistValidatorV1x2to5` is a distributed validator managed by the cluster for /// version v1.2.0 to v1.5.0. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -185,7 +186,7 @@ impl From for DistValidator { } } } -/// DistValidatorV1x6 is a distributed validator managed by the cluster for +/// `DistValidatorV1x6` is a distributed validator managed by the cluster for /// version v1.6.0. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -231,7 +232,7 @@ impl From for DistValidator { } } -/// DistValidatorV1x7 is a distributed validator managed by the cluster for +/// `DistValidatorV1x7` is a distributed validator managed by the cluster for /// version v1.7.0. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -281,7 +282,7 @@ impl From for DistValidator { } } } -/// DistValidatorV1x8orLater is a distributed validator managed by the cluster +/// `DistValidatorV1x8orLater` is a distributed validator managed by the cluster /// for version v1.8.0 or later. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] diff --git a/crates/cluster/src/eip712sigs.rs b/crates/cluster/src/eip712sigs.rs index 4fcde7cf..87efa0d1 100644 --- a/crates/cluster/src/eip712sigs.rs +++ b/crates/cluster/src/eip712sigs.rs @@ -12,7 +12,7 @@ type ValueFunc = Box Value>; type Result = std::result::Result; -/// EIP712Error is the error type for EIP-712 errors. +/// `EIP712Error` is the error type for EIP-712 errors. #[derive(Debug, thiserror::Error)] pub enum EIP712Error { /// Failed to convert fork version to chain ID. @@ -171,8 +171,8 @@ fn sign_eip712( Ok(signature.to_vec()) } -/// sign_terms_and_conditions returns the EIP712 signature for Obol's Terms and -/// Conditions +/// `sign_terms_and_conditions` returns the EIP712 signature for Obol's Terms +/// and Conditions pub fn sign_terms_and_conditions( secret_key: &SecretKey, definition: &Definition, @@ -185,7 +185,7 @@ pub fn sign_terms_and_conditions( ) } -/// sign_cluster_definition_hash returns the EIP712 signature for the cluster +/// `sign_cluster_definition_hash` returns the EIP712 signature for the cluster /// definition hash pub fn sign_cluster_definition_hash( secret_key: &SecretKey, diff --git a/crates/cluster/src/helpers.rs b/crates/cluster/src/helpers.rs index fd794891..666797e5 100644 --- a/crates/cluster/src/helpers.rs +++ b/crates/cluster/src/helpers.rs @@ -5,8 +5,8 @@ use std::borrow::Cow; use crate::{definition::ADDRESS_LEN, ssz::SSZError, ssz_hasher::HashWalker}; -/// EthHex represents byte slices that are json formatted as 0x prefixed hex. -/// Can be used both as a standalone type and with serde_as. +/// `EthHex` represents byte slices that are json formatted as 0x prefixed hex. +/// Can be used both as a standalone type and with `serde_as`. #[derive(Debug, Clone, PartialEq, Eq)] pub struct EthHex(Vec); @@ -63,12 +63,14 @@ where // Helper methods and conversions impl EthHex { - /// Create a new EthHex from a byte slice. + /// Create a new `EthHex` from a byte slice. + #[must_use] pub fn new(bytes: Vec) -> Self { Self(bytes) } /// Inner bytes. + #[must_use] pub fn inner(&self) -> &Vec { &self.0 } @@ -99,7 +101,7 @@ impl TryFrom<&str> for EthHex { } } -/// TimestampSeconds represents a timestamp in seconds since the Unix epoch. +/// `TimestampSeconds` represents a timestamp in seconds since the Unix epoch. pub struct TimestampSeconds; impl SerializeAs> for TimestampSeconds { @@ -173,7 +175,7 @@ pub fn put_bytes_n(hh: &mut H, bytes: &[u8], n: usize) -> Result< if bytes.len() > n { return Err(SSZError::::IncorrectListSize { namespace: "put_bytes_n", - field: "".to_string(), + field: String::new(), actual: bytes.len(), expected: n, }); @@ -196,6 +198,7 @@ pub fn put_hex_bytes_20(hh: &mut H, address: &str) -> Result<(), /// `left_pad` returns the byte slice left padded with zero to ensure a length /// of at least len. +#[must_use] pub fn left_pad(bytes: &[u8], len: usize) -> Vec { if bytes.len() >= len { return bytes.to_vec(); @@ -207,6 +210,7 @@ pub fn left_pad(bytes: &[u8], len: usize) -> Vec { padded } /// `to_0x_hex` converts a byte slice to a 0x prefixed hex string. +#[must_use] pub fn to_0x_hex(bytes: &[u8]) -> String { if bytes.is_empty() { return String::new(); diff --git a/crates/cluster/src/lock.rs b/crates/cluster/src/lock.rs index 70a8c90d..53c4bf5b 100644 --- a/crates/cluster/src/lock.rs +++ b/crates/cluster/src/lock.rs @@ -11,7 +11,7 @@ use crate::{ helpers::EthHex, ssz::{SSZError, hash_lock}, ssz_hasher::Hasher, - version::versions::*, + version::versions::{V1_0, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V1_9, V1_10}, }; use pluto_eth2util::enr::{Record, RecordError}; use pluto_k1util::K1UtilError; @@ -20,7 +20,7 @@ use serde_with::{ serde_as, }; -/// LockError is the error type for Lock errors. +/// `LockError` is the error type for Lock errors. #[derive(Debug, thiserror::Error)] pub enum LockError { /// Unexpected validator registration @@ -179,7 +179,7 @@ impl<'de> Deserialize<'de> for Lock { let lock: LockV1x8orLater = serde_json::from_value(value).map_err(Error::custom)?; Ok(lock.into()) } - _ => Err(Error::custom(format!("Unsupported version: {}", version))), + _ => Err(Error::custom(format!("Unsupported version: {version}"))), } } } @@ -338,7 +338,7 @@ pub struct LockV1x2to5 { #[serde(rename = "distributed_validators")] pub distributed_validators: Vec, - /// LockHash uniquely identifies a cluster lock. + /// `LockHash` uniquely identifies a cluster lock. #[serde_as(as = "EthHex")] pub lock_hash: Vec, diff --git a/crates/cluster/src/operator.rs b/crates/cluster/src/operator.rs index dcd873a0..f75c6063 100644 --- a/crates/cluster/src/operator.rs +++ b/crates/cluster/src/operator.rs @@ -39,7 +39,7 @@ pub struct OperatorV1X1 { pub enr_signature: Vec, } -/// OperatorV1X2OrLater is the json formatter of Operator for versions v1.2.0 +/// `OperatorV1X2OrLater` is the json formatter of Operator for versions v1.2.0 /// and later. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "snake_case")] diff --git a/crates/cluster/src/registration.rs b/crates/cluster/src/registration.rs index 3fceab6f..a1bbbd56 100644 --- a/crates/cluster/src/registration.rs +++ b/crates/cluster/src/registration.rs @@ -4,7 +4,7 @@ use serde_with::serde_as; use crate::helpers::{EthHex, TimestampSeconds}; -/// BuilderRegistration defines pre-generated signed validator builder +/// `BuilderRegistration` defines pre-generated signed validator builder /// registration to be sent to builder network. #[serde_as] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] diff --git a/crates/cluster/src/ssz.rs b/crates/cluster/src/ssz.rs index 16495237..d7e142e1 100644 --- a/crates/cluster/src/ssz.rs +++ b/crates/cluster/src/ssz.rs @@ -6,7 +6,10 @@ use crate::{ lock::Lock, registration::{BuilderRegistration, Registration}, ssz_hasher::{HashWalker, Hasher, HasherError}, - version::{ZERO_NONCE, versions::*}, + version::{ + ZERO_NONCE, + versions::{V1_0, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V1_9, V1_10}, + }, }; /// Maximum length of the ENR. @@ -40,16 +43,16 @@ pub(crate) const SSZ_LEN_WITHDRAW_CREDS: usize = 32; /// Length of a public key. pub const SSZ_LEN_PUB_KEY: usize = 48; -/// HashFunc is a function that hashes a definition +/// `HashFunc` is a function that hashes a definition pub type HashFuncWithBool = fn(&T, &mut H, bool) -> Result<(), SSZError>; -/// HashFuncWithVersion is a function that hashes a definition with a version. +/// `HashFuncWithVersion` is a function that hashes a definition with a version. pub type HashFuncWithVersion = fn(&T, &mut H, &str) -> Result<(), SSZError>; -/// HashFunc is a function that hashes a definition. +/// `HashFunc` is a function that hashes a definition. pub type HashFunc = fn(&T, &mut H) -> Result<(), SSZError>; -/// SSZError is an error type for SSZ errors. +/// `SSZError` is an error type for SSZ errors. #[derive(Debug, thiserror::Error)] pub enum SSZError { /// Invalid length @@ -698,10 +701,10 @@ pub(crate) fn hash_validator_v1x5to7( let deposit_hash_func = get_deposit_data_hash_func(version)?; // Field (2) 'DepositData' Composite - let deposit_data = if !validator.partial_deposit_data.is_empty() { - &validator.partial_deposit_data[0] - } else { + let deposit_data = if validator.partial_deposit_data.is_empty() { &DepositData::default() + } else { + &validator.partial_deposit_data[0] }; deposit_hash_func(deposit_data, hh)?; diff --git a/crates/cluster/src/ssz_hasher.rs b/crates/cluster/src/ssz_hasher.rs index deb04834..03af3b6a 100644 --- a/crates/cluster/src/ssz_hasher.rs +++ b/crates/cluster/src/ssz_hasher.rs @@ -192,9 +192,8 @@ impl Hasher { if limit == 1 { if count == 1 { return Ok(input[..32].to_vec()); - } else { - return Ok(ZERO_BYTES.to_vec()); } + return Ok(ZERO_BYTES.to_vec()); } let depth = Self::get_depth(limit); @@ -347,9 +346,9 @@ impl HashWalker for Hasher { /// Append a boolean value. fn put_bool(&mut self, b: bool) -> Result<(), Self::Error> { if b { - self.buf.extend_from_slice(&TRUE_BYTES) + self.buf.extend_from_slice(&TRUE_BYTES); } else { - self.buf.extend_from_slice(&FALSE_BYTES) + self.buf.extend_from_slice(&FALSE_BYTES); } Ok(()) @@ -424,6 +423,7 @@ impl HashWalker for Hasher { } /// Calculate the limit for the merkleization with a mixin value. +#[must_use] pub fn calculate_limit(max_capacity: usize, num_items: usize, size: usize) -> usize { let limit = (max_capacity.saturating_mul(size)).div_ceil(32); if limit != 0 { diff --git a/crates/core/src/consensus/protocols.rs b/crates/core/src/consensus/protocols.rs index 2b9e8a88..009e6dbd 100644 --- a/crates/core/src/consensus/protocols.rs +++ b/crates/core/src/consensus/protocols.rs @@ -6,20 +6,23 @@ const PROTOCOL_ID_PREFIX: &str = "/charon/consensus/"; pub const QBFT_V2_PROTOCOL_ID: &str = "/charon/consensus/qbft/2.0.0"; /// Protocols supported by the Charon core. +#[must_use] pub fn protocols() -> Vec { vec![StreamProtocol::new(QBFT_V2_PROTOCOL_ID)] } /// Returns the most preferred consensus protocol from the list of protocols. +#[must_use] pub fn most_preferred_consensus_protocol<'a>(protocols: &[&'a str]) -> &'a str { protocols .iter() - .find(|p| p.to_string().starts_with(PROTOCOL_ID_PREFIX)) - .cloned() + .find(|p| (**p).to_string().starts_with(PROTOCOL_ID_PREFIX)) + .copied() .unwrap_or(QBFT_V2_PROTOCOL_ID) } /// Returns true if the protocol name is supported by the Charon core. +#[must_use] pub fn is_supported_protocol_name(name: &str) -> bool { let normalized_name = name.to_lowercase(); @@ -33,11 +36,12 @@ pub fn is_supported_protocol_name(name: &str) -> bool { } /// Prioritizes protocols matching the given name by moving them to the front. +#[must_use] pub fn prioritize_protocols_by_name( protocol_name: &str, all_protocols: &[StreamProtocol], ) -> Vec { - let target_prefix = format!("{}{}/", PROTOCOL_ID_PREFIX, protocol_name); + let target_prefix = format!("{PROTOCOL_ID_PREFIX}{protocol_name}/"); let (matching, others): (Vec<_>, Vec<_>) = all_protocols .iter() diff --git a/crates/core/src/corepb/v1.rs b/crates/core/src/corepb/v1.rs index 4c4c5b7d..b93e5505 100644 --- a/crates/core/src/corepb/v1.rs +++ b/crates/core/src/corepb/v1.rs @@ -2,7 +2,7 @@ pub mod consensus; /// Core protobuf definitions. pub mod core; -/// ParSigEx protobuf definitions. +/// `ParSigEx` protobuf definitions. pub mod parsigex; /// Priority protobuf definitions. pub mod priority; diff --git a/crates/core/src/qbft/fake_clock.rs b/crates/core/src/qbft/fake_clock.rs index 04e143f5..02470608 100644 --- a/crates/core/src/qbft/fake_clock.rs +++ b/crates/core/src/qbft/fake_clock.rs @@ -69,13 +69,13 @@ impl FakeClock { inner.now += duration; let now = inner.now; - for (&id, (ch, deadline)) in inner.clients.iter() { + for (&id, (ch, deadline)) in &inner.clients { if *deadline <= now { expired.push((id, ch.clone())); } } - for (id, _) in expired.iter() { + for (id, _) in &expired { inner.clients.remove(id); } diff --git a/crates/core/src/qbft/internal_test.rs b/crates/core/src/qbft/internal_test.rs index b7770251..39b03914 100644 --- a/crates/core/src/qbft/internal_test.rs +++ b/crates/core/src/qbft/internal_test.rs @@ -94,7 +94,7 @@ fn test_qbft(test: Test) { }) }, log_unjust: Box::new(|_, _, msg| { - println!("Unjust: {:?}", msg); + println!("Unjust: {msg:?}"); }), log_upon_rule: { let clock = clock.clone(); @@ -235,7 +235,7 @@ fn test_qbft(test: Test) { mpmc::select! { recv(broadcast_rx) -> msg => { let msg = msg.expect(READ_CHAN_ERR); - for (target, (out_tx, _)) in receives.iter() { + for (target, (out_tx, _)) in &receives { if *target == msg.source() { continue; // Do not broadcast to self, we sent to self already. } @@ -259,7 +259,7 @@ fn test_qbft(test: Test) { let q_commit = res.expect(READ_CHAN_ERR); for commit in q_commit.clone() { - for (_, previous) in results.iter() { + for (_, previous) in &results { assert_eq!(previous.value(), commit.value(), "commit values"); } @@ -295,9 +295,7 @@ fn test_qbft(test: Test) { let err = res.expect(READ_CHAN_ERR); if err.is_err() { - if !decided { - panic!("unexpected run error"); - } + assert!(decided, "unexpected run error"); } done += 1; @@ -758,7 +756,7 @@ fn duplicate_pre_prepare_rules() { return; } - panic!("unexpected round {}", round); + panic!("unexpected round {round}"); }); def.compare = Box::new(|_, _, _, _, return_err, _| { _ = return_err.send(Ok(())); diff --git a/crates/core/src/qbft/mod.rs b/crates/core/src/qbft/mod.rs index a686f1f6..d12b62fd 100644 --- a/crates/core/src/qbft/mod.rs +++ b/crates/core/src/qbft/mod.rs @@ -167,12 +167,14 @@ where { /// Quorum count for the system. /// See IBFT 2.0 paper for correct formula: + #[must_use] pub fn quorum(&self) -> i64 { (self.nodes as u64 * 2).div_ceil(3) as i64 } /// Maximum number of faulty/byzantine nodes supported in the system. /// See IBFT 2.0 paper for correct formula: + #[must_use] pub fn faulty(&self) -> i64 { (self.nodes - 1) / 3 } @@ -194,6 +196,7 @@ pub const MSG_DECIDED: MessageType = MessageType(5); const MSG_SENTINEL: MessageType = MessageType(6); // intentionally not public impl MessageType { + #[must_use] pub fn valid(&self) -> bool { self.0 > MSG_UNKNOWN.0 && self.0 < MSG_SENTINEL.0 } @@ -210,7 +213,7 @@ impl Display for MessageType { 5 => "decided", _ => panic!("bug: invalid message type"), }; - write!(f, "{}", s) + write!(f, "{s}") } } @@ -273,7 +276,7 @@ impl Display for UponRule { 8 => "round_timeout", _ => panic!("bug: invalid upon rule"), }; - write!(f, "{}", s) + write!(f, "{s}") } } @@ -353,9 +356,10 @@ where // and our own input value if present, otherwise it caches the justification // to be used when the input value becomes available. let broadcast_own_pre_prepare = |justification: Vec>| { - if ppj_cache.borrow().is_some() { - panic!("bug: justification cache must be none") - } + assert!( + !ppj_cache.borrow().is_some(), + "bug: justification cache must be none" + ); if *input_value.borrow() == Default::default() { // Can't broadcast a pre-prepare yet, need to wait for an input value. @@ -556,7 +560,7 @@ where // Only applicable to current round (round > 1) match get_single_justified_pr_pv(d, &justification) { Some((pr, pv)) if compare_failure_round != pr => { - broadcast_msg(MSG_PRE_PREPARE, &pv, Some(&justification))? + broadcast_msg(MSG_PRE_PREPARE, &pv, Some(&justification))?; } _ => broadcast_own_pre_prepare(justification)?, } @@ -636,7 +640,7 @@ where let err = msg?; return match err { - Ok(_) => Ok(result), + Ok(()) => Ok(result), Err(_) => Err(QbftError::CompareError), }; }, @@ -776,9 +780,7 @@ where V: PartialEq, { // Get all RoundChange messages with round (rj) higher than current round (ri) - if (frc.len() as i64) < d.faulty() + 1 { - panic!("bug: Frc too short"); - } + assert!(((frc.len() as i64) >= d.faulty() + 1), "bug: Frc too short"); // Get the smallest round in the set. let mut rmin = i64::MAX; @@ -818,15 +820,16 @@ where } } -/// Returns true if the ROUND_CHANGE message's prepared round and value is +/// Returns true if the `ROUND_CHANGE` message's prepared round and value is /// justified. fn is_justified_round_change(d: &Definition, msg: &Msg) -> bool where V: PartialEq + Default, { - if msg.type_() != MSG_ROUND_CHANGE { - panic!("bug: not a round change message"); - } + assert!( + !(msg.type_() != MSG_ROUND_CHANGE), + "bug: not a round change message" + ); // ROUND-CHANGE justification contains quorum PREPARE messages that justifies Pr // and Pv. @@ -873,9 +876,7 @@ fn is_justified_decided(d: &Definition, msg: &Msg) -> where V: PartialEq, { - if msg.type_() != MSG_DECIDED { - panic!("bug: not a decided message"); - } + assert!(!(msg.type_() != MSG_DECIDED), "bug: not a decided message"); let v = msg.value(); let commits = filter_msgs( @@ -900,9 +901,10 @@ fn is_justified_pre_prepare( where V: Eq + Hash + Default, { - if msg.type_() != MSG_PRE_PREPARE { - panic!("bug: not a preprepare message"); - } + assert!( + !(msg.type_() != MSG_PRE_PREPARE), + "bug: not a preprepare message" + ); if !(d.is_leader)(instance, msg.round(), msg.source()) { return false; @@ -926,7 +928,7 @@ where } /// Implements algorithm 4:1 and returns true and pv if the messages contains a -/// justified quorum ROUND_CHANGEs (Qrc). +/// justified quorum `ROUND_CHANGEs` (Qrc). fn contains_justified_qrc( d: &Definition, justification: &Vec>, @@ -945,7 +947,7 @@ where // J1: If qrc contains quorum ROUND-CHANGEs with null pv and null pr. let mut all_null = true; - for rc in qrc.iter() { + for rc in &qrc { if rc.prepared_round() != 0 || rc.prepared_value() != Default::default() { all_null = false; break; @@ -1018,7 +1020,8 @@ where } } -/// Implements algorithm 4:1 and returns a justified quorum ROUND_CHANGEs (Qrc) +/// Implements algorithm 4:1 and returns a justified quorum `ROUND_CHANGEs` +/// (Qrc) fn get_justified_qrc( d: &Definition, all: &Vec>, @@ -1043,7 +1046,7 @@ where let pv = prepares[0].value(); let mut uniq = uniq_source::(vec![]); - for rc in round_changes.iter() { + for rc in &round_changes { if rc.prepared_round() > pr { continue; } @@ -1271,9 +1274,7 @@ where resp.push(msg.clone()); for j in msg.justification() { resp.push(j.clone()); - if !j.justification().is_empty() { - panic!("bug: nested justifications"); - } + assert!(j.justification().is_empty(), "bug: nested justifications"); } } } diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 38f407af..94693741 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -47,22 +47,23 @@ impl Display for DutyType { // safe to unwrap because we know the duty type is valid let v = serde_json::to_value(self).expect("failed to serialize duty type"); if let Some(s) = v.as_str() { - write!(f, "{}", s) + write!(f, "{s}") } else { // fallback for non-string variants (structs, numbers, etc.) - write!(f, "{}", v) + write!(f, "{v}") } } } impl DutyType { /// Returns true if the duty type is valid. + #[must_use] pub fn is_valid(&self) -> bool { !matches!(self, DutyType::Unknown | DutyType::DutySentinel(_)) } } -/// SlotNumber struct +/// `SlotNumber` struct #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct SlotNumber(u64); @@ -86,16 +87,19 @@ impl From for u64 { impl SlotNumber { /// Create a new slot number. + #[must_use] pub fn new(slot: u64) -> Self { SlotNumber(slot) } /// Inner slot number. + #[must_use] pub fn inner(&self) -> u64 { self.0 } /// Next slot number. + #[must_use] pub fn next(&self) -> Self { Self::new(self.inner().saturating_add(1)) } @@ -118,71 +122,85 @@ impl Display for Duty { impl Duty { /// Create a new duty. + #[must_use] pub fn new(slot: SlotNumber, duty_type: DutyType) -> Self { Self { slot, duty_type } } /// Create a new attester duty. + #[must_use] pub fn new_attester_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::Attester) } /// Create a new randao duty. + #[must_use] pub fn new_randao_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::Randao) } /// Create a new voluntary exit duty. + #[must_use] pub fn new_voluntary_exit_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::Exit) } /// Create a new proposer duty. + #[must_use] pub fn new_proposer_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::Proposer) } /// Create a new builder proposer duty. + #[must_use] pub fn new_builder_proposer_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::BuilderProposer) } /// Create a new builder registration duty. + #[must_use] pub fn new_builder_registration_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::BuilderRegistration) } /// Create a new sync contribution duty. + #[must_use] pub fn new_sync_contribution_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::SyncContribution) } /// Create a new signature duty. + #[must_use] pub fn new_signature_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::Signature) } /// Create a new prepare aggregator duty. + #[must_use] pub fn new_prepare_aggregator_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::PrepareAggregator) } /// Create a new aggregator duty. + #[must_use] pub fn new_aggregator_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::Aggregator) } /// Create a new sync message duty. + #[must_use] pub fn new_sync_message_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::SyncMessage) } /// Create a new prepare sync contribution duty. + #[must_use] pub fn new_prepare_sync_contribution_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::PrepareSyncContribution) } /// Create a new info sync duty. + #[must_use] pub fn new_info_sync_duty(slot: SlotNumber) -> Self { Self::new(slot, DutyType::InfoSync) } @@ -271,11 +289,13 @@ pub enum PubKeyError { impl PubKey { /// Create a new public key. + #[must_use] pub fn new(pk: [u8; PK_LEN]) -> Self { PubKey(pk) } - /// Returns logging-friendly abbreviated form: "b82_97f" + /// Returns logging-friendly abbreviated form: "`b82_97f`" + #[must_use] pub fn abbreviated(&self) -> String { let hex = hex::encode(self.0); format!("{}_{}", &hex[0..3], &hex[93..96]) @@ -301,7 +321,7 @@ impl Display for PubKey { } } -/// Implement AsRef<[u8]> for PubKey to allow for easy conversion to bytes. +/// Implement `AsRef`<[u8]> for `PubKey` to allow for easy conversion to bytes. impl AsRef<[u8]> for PubKey { fn as_ref(&self) -> &[u8] { &self.0 @@ -336,11 +356,13 @@ where T: Clone + Serialize + StdDebug, { /// Create a new duty definition set. + #[must_use] pub fn new() -> Self { Self(HashMap::default()) } /// Get a duty definition by duty type. + #[must_use] pub fn get(&self, duty_type: &DutyType) -> Option<&DutyDefinition> { self.0.get(duty_type) } @@ -356,6 +378,7 @@ where } /// Inner duty definition set. + #[must_use] pub fn inner(&self) -> &HashMap> { &self.0 } @@ -399,11 +422,13 @@ where T: Clone + Serialize + StdDebug, { /// Create a new unsigned data set. + #[must_use] pub fn new() -> Self { Self::default() } /// Get an unsigned data by duty type. + #[must_use] pub fn get(&self, duty_type: &DutyType) -> Option<&UnsignedData> { self.0.get(duty_type) } @@ -419,6 +444,7 @@ where } /// Inner unsigned data set. + #[must_use] pub fn inner(&self) -> &HashMap> { &self.0 } @@ -436,6 +462,7 @@ pub struct Signature(pub(crate) [u8; SIG_LEN]); impl Signature { /// Create a new signature. + #[must_use] pub fn new(signature: [u8; SIG_LEN]) -> Self { Signature(signature) } @@ -449,18 +476,18 @@ pub trait SignedData: Clone + Serialize + StdDebug { /// signature returns the signed duty data's signature. fn signature(&self) -> Signature; - /// set_signature returns a copy of signed duty data with the signature + /// `set_signature` returns a copy of signed duty data with the signature /// replaced. fn set_signature(&mut self, signature: Signature) -> Result<(), Self::Error>; - /// message_root returns the message root for the unsigned data. + /// `message_root` returns the message root for the unsigned data. fn message_root(&self) -> [u8; 32]; } // todo: add Eth2SignedData type // https://github.com/ObolNetwork/charon/blob/b3008103c5429b031b63518195f4c49db4e9a68d/core/types.go#L396 -/// ParSignedData is a partially signed duty data only signed by a single +/// `ParSignedData` is a partially signed duty data only signed by a single /// threshold BLS share. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ParSignedData { @@ -484,7 +511,7 @@ where } } -/// ParSignedDataSet is a set of partially signed duty data only signed by a +/// `ParSignedDataSet` is a set of partially signed duty data only signed by a /// single threshold BLS share. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ParSignedDataSet(HashMap>); @@ -503,11 +530,13 @@ where T: SignedData, { /// Create a new partially signed data set. + #[must_use] pub fn new() -> Self { Self::default() } /// Get a partially signed data by public key. + #[must_use] pub fn get(&self, pub_key: &PubKey) -> Option<&ParSignedData> { self.inner().get(pub_key) } @@ -523,6 +552,7 @@ where } /// Inner partially signed data set. + #[must_use] pub fn inner(&self) -> &HashMap> { &self.0 } @@ -533,7 +563,7 @@ where } } -/// SignedDataSet is a set of signed duty data. +/// `SignedDataSet` is a set of signed duty data. #[derive(Debug, Clone, PartialEq, Eq)] pub struct SignedDataSet(HashMap); @@ -551,11 +581,13 @@ where T: SignedData, { /// Create a new signed data set. + #[must_use] pub fn new() -> Self { Self::default() } /// Get a signed data by public key. + #[must_use] pub fn get(&self, pub_key: &PubKey) -> Option<&T> { self.0.get(pub_key) } @@ -571,6 +603,7 @@ where } /// Inner signed data set. + #[must_use] pub fn inner(&self) -> &HashMap { &self.0 } @@ -599,6 +632,7 @@ pub struct Slot { impl Slot { /// Get the epoch of the slot + #[must_use] pub fn epoch(&self) -> u64 { #[allow(clippy::arithmetic_side_effects)] self.slot.inner().saturating_div(self.slots_per_epoch) @@ -606,6 +640,7 @@ impl Slot { /// Returns true if this is the last slot in the epoch. #[allow(clippy::arithmetic_side_effects)] + #[must_use] pub fn last_in_epoch(&self) -> bool { self.slot.inner().wrapping_rem(self.slots_per_epoch) == self.slots_per_epoch.saturating_sub(1) @@ -613,12 +648,14 @@ impl Slot { /// Returns true if this is the first slot in the epoch. #[allow(clippy::arithmetic_side_effects)] + #[must_use] pub fn first_in_epoch(&self) -> bool { self.slot.inner().wrapping_rem(self.slots_per_epoch) == 0 } /// Returns the next slot #[allow(clippy::arithmetic_side_effects)] + #[must_use] pub fn next_slot(&self) -> Slot { Slot { slot: self.slot.next(), diff --git a/crates/core/src/version.rs b/crates/core/src/version.rs index a33a1b0d..2c0c077a 100644 --- a/crates/core/src/version.rs +++ b/crates/core/src/version.rs @@ -16,7 +16,7 @@ pub enum SemVerError { pub static VERSION: LazyLock = LazyLock::new(|| { let str = env!("CARGO_PKG_VERSION"); - SemVer::parse(format!("v{}", str)).expect("invalid semantic version") + SemVer::parse(format!("v{str}")).expect("invalid semantic version") }); /// Supported minor versions in order of precedence. @@ -48,20 +48,23 @@ mod built_info { } /// Git commit hash and timestamp from build info. +#[must_use] pub fn git_commit() -> (String, String) { let hash = option_env!("GIT_COMMIT_HASH_SHORT") .or(built_info::GIT_COMMIT_HASH_SHORT) .unwrap_or("unknown") .into(); - let timestamp = chrono::DateTime::parse_from_rfc2822(built_info::BUILT_TIME_UTC) - .map(|dt| dt.to_rfc3339_opts(chrono::SecondsFormat::Secs, true)) - .unwrap_or_else(|_| "unknown".into()); + let timestamp = chrono::DateTime::parse_from_rfc2822(built_info::BUILT_TIME_UTC).map_or_else( + |_| "unknown".into(), + |dt| dt.to_rfc3339_opts(chrono::SecondsFormat::Secs, true), + ); (hash, timestamp) } /// Dependency list from build info in `name v{version}` format. +#[must_use] pub fn dependencies() -> Vec { let mut deps: Vec = built_info::DEPENDENCIES .iter() @@ -100,6 +103,7 @@ static SEMVER_REGEX: LazyLock = LazyLock::new(|| { impl SemVer { /// Returns true if the [`SemVer`] represents a tag for a pre-release. + #[must_use] pub fn is_pre_release(&self) -> bool { self.sem_ver_type == SemVerType::PreRelease } @@ -107,6 +111,7 @@ impl SemVer { /// Produces the minor version of the semantic version. /// It strips the `patch` version and `pre_release` label if /// present. + #[must_use] pub const fn to_minor(&self) -> SemVer { Self { sem_ver_type: SemVerType::Minor, diff --git a/crates/crypto/src/blst_impl.rs b/crates/crypto/src/blst_impl.rs index 84a14579..cfe88082 100644 --- a/crates/crypto/src/blst_impl.rs +++ b/crates/crypto/src/blst_impl.rs @@ -252,22 +252,22 @@ fn aggregate_public_keys(pks: &[BlstPublicKey]) -> Result unsafe { // Convert first key to projective form let first_affine: &blst::blst_p1_affine = (&pks[0]).into(); - blst::blst_p1_from_affine(&mut agg, first_affine); + blst::blst_p1_from_affine(&raw mut agg, first_affine); for pk in pks.iter().skip(1) { let pk_affine: &blst::blst_p1_affine = pk.into(); - blst::blst_p1_add_or_double_affine(&mut agg, &agg, pk_affine); + blst::blst_p1_add_or_double_affine(&raw mut agg, &raw const agg, pk_affine); } // Convert back to affine let mut agg_affine = blst::blst_p1_affine::default(); - blst::blst_p1_to_affine(&mut agg_affine, &agg); + blst::blst_p1_to_affine(&raw mut agg_affine, &raw const agg); Ok(BlstPublicKey::from(agg_affine)) } } /// Evaluate polynomial at point x -/// poly(x) = a_0 + a_1*x + a_2*x^2 + ... + a_n*x^n +/// poly(x) = `a_0` + `a_1`*x + `a_2`*x^2 + ... + `a_n`*x^n fn evaluate_polynomial(poly: &[BlstSecretKey], x: Index) -> Result { if poly.is_empty() { return Err(Error::PolynomialIsEmpty); @@ -295,7 +295,7 @@ fn evaluate_polynomial(poly: &[BlstSecretKey], x: Index) -> Result Result, Error> { // Check if indices are unique if indices.len() != indices.iter().collect::>().len() { @@ -401,7 +406,7 @@ fn compute_lagrange_coefficients(indices: &[Index]) -> Result blst::blst_scalar { let mut scalar = blst::blst_scalar::default(); unsafe { - blst::blst_scalar_from_uint64(&mut scalar, &val); + blst::blst_scalar_from_uint64(&raw mut scalar, &raw const val); } scalar } @@ -437,11 +442,16 @@ fn signature_mult(sig: &BlstSignature, scalar: &blst::blst_scalar) -> Result Result Result { let mut result = blst::blst_scalar::default(); unsafe { - if blst::blst_sk_add_n_check(&mut result, a, b) { + if blst::blst_sk_add_n_check(&raw mut result, a, b) { Ok(result) } else { Err(Error::FailedToAddScalars) @@ -466,7 +476,7 @@ fn scalar_mult_scalars( ) -> Result { let mut result = blst::blst_scalar::default(); unsafe { - if blst::blst_sk_mul_n_check(&mut result, a, b) { + if blst::blst_sk_mul_n_check(&raw mut result, a, b) { Ok(result) } else { Err(Error::FailedToMultiplyScalars) @@ -487,13 +497,13 @@ fn scalar_negate(a: &blst::blst_scalar) -> Result { let mut a_fr = blst::blst_fr::default(); let mut zero_fr = blst::blst_fr::default(); - blst::blst_fr_from_scalar(&mut a_fr, a); - blst::blst_fr_from_scalar(&mut zero_fr, &zero); + blst::blst_fr_from_scalar(&raw mut a_fr, a); + blst::blst_fr_from_scalar(&raw mut zero_fr, &raw const zero); let mut result_fr = blst::blst_fr::default(); - blst::blst_fr_sub(&mut result_fr, &zero_fr, &a_fr); + blst::blst_fr_sub(&raw mut result_fr, &raw const zero_fr, &raw const a_fr); - blst::blst_scalar_from_fr(&mut result_scalar, &result_fr); + blst::blst_scalar_from_fr(&raw mut result_scalar, &raw const result_fr); } Ok(result_scalar) @@ -512,7 +522,7 @@ fn scalar_div( let mut inv_scalar = blst::blst_scalar::default(); unsafe { - blst::blst_sk_inverse(&mut inv_scalar, denominator); + blst::blst_sk_inverse(&raw mut inv_scalar, denominator); } scalar_mult_scalars(numerator, &inv_scalar) @@ -554,7 +564,7 @@ mod tests { // Create signatures for each share let mut signatures = HashMap::new(); - for (idx, key) in shares.iter() { + for (idx, key) in &shares { let signature = blst.sign(key, data).unwrap(); signatures.insert(*idx, signature); } @@ -659,7 +669,7 @@ mod tests { // Split into shares and sign with each let shares = blst.threshold_split(&secret, 5, 3).unwrap(); let mut signatures = HashMap::new(); - for (idx, key) in shares.iter() { + for (idx, key) in &shares { let signature = blst.sign(key, data).unwrap(); signatures.insert(*idx, signature); } diff --git a/crates/crypto/src/tbls.rs b/crates/crypto/src/tbls.rs index e7d7f495..82c9a39c 100644 --- a/crates/crypto/src/tbls.rs +++ b/crates/crypto/src/tbls.rs @@ -40,7 +40,7 @@ pub trait Tbls { rng: impl RngCore + CryptoRng, ) -> Result, Error>; - /// ThresholdSplit splits a compressed secret into total units of secret + /// `ThresholdSplit` splits a compressed secret into total units of secret /// keys, with the given threshold. It returns a map that associates /// each private, compressed private key to its ID. /// diff --git a/crates/crypto/src/types.rs b/crates/crypto/src/types.rs index 03d208bf..1e0dd6b2 100644 --- a/crates/crypto/src/types.rs +++ b/crates/crypto/src/types.rs @@ -121,7 +121,7 @@ pub enum Error { /// BLST-specific error wrapper. /// -/// Wraps BLST_ERROR enum to provide idiomatic Rust error handling. +/// Wraps `BLST_ERROR` enum to provide idiomatic Rust error handling. #[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)] pub enum BlsError { /// Generic BLS error during key generation. diff --git a/crates/dkg/src/dkgpb/v1.rs b/crates/dkg/src/dkgpb/v1.rs index 2c469269..7f09479e 100644 --- a/crates/dkg/src/dkgpb/v1.rs +++ b/crates/dkg/src/dkgpb/v1.rs @@ -1,4 +1,4 @@ -/// BCast protobuf definitions. +/// `BCast` protobuf definitions. pub mod bcast; /// Frost protobuf definitions. pub mod frost; diff --git a/crates/eth2api/build.rs b/crates/eth2api/build.rs index cd311789..f1819a7e 100644 --- a/crates/eth2api/build.rs +++ b/crates/eth2api/build.rs @@ -1,4 +1,4 @@ -//! # Eth2Api +//! # `Eth2Api` //! //! Abstraction to multiple Ethereum 2 beacon nodes. Its external API follows //! the official [Ethereum beacon APIs specification](https://ethereum.github.io/beacon-APIs/). @@ -11,9 +11,9 @@ use std::{ const BEACON_NODE_OAPI_PATH: &str = "build/beacon-node-oapi.json"; -/// Generate the required code from the OpenAPI specification. +/// Generate the required code from the `OpenAPI` specification. pub fn main() -> Result<()> { - println!("cargo:rerun-if-changed={}", BEACON_NODE_OAPI_PATH); + println!("cargo:rerun-if-changed={BEACON_NODE_OAPI_PATH}"); let generator = std::process::Command::new("oas3-gen") .args([ @@ -75,7 +75,7 @@ fn ensure_serde_derives(path: &str) -> Result<()> { if has_deserialize && !has_serialize { // Find the position of Deserialize and add Serialize before it let new_inner = DESERIALIZE_RE.replace(inner, "Serialize, Deserialize"); - format!("#[derive({})]", new_inner) + format!("#[derive({new_inner})]") } else { // Don't change the derive attribute full_match.to_string() diff --git a/crates/eth2api/src/integration.rs b/crates/eth2api/src/integration.rs index ba007787..534e0891 100644 --- a/crates/eth2api/src/integration.rs +++ b/crates/eth2api/src/integration.rs @@ -42,7 +42,7 @@ async fn lighthouse_beacon_headers_head() { let host = container.get_host().await.expect("Failed to get host"); // Build an EthBeaconNodeApiClient - let base_url = format!("http://{}:{}", host, host_port); + let base_url = format!("http://{host}:{host_port}"); let client = EthBeaconNodeApiClient::with_base_url(base_url).expect("Failed to create client"); // Invoke the `get_block_header` API with "head" block ID @@ -56,7 +56,7 @@ async fn lighthouse_beacon_headers_head() { .expect("Failed to get block header"); let GetBlockHeaderResponse::Ok(headers) = response else { - panic!("Expected Ok response, got: {:?}", response) + panic!("Expected Ok response, got: {response:?}") }; // Validate the response diff --git a/crates/eth2api/src/lib.rs b/crates/eth2api/src/lib.rs index 0e0ef299..c51ea035 100644 --- a/crates/eth2api/src/lib.rs +++ b/crates/eth2api/src/lib.rs @@ -1,4 +1,4 @@ -//! # Eth2Api +//! # `Eth2Api` //! //! Abstraction to multiple Ethereum 2 beacon nodes. Its external API follows //! the official [Ethereum beacon APIs specification](https://ethereum.github.io/beacon-APIs/). diff --git a/crates/eth2util/src/deposit/constants.rs b/crates/eth2util/src/deposit/constants.rs index d054f804..06d25fa5 100644 --- a/crates/eth2util/src/deposit/constants.rs +++ b/crates/eth2util/src/deposit/constants.rs @@ -24,8 +24,8 @@ pub const ETH1_ADDRESS_WITHDRAWAL_PREFIX: u8 = 0x01; /// EIP-7251 address withdrawal prefix for compounding (0x02) pub const EIP7251_ADDRESS_WITHDRAWAL_PREFIX: u8 = 0x02; -/// DOMAIN_DEPOSIT type as per ETH2 spec -/// See: https://benjaminion.xyz/eth2-annotated-spec/phase0/beacon-chain/#domain-types +/// `DOMAIN_DEPOSIT` type as per ETH2 spec +/// See: pub const DEPOSIT_DOMAIN_TYPE: [u8; 4] = [0x03, 0x00, 0x00, 0x00]; /// Withdrawal credentials length (32 bytes) diff --git a/crates/eth2util/src/deposit/mod.rs b/crates/eth2util/src/deposit/mod.rs index d8799e1f..b906dd24 100644 --- a/crates/eth2util/src/deposit/mod.rs +++ b/crates/eth2util/src/deposit/mod.rs @@ -22,6 +22,7 @@ use pluto_crypto::{ use tree_hash::TreeHash; /// Returns the maximum deposit amount based on compounding flag. +#[must_use] pub fn max_deposit_amount(compounding: bool) -> Gwei { if compounding { MAX_COMPOUNDING_DEPOSIT_AMOUNT @@ -155,6 +156,7 @@ pub fn verify_deposit_amounts(amounts: &[Gwei], compounding: bool) -> Result<()> } /// Converts amounts from ETH (as integers) to Gwei. +#[must_use] pub fn eths_to_gweis(eth_amounts: &[u64]) -> Vec { eth_amounts .iter() @@ -163,6 +165,7 @@ pub fn eths_to_gweis(eth_amounts: &[u64]) -> Vec { } /// Deduplicates and sorts amounts in ascending order. +#[must_use] pub fn dedup_amounts(amounts: &[Gwei]) -> Vec { let mut result: Vec = amounts.to_vec(); result.sort_unstable(); @@ -171,6 +174,7 @@ pub fn dedup_amounts(amounts: &[Gwei]) -> Vec { } /// Returns the default deposit amounts based on compounding flag. +#[must_use] pub fn default_deposit_amounts(compounding: bool) -> Vec { if compounding { vec![ @@ -195,7 +199,7 @@ pub async fn write_cluster_deposit_data_files>( let cluster_dir = cluster_dir.as_ref(); for deposit_data_set in deposit_datas { for n in 0..num_nodes { - let node_dir = cluster_dir.join(format!("node{}", n)); + let node_dir = cluster_dir.join(format!("node{n}")); write_deposit_data_file(deposit_data_set.as_ref(), network, &node_dir).await?; } } @@ -247,7 +251,7 @@ pub fn get_deposit_file_path(data_dir: impl AsRef, amount: Gwei) -> PathBu // Convert Gwei to ETH and format #[allow(clippy::cast_precision_loss)] let eth = amount as f64 / ONE_ETH_IN_GWEI as f64; - format!("deposit-data-{}eth.json", eth) + format!("deposit-data-{eth}eth.json") }; data_dir.as_ref().join(filename) @@ -329,6 +333,7 @@ pub async fn read_deposit_data_files( } /// Merges two sets of deposit data files. +#[must_use] pub fn merge_deposit_data_sets( a: Vec>, b: Vec>, diff --git a/crates/eth2util/src/deposit/types.rs b/crates/eth2util/src/deposit/types.rs index f7b1b0e8..9cd9c423 100644 --- a/crates/eth2util/src/deposit/types.rs +++ b/crates/eth2util/src/deposit/types.rs @@ -18,8 +18,8 @@ pub type Root = [u8; 32]; /// Withdrawal credentials type (32 bytes). pub type WithdrawalCredentials = [u8; 32]; -/// DepositMessage represents the deposit message to be signed. -/// See: https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md#depositmessage +/// `DepositMessage` represents the deposit message to be signed. +/// See: #[derive(Debug, Clone, PartialEq, Eq, TreeHash)] pub struct DepositMessage { /// Validator's BLS public key (48 bytes) @@ -30,8 +30,8 @@ pub struct DepositMessage { pub amount: Gwei, } -/// DepositData defines the deposit data to activate a validator. -/// See: https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md#depositdata +/// `DepositData` defines the deposit data to activate a validator. +/// See: #[derive(Debug, Clone, PartialEq, Eq, TreeHash)] pub struct DepositData { /// Validator's BLS public key (48 bytes) @@ -44,8 +44,8 @@ pub struct DepositData { pub signature: Signature, } -/// ForkData is used for computing the deposit domain. -/// See: https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md#forkdata +/// `ForkData` is used for computing the deposit domain. +/// See: #[derive(Debug, Clone, PartialEq, Eq, TreeHash)] pub(crate) struct ForkData { /// Current fork version @@ -54,8 +54,8 @@ pub(crate) struct ForkData { pub genesis_validators_root: Root, } -/// SigningData is used for computing the signing root. -/// See: https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md#signingdata +/// `SigningData` is used for computing the signing root. +/// See: #[derive(Debug, Clone, PartialEq, Eq, TreeHash)] pub(crate) struct SigningData { /// Object root being signed @@ -64,7 +64,7 @@ pub(crate) struct SigningData { pub domain: Domain, } -/// DepositDataJson is the json representation of Deposit Data. +/// `DepositDataJson` is the json representation of Deposit Data. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DepositDataJson { /// Validator public key as hex string (without 0x prefix) diff --git a/crates/eth2util/src/eip712.rs b/crates/eth2util/src/eip712.rs index 226d675e..d9978491 100644 --- a/crates/eth2util/src/eip712.rs +++ b/crates/eth2util/src/eip712.rs @@ -5,16 +5,16 @@ use sha3::{Digest, Keccak256}; /// Primitive is a type alias for a string. pub type Primitive = String; -/// PRIMITIVE_STRING is the string primitive type. +/// `PRIMITIVE_STRING` is the string primitive type. pub const PRIMITIVE_STRING: &str = "string"; -/// PRIMITIVE_UINT64 is the uint64 primitive type. +/// `PRIMITIVE_UINT64` is the uint64 primitive type. pub const PRIMITIVE_UINT256: &str = "uint256"; -/// TERMS_AND_CONDITION_TYPE_NAME is the terms and conditions type name. +/// `TERMS_AND_CONDITION_TYPE_NAME` is the terms and conditions type name. pub const TERMS_AND_CONDITION_TYPE_NAME: &str = "TermsAndConditions"; -/// TypedData represents a dynamically typed EIP-712 message. +/// `TypedData` represents a dynamically typed EIP-712 message. #[derive(Debug, Clone, PartialEq)] pub struct TypedData { /// Domain of the EIP-712 message. @@ -109,7 +109,7 @@ fn domain_to_type(domain: &Domain) -> Type { type Result = std::result::Result; -/// Eip712Error is the error type for EIP-712 errors. +/// `Eip712Error` is the error type for EIP-712 errors. #[derive(Debug, thiserror::Error)] pub enum Eip712Error { /// Unsupported field type. diff --git a/crates/eth2util/src/enr.rs b/crates/eth2util/src/enr.rs index 179c06ba..a727a5a4 100644 --- a/crates/eth2util/src/enr.rs +++ b/crates/eth2util/src/enr.rs @@ -72,7 +72,7 @@ pub enum RecordError { FailedToConvertSignature(std::array::TryFromSliceError), } -/// InvalidFormatError is an error type for invalid format errors. +/// `InvalidFormatError` is an error type for invalid format errors. #[derive(Debug, thiserror::Error)] pub enum InvalidFormatError { /// Record does not start with 'enr:'. @@ -105,24 +105,27 @@ pub struct Record { kvs: HashMap>, } -/// OptionFn is a function that sets an option in the record. +/// `OptionFn` is a function that sets an option in the record. pub type OptionFn = Box>)>; -/// with_ip_impl is a function that sets the IP address in the record. +/// `with_ip_impl` is a function that sets the IP address in the record. +#[must_use] pub fn with_ip_impl(ip: Ipv4Addr) -> OptionFn { Box::new(move |kvs: &mut HashMap>| { kvs.insert(KEY_IP.to_string(), ip.octets().to_vec()); }) } -/// with_tcp_impl is a function that sets the TCP port in the record. +/// `with_tcp_impl` is a function that sets the TCP port in the record. +#[must_use] pub fn with_tcp_impl(tcp: u16) -> OptionFn { Box::new(move |kvs: &mut HashMap>| { kvs.insert(KEY_TCP.to_string(), tcp.to_be_bytes().to_vec()); }) } -/// with_udp_impl is a function that sets the UDP port in the record. +/// `with_udp_impl` is a function that sets the UDP port in the record. +#[must_use] pub fn with_udp_impl(udp: u16) -> OptionFn { Box::new(move |kvs: &mut HashMap>| { kvs.insert(KEY_UDP.to_string(), udp.to_be_bytes().to_vec()); @@ -156,6 +159,7 @@ impl Record { /// Returns the IP address of the record. /// /// Returns None if the IP address is not set. + #[must_use] pub fn ip(&self) -> Option { let value = self.kvs.get(KEY_IP)?; let bytes: [u8; 4] = value.as_slice().try_into().ok()?; @@ -165,6 +169,7 @@ impl Record { /// Returns the TCP port of the record. /// /// Returns None if the TCP port is not set. + #[must_use] pub fn tcp(&self) -> Option { let value = self.kvs.get(KEY_TCP)?; let bytes = value.as_slice().try_into().ok()?; @@ -174,6 +179,7 @@ impl Record { /// Returns the UDP port of the record. /// /// Returns None if the UDP port is not set. + #[must_use] pub fn udp(&self) -> Option { let value = self.kvs.get(KEY_UDP)?; let bytes = value.as_slice().try_into().ok()?; @@ -354,7 +360,7 @@ mod tests { ); let ip = r.ip().expect("IP address should be set"); - assert_eq!(ip, Ipv4Addr::new(127, 0, 0, 1)); + assert_eq!(ip, Ipv4Addr::LOCALHOST); let tcp = r.tcp().expect("TCP port should be set"); assert_eq!(tcp, 3610); diff --git a/crates/eth2util/src/helpers.rs b/crates/eth2util/src/helpers.rs index 601f8321..5a8f0c95 100644 --- a/crates/eth2util/src/helpers.rs +++ b/crates/eth2util/src/helpers.rs @@ -81,6 +81,7 @@ pub fn checksum_address(address: impl AsRef) -> Result { } /// Returns the EIP55-compliant 0xhex ethereum address of the public key. +#[must_use] pub fn public_key_to_address(pubkey: &PublicKey) -> String { // Alloy expects the 64-byte uncompressed public key without the 0x04 prefix let uncompressed = pubkey.to_encoded_point(false); @@ -175,7 +176,7 @@ mod tests { for addr in addrs { let result = checksum_address(addr); - assert!(result.is_err(), "Expected error for address: {}", addr); + assert!(result.is_err(), "Expected error for address: {addr}"); } } @@ -223,7 +224,7 @@ mod tests { }, TestCase { name: "empty", - headers: vec!["".to_string()], + headers: vec![String::new()], valid: false, }, TestCase { @@ -336,20 +337,21 @@ mod tests { for tt in tests { let parsed = parse_http_headers(&tt.headers); - if parsed.is_err() { - panic!( - "Test '{}': Header ({:?}) failed to parse", - tt.name, tt.headers - ); - } + assert!( + !parsed.is_err(), + "Test '{}': Header ({:?}) failed to parse", + tt.name, + tt.headers + ); let parsed = parsed.unwrap(); - if parsed != tt.want { - panic!( - "Test '{}': Headers badly parsed, have {:?}, want {:?}", - tt.name, parsed, tt.want - ); - } + assert!( + !(parsed != tt.want), + "Test '{}': Headers badly parsed, have {:?}, want {:?}", + tt.name, + parsed, + tt.want + ) } } } diff --git a/crates/eth2util/src/network.rs b/crates/eth2util/src/network.rs index 131d4185..69cd5a0c 100644 --- a/crates/eth2util/src/network.rs +++ b/crates/eth2util/src/network.rs @@ -42,23 +42,25 @@ type Result = std::result::Result; /// Network contains information about an Ethereum network. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct Network { - /// chain_id represents chain id of the network. + /// `chain_id` represents chain id of the network. pub chain_id: u64, /// name represents name of the network. pub name: &'static str, - /// genesis_fork_version_hex represents fork version of the network in hex. + /// `genesis_fork_version_hex` represents fork version of the network in + /// hex. pub genesis_fork_version_hex: &'static str, - /// genesis_timestamp represents genesis timestamp of the network in unix + /// `genesis_timestamp` represents genesis timestamp of the network in unix /// format. pub genesis_timestamp: u64, - /// capella_hard_fork represents capella fork version, used for computing + /// `capella_hard_fork` represents capella fork version, used for computing /// domains for signatures. pub capella_hard_fork: &'static str, } impl Network { - /// is_non_zero checks if each field in this struct is not equal to its zero - /// value. + /// `is_non_zero` checks if each field in this struct is not equal to its + /// zero value. + #[must_use] pub fn is_non_zero(&self) -> bool { self != &Network::default() } @@ -113,7 +115,7 @@ mod predefined { capella_hard_fork: "0x90000072", }; - /// Holesky network. Metadata taken from https://github.com/eth-clients/holesky#metadata. + /// Holesky network. Metadata taken from . pub const HOLESKY: Network = Network { chain_id: 17000, name: "holesky", @@ -122,7 +124,7 @@ mod predefined { capella_hard_fork: "0x04017000", }; - /// Hoodi network. Metadata taken from https://github.com/eth-clients/hoodi/#metadata. + /// Hoodi network. Metadata taken from . pub const HOODI: Network = Network { chain_id: 560048, name: "hoodi", @@ -220,6 +222,7 @@ pub fn network_to_fork_version_bytes(network: &str) -> Result> { } /// Valid network. +#[must_use] pub fn valid_network(name: &str) -> bool { network_from_name(name).is_ok() } @@ -340,18 +343,13 @@ mod tests { let unsupported_networks = vec!["ropsten"]; for network in supported_networks { - assert!( - valid_network(network), - "Network {} should be valid", - network - ); + assert!(valid_network(network), "Network {network} should be valid"); } for network in unsupported_networks { assert!( !valid_network(network), - "Network {} should be invalid", - network + "Network {network} should be invalid" ); } } diff --git a/crates/eth2util/src/rlp.rs b/crates/eth2util/src/rlp.rs index 0f8cf7c6..4abc8459 100644 --- a/crates/eth2util/src/rlp.rs +++ b/crates/eth2util/src/rlp.rs @@ -76,6 +76,7 @@ pub fn decode_bytes(input: &[u8]) -> Result> { } /// Encodes a single byte slice into RLP format. +#[must_use] pub fn encode_bytes(item: &[u8]) -> Vec { if item.len() == 1 && item[0] < 0x80 { return item.to_vec(); @@ -178,7 +179,12 @@ mod tests { let input = vec![b"cat".to_vec(), b"dog".to_vec()]; let expected = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; - let encoded = encode_bytes_list(&input.iter().map(|v| v.as_slice()).collect::>()); + let encoded = encode_bytes_list( + &input + .iter() + .map(std::vec::Vec::as_slice) + .collect::>(), + ); assert_eq!(encoded, expected); let decoded = decode_bytes_list(&encoded).unwrap(); @@ -190,7 +196,12 @@ mod tests { let input: Vec> = vec![]; let expected = vec![0xc0]; - let encoded = encode_bytes_list(&input.iter().map(|v| v.as_slice()).collect::>()); + let encoded = encode_bytes_list( + &input + .iter() + .map(std::vec::Vec::as_slice) + .collect::>(), + ); assert_eq!(encoded, expected); let decoded = decode_bytes_list(&encoded).unwrap(); @@ -215,7 +226,12 @@ mod tests { expected.extend_from_slice(LOREM_OUT); } - let encoded = encode_bytes_list(&input.iter().map(|v| v.as_slice()).collect::>()); + let encoded = encode_bytes_list( + &input + .iter() + .map(std::vec::Vec::as_slice) + .collect::>(), + ); assert_eq!(encoded, expected); let decoded = decode_bytes_list(&encoded).unwrap(); @@ -289,7 +305,7 @@ mod tests { let encoded = encode_bytes(&buf); let decoded = decode_bytes(&encoded).unwrap(); - assert_eq!(decoded, buf, "Failed for length {}", length); + assert_eq!(decoded, buf, "Failed for length {length}"); } } @@ -304,7 +320,12 @@ mod tests { #[test] fn test_roundtrip_bytes_list() { let items = vec![b"foo".to_vec(), b"bar".to_vec(), b"baz".to_vec()]; - let encoded = encode_bytes_list(&items.iter().map(|v| v.as_slice()).collect::>()); + let encoded = encode_bytes_list( + &items + .iter() + .map(std::vec::Vec::as_slice) + .collect::>(), + ); let decoded = decode_bytes_list(&encoded).unwrap(); assert_eq!(decoded, items); } diff --git a/crates/k1util/benches/k1util.rs b/crates/k1util/benches/k1util.rs index 49ccf04d..9c15b7ac 100644 --- a/crates/k1util/benches/k1util.rs +++ b/crates/k1util/benches/k1util.rs @@ -24,7 +24,7 @@ fn bench_sign(c: &mut Criterion) { let digest = vec![0u8; K1_HASH_LEN]; c.bench_function("sign", |b| { - b.iter(|| sign(black_box(&key), black_box(&digest)).expect("sign should succeed")) + b.iter(|| sign(black_box(&key), black_box(&digest)).expect("sign should succeed")); }); } @@ -37,7 +37,7 @@ fn bench_recover(c: &mut Criterion) { let recovered = recover(black_box(&digest), black_box(&sig)).expect("recover should succeed"); assert_eq!(recovered, pubkey); - }) + }); }); } @@ -54,7 +54,7 @@ fn bench_verify(c: &mut Criterion) { ) .expect("verify should succeed"); assert!(ok); - }) + }); }); } diff --git a/crates/k1util/src/k1util.rs b/crates/k1util/src/k1util.rs index 299c335a..923efa47 100644 --- a/crates/k1util/src/k1util.rs +++ b/crates/k1util/src/k1util.rs @@ -83,7 +83,7 @@ pub enum K1UtilError { type Result = std::result::Result; -/// Converts a libp2p PublicKey to a secp256k1 PublicKey. +/// Converts a libp2p `PublicKey` to a secp256k1 `PublicKey`. pub fn public_key_from_libp2p(pk: &Libp2pPublicKey) -> Result { let secp_key = pk.clone().try_into_secp256k1()?; PublicKey::from_sec1_bytes(&secp_key.to_bytes()) @@ -125,7 +125,7 @@ pub fn verify_65(pubkey: &PublicKey, hash: &[u8], sig: &[u8]) -> Result { Ok(recovered == *pubkey) } -/// verify_64 returns whether the 64 byte signature is valid for the provided +/// `verify_64` returns whether the 64 byte signature is valid for the provided /// hash and secp256k1 public key. /// /// Note the signature MUST be 64 bytes in the [R || S] format without recovery @@ -316,7 +316,7 @@ mod tests { for hex_str in hex_strs { let mut temp_file = tempfile::NamedTempFile::new().unwrap(); - write!(temp_file, "{}", hex_str).unwrap(); + write!(temp_file, "{hex_str}").unwrap(); let result = load(Path::new(&temp_file.path())); assert!( diff --git a/crates/k1util/src/lib.rs b/crates/k1util/src/lib.rs index debab0d6..182d6482 100644 --- a/crates/k1util/src/lib.rs +++ b/crates/k1util/src/lib.rs @@ -1,4 +1,4 @@ -//! # Charon K1Util +//! # Charon `K1Util` /// K1Util provides helper function for working with secp256k1 keys. mod k1util; diff --git a/crates/p2p/examples/metrics.rs b/crates/p2p/examples/metrics.rs index 9abc1f84..bb6cd91b 100644 --- a/crates/p2p/examples/metrics.rs +++ b/crates/p2p/examples/metrics.rs @@ -10,7 +10,7 @@ //! cargo run --example metrics -p pluto-p2p //! ``` //! -//! Metrics will be available in Grafana at http://localhost:3000. +//! Metrics will be available in Grafana at . use std::net::SocketAddr; diff --git a/crates/p2p/examples/p2p.rs b/crates/p2p/examples/p2p.rs index c83594fe..2d971323 100644 --- a/crates/p2p/examples/p2p.rs +++ b/crates/p2p/examples/p2p.rs @@ -37,8 +37,8 @@ pub struct Args { async fn main() -> Result<()> { let key = k256::SecretKey::random(&mut OsRng); let mut p2p: Node<_> = Node::new( - P2PConfig::default(), - key.clone(), + &P2PConfig::default(), + &key, false, NodeType::QUIC, PlutoMdnsBehaviour::new, diff --git a/crates/p2p/src/config.rs b/crates/p2p/src/config.rs index 541e026b..1ea1e2cf 100644 --- a/crates/p2p/src/config.rs +++ b/crates/p2p/src/config.rs @@ -309,11 +309,11 @@ mod tests { let tcp_addrs_str = tcp_multiaddrs .iter() - .map(|addr| addr.to_string()) + .map(std::string::ToString::to_string) .collect::>(); let udp_addrs_str = udp_multiaddrs .iter() - .map(|addr| addr.to_string()) + .map(std::string::ToString::to_string) .collect::>(); let merged_addrs_str = tcp_addrs_str diff --git a/crates/p2p/src/conn_logger.rs b/crates/p2p/src/conn_logger.rs index ada832da..8bc4a2df 100644 --- a/crates/p2p/src/conn_logger.rs +++ b/crates/p2p/src/conn_logger.rs @@ -21,7 +21,7 @@ use crate::{ /// Connection key for tracking connection counts. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -struct ConnKey { +pub(crate) struct ConnKey { peer_id: PeerId, connection_type: ConnectionType, protocol: Protocol, @@ -29,7 +29,7 @@ struct ConnKey { /// Existing connection. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -struct ExistingConnection { +pub(crate) struct ExistingConnection { peer_id: PeerId, connection_type: ConnectionType, } @@ -99,6 +99,7 @@ pub struct TestConnectionLoggerMetrics { impl TestConnectionLoggerMetrics { /// Returns the inner metrics for testing. #[cfg(test)] + #[must_use] pub fn inner(&self) -> &P2PMetrics { &self.metrics } diff --git a/crates/p2p/src/k1.rs b/crates/p2p/src/k1.rs index 2f9eee15..03113332 100644 --- a/crates/p2p/src/k1.rs +++ b/crates/p2p/src/k1.rs @@ -185,7 +185,9 @@ mod tests { assert!(backup_dir.exists()); assert!(backup_dir.is_dir()); - let entries: Vec<_> = fs::read_dir(&backup_dir)?.filter_map(|e| e.ok()).collect(); + let entries: Vec<_> = fs::read_dir(&backup_dir)? + .filter_map(std::result::Result::ok) + .collect(); assert_eq!(entries.len(), 1); Ok(()) @@ -208,7 +210,9 @@ mod tests { let backup_dir = data_dir.join(KEY_BACKUP_DIR); assert!(backup_dir.exists()); - let entries: Vec<_> = fs::read_dir(&backup_dir)?.filter_map(|e| e.ok()).collect(); + let entries: Vec<_> = fs::read_dir(&backup_dir)? + .filter_map(std::result::Result::ok) + .collect(); assert_eq!(entries.len(), 1); Ok(()) @@ -228,8 +232,10 @@ mod tests { } let backup_dir = data_dir.join(KEY_BACKUP_DIR); - let entries: Vec<_> = fs::read_dir(&backup_dir)?.filter_map(|e| e.ok()).collect(); - let backup_names: HashSet<_> = entries.iter().map(|e| e.file_name()).collect(); + let entries: Vec<_> = fs::read_dir(&backup_dir)? + .filter_map(std::result::Result::ok) + .collect(); + let backup_names: HashSet<_> = entries.iter().map(std::fs::DirEntry::file_name).collect(); assert_eq!( backup_names.len(), diff --git a/crates/p2p/src/manet.rs b/crates/p2p/src/manet.rs index 9f77965a..c745ea1d 100644 --- a/crates/p2p/src/manet.rs +++ b/crates/p2p/src/manet.rs @@ -310,7 +310,7 @@ mod tests { #[test] fn test_ipv4_private() { // Localhost - assert!(Ipv4Addr::new(127, 0, 0, 1).is_private_ip()); + assert!(Ipv4Addr::LOCALHOST.is_private_ip()); assert!(Ipv4Addr::new(127, 255, 255, 255).is_private_ip()); // 10.0.0.0/8 @@ -342,20 +342,20 @@ mod tests { assert!(Ipv4Addr::new(142, 250, 185, 14).is_public_ip()); // Private addresses are not public - assert!(!Ipv4Addr::new(127, 0, 0, 1).is_public_ip()); + assert!(!Ipv4Addr::LOCALHOST.is_public_ip()); assert!(!Ipv4Addr::new(10, 0, 0, 1).is_public_ip()); assert!(!Ipv4Addr::new(192, 168, 1, 1).is_public_ip()); // Unroutable addresses are not public - assert!(!Ipv4Addr::new(0, 0, 0, 0).is_public_ip()); - assert!(!Ipv4Addr::new(255, 255, 255, 255).is_public_ip()); + assert!(!Ipv4Addr::UNSPECIFIED.is_public_ip()); + assert!(!Ipv4Addr::BROADCAST.is_public_ip()); assert!(!Ipv4Addr::new(224, 0, 0, 1).is_public_ip()); // Multicast } #[test] fn test_ipv6_private() { // Localhost - assert!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).is_private_ip()); + assert!(Ipv6Addr::LOCALHOST.is_private_ip()); // ULA assert!(Ipv6Addr::new(0xfc00, 0, 0, 0, 0, 0, 0, 1).is_private_ip()); @@ -377,7 +377,7 @@ mod tests { assert!(Ipv6Addr::new(0x2606, 0x4700, 0x4700, 0, 0, 0, 0, 0x1111).is_public_ip()); // Private addresses are not public - assert!(!Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).is_public_ip()); + assert!(!Ipv6Addr::LOCALHOST.is_public_ip()); assert!(!Ipv6Addr::new(0xfc00, 0, 0, 0, 0, 0, 0, 1).is_public_ip()); assert!(!Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1).is_public_ip()); @@ -501,7 +501,7 @@ mod tests { } /// Test cases from the original Go implementation. - /// See: https://github.com/multiformats/go-multiaddr/blob/master/net/private_test.go + /// See: #[test] fn test_is_public_addr_go_compat() { struct TestCase { diff --git a/crates/peerinfo/examples/peerinfo.rs b/crates/peerinfo/examples/peerinfo.rs index 338b7fc8..269bfa6f 100644 --- a/crates/peerinfo/examples/peerinfo.rs +++ b/crates/peerinfo/examples/peerinfo.rs @@ -65,7 +65,7 @@ pub struct Args { #[arg(long, default_value = "info")] pub log_level: String, - /// Loki URL for log aggregation (e.g., http://localhost:3100) + /// Loki URL for log aggregation (e.g., ) #[arg(long)] pub loki_url: Option, @@ -78,7 +78,7 @@ pub struct Args { fn parse_key_value(s: &str) -> Result<(String, String), String> { let parts: Vec<&str> = s.splitn(2, '=').collect(); if parts.len() != 2 { - return Err(format!("Invalid key=value format: {}", s)); + return Err(format!("Invalid key=value format: {s}")); } Ok((parts[0].to_string(), parts[1].to_string())) } diff --git a/crates/peerinfo/src/behaviour.rs b/crates/peerinfo/src/behaviour.rs index c0f7062c..9c26cfb3 100644 --- a/crates/peerinfo/src/behaviour.rs +++ b/crates/peerinfo/src/behaviour.rs @@ -60,6 +60,7 @@ pub struct Behaviour { impl Behaviour { /// Creates a new [`Behaviour`] with the given configuration. + #[must_use] pub fn new(config: Config) -> Self { let name = &config.local_info().nickname; @@ -96,6 +97,7 @@ impl Behaviour { } /// Returns the current configuration. + #[must_use] pub fn config(&self) -> &Config { &self.config } diff --git a/crates/peerinfo/src/config.rs b/crates/peerinfo/src/config.rs index b3060e3f..babbe6e7 100644 --- a/crates/peerinfo/src/config.rs +++ b/crates/peerinfo/src/config.rs @@ -94,6 +94,7 @@ impl Config { /// * A peer info request is sent every 60 seconds on a healthy connection. /// * Every request must yield a response within 20 seconds to be /// successful. + #[must_use] pub fn new(local_info: LocalPeerInfo) -> Self { Self { timeout: DEFAULT_TIMEOUT, @@ -104,45 +105,53 @@ impl Config { } /// Sets the peer info request timeout. + #[must_use] pub fn with_timeout(mut self, d: Duration) -> Self { self.timeout = d; self } /// Sets the peer info exchange interval. + #[must_use] pub fn with_interval(mut self, d: Duration) -> Self { self.interval = d; self } /// Sets the local peer info. + #[must_use] pub fn with_local_info(mut self, info: LocalPeerInfo) -> Self { self.local_info = info; self } /// Sets the known peers. + #[must_use] pub fn with_peers(mut self, peers: Vec) -> Self { self.peers = peers; self } /// Returns the local peer info. + #[must_use] pub fn local_info(&self) -> &LocalPeerInfo { &self.local_info } /// Returns the timeout. + #[must_use] pub fn timeout(&self) -> Duration { self.timeout } /// Returns the interval. + #[must_use] pub fn interval(&self) -> Duration { self.interval } /// Returns the known peers. + #[must_use] pub fn peers(&self) -> &[PeerId] { &self.peers } diff --git a/crates/peerinfo/src/handler.rs b/crates/peerinfo/src/handler.rs index 5d722557..300ae5c4 100644 --- a/crates/peerinfo/src/handler.rs +++ b/crates/peerinfo/src/handler.rs @@ -76,6 +76,7 @@ enum State { impl Handler { /// Builds a new [`Handler`] with the given configuration. + #[must_use] pub fn new(config: Config, peer: PeerId) -> Self { let interval = config.interval(); let local_info = config.local_info().clone(); @@ -262,7 +263,7 @@ impl ConnectionHandler for Handler { )); } ConnectionEvent::DialUpgradeError(dial_upgrade_error) => { - self.on_dial_upgrade_error(dial_upgrade_error) + self.on_dial_upgrade_error(dial_upgrade_error); } _ => {} } diff --git a/crates/peerinfo/src/lib.rs b/crates/peerinfo/src/lib.rs index 331d0f86..b87f8db7 100644 --- a/crates/peerinfo/src/lib.rs +++ b/crates/peerinfo/src/lib.rs @@ -65,6 +65,7 @@ pub use handler::Success; pub const PROTOCOL_NAME: StreamProtocol = StreamProtocol::new("/charon/peerinfo/2.0.0"); /// Returns the supported protocols of this package in order of precedence. +#[must_use] pub fn protocols() -> Vec { vec![PROTOCOL_NAME] } diff --git a/crates/peerinfo/src/metrics.rs b/crates/peerinfo/src/metrics.rs index fe38f214..9d529b39 100644 --- a/crates/peerinfo/src/metrics.rs +++ b/crates/peerinfo/src/metrics.rs @@ -1,6 +1,6 @@ //! Metrics for the peerinfo protocol. -use vise::*; +use vise::{EncodeLabelSet, Family, Gauge, Global, LabeledFamily, Metrics}; /// Metrics for the peerinfo protocol. #[derive(Debug, Metrics)] @@ -13,7 +13,7 @@ pub struct PeerInfoMetrics { /// Constant gauge with version label set to peer's charon version. pub version: Family, - /// Constant gauge with git_hash label set to peer's git commit hash. + /// Constant gauge with `git_hash` label set to peer's git commit hash. pub git_commit: Family, /// Constant gauge set to the peer start time of the binary in unix seconds. diff --git a/crates/peerinfo/src/protocol.rs b/crates/peerinfo/src/protocol.rs index 2fe6ad70..d8d0ef28 100644 --- a/crates/peerinfo/src/protocol.rs +++ b/crates/peerinfo/src/protocol.rs @@ -139,6 +139,7 @@ fn supported_peer_version(version: &str, supported: &[SemVer]) -> Result<(), Pro impl ProtocolState { /// Creates a new protocol state. + #[must_use] pub fn new(peer_id: PeerId, local_info: LocalPeerInfo) -> Self { let name = pluto_p2p::name::peer_name(&peer_id); let mut nicknames = HashMap::new(); @@ -395,7 +396,7 @@ mod tests { assert!(GIT_HASH_RE.is_match("abc1234")); } - /// Helper to create a PeerInfo with minimal fields + /// Helper to create a `PeerInfo` with minimal fields fn make_minimal_peerinfo() -> PeerInfo { PeerInfo { pluto_version: "v1.0.0".to_string(), @@ -408,7 +409,7 @@ mod tests { } } - /// Helper to create a PeerInfo with git hash + /// Helper to create a `PeerInfo` with git hash fn make_with_git_hash_peerinfo() -> PeerInfo { PeerInfo { pluto_version: "v1.7.1".to_string(), @@ -421,7 +422,7 @@ mod tests { } } - /// Helper to create a full PeerInfo with all fields + /// Helper to create a full `PeerInfo` with all fields fn make_full_peerinfo() -> PeerInfo { PeerInfo { pluto_version: "v1.7.1".to_string(), @@ -440,7 +441,7 @@ mod tests { } } - /// Helper to create a PeerInfo with builder disabled + /// Helper to create a `PeerInfo` with builder disabled fn make_builder_disabled_peerinfo() -> PeerInfo { PeerInfo { pluto_version: "v1.5.0".to_string(), @@ -459,7 +460,7 @@ mod tests { } } - /// Helper to create a PeerInfo with empty optional fields + /// Helper to create a `PeerInfo` with empty optional fields fn make_empty_optional_peerinfo() -> PeerInfo { PeerInfo { pluto_version: "v1.6.0".to_string(), diff --git a/crates/relay-server/src/behaviour.rs b/crates/relay-server/src/behaviour.rs index de0ddaee..6e88259c 100644 --- a/crates/relay-server/src/behaviour.rs +++ b/crates/relay-server/src/behaviour.rs @@ -21,12 +21,14 @@ pub struct RelayServerBehaviour { } impl RelayServerBehaviour { - /// Creates a new RelayServerBehaviour with default configuration. + /// Creates a new `RelayServerBehaviour` with default configuration. + #[must_use] pub fn new(key: &Keypair) -> Self { RelayServerBehaviourBuilder::default().build(key) } - /// Returns a new builder for configuring a RelayServerBehaviour. + /// Returns a new builder for configuring a `RelayServerBehaviour`. + #[must_use] pub fn builder() -> RelayServerBehaviourBuilder { RelayServerBehaviourBuilder::default() } @@ -57,11 +59,13 @@ impl Default for RelayServerBehaviourBuilder { impl RelayServerBehaviourBuilder { /// Creates a new builder with default configuration. + #[must_use] pub fn new() -> Self { Self::default() } /// Sets the connection gater. + #[must_use] pub fn with_gater(mut self, gater: ConnGater) -> Self { self.gater = Some(gater); self @@ -74,6 +78,7 @@ impl RelayServerBehaviourBuilder { } /// Sets the relay server configuration. + #[must_use] pub fn with_relay_config(mut self, config: relay::Config) -> Self { self.relay_config = Some(config); self @@ -86,6 +91,7 @@ impl RelayServerBehaviourBuilder { } /// Builds the [`RelayServerBehaviour`] with the provided keypair. + #[must_use] pub fn build(self, key: &Keypair) -> RelayServerBehaviour { RelayServerBehaviour { relay: relay::Behaviour::new( diff --git a/crates/relay-server/src/config.rs b/crates/relay-server/src/config.rs index 412443c9..2fa6174a 100644 --- a/crates/relay-server/src/config.rs +++ b/crates/relay-server/src/config.rs @@ -39,7 +39,7 @@ pub struct Config { /// Whether to filter private addresses. #[builder(default = false)] pub filter_private_addrs: bool, - /// LibP2PLogLevel. + /// `LibP2PLogLevel`. #[builder(default = "Info".to_string())] pub libp2p_log_level: String, } diff --git a/crates/relay-server/src/metrics.rs b/crates/relay-server/src/metrics.rs index 7b741479..e893a341 100644 --- a/crates/relay-server/src/metrics.rs +++ b/crates/relay-server/src/metrics.rs @@ -1,4 +1,4 @@ -use vise::*; +use vise::{Counter, EncodeLabelSet, Family, Gauge, Global, Histogram, Metrics}; use pluto_p2p::metrics::BUCKETS; diff --git a/crates/relay-server/src/p2p.rs b/crates/relay-server/src/p2p.rs index 4a9aad86..1908e4fc 100644 --- a/crates/relay-server/src/p2p.rs +++ b/crates/relay-server/src/p2p.rs @@ -36,13 +36,13 @@ pub async fn run_relay_p2p_node( // todo: monitor connections - for tcp_addr in config.p2p_config.tcp_addrs.iter() { + for tcp_addr in &config.p2p_config.tcp_addrs { debug!("Listening on TCP address {}", tcp_addr); node.swarm .listen_on(tcp_addr.parse()?) .map_err(RelayP2PError::FailedToListenOnAddress)?; } - for udp_addr in config.p2p_config.udp_addrs.iter() { + for udp_addr in &config.p2p_config.udp_addrs { debug!("Listening on UDP address {}", udp_addr); node.swarm .listen_on(udp_addr.parse()?) @@ -71,7 +71,7 @@ pub async fn run_relay_p2p_node( loop { tokio::select! { biased; - _ = ct.cancelled() => { + () = ct.cancelled() => { info!("Relay server shutdown signal received, shutting down gracefully"); break; }, diff --git a/crates/relay-server/src/utils.rs b/crates/relay-server/src/utils.rs index 5c039d8f..294a7293 100644 --- a/crates/relay-server/src/utils.rs +++ b/crates/relay-server/src/utils.rs @@ -15,7 +15,7 @@ pub(crate) fn is_quic_addr(addr: &Multiaddr) -> bool { /// Returns true if the multiaddr is a public address. pub(crate) fn is_public_addr(addr: &Multiaddr) -> bool { - for protocol in addr.iter() { + for protocol in addr { match protocol { Protocol::Ip4(ip) => { return !ip.is_private() @@ -37,7 +37,7 @@ pub(crate) fn extract_ip_and_tcp_port(addr: &Multiaddr) -> Option<(Ipv4Addr, u16 let mut ip: Option = None; let mut port: Option = None; - for protocol in addr.iter() { + for protocol in addr { match protocol { Protocol::Ip4(i) => ip = Some(i), Protocol::Tcp(p) => port = Some(p), @@ -56,7 +56,7 @@ pub(crate) fn extract_ip_and_udp_port(addr: &Multiaddr) -> Option<(Ipv4Addr, u16 let mut ip: Option = None; let mut port: Option = None; - for protocol in addr.iter() { + for protocol in addr { match protocol { Protocol::Ip4(i) => ip = Some(i), Protocol::Udp(p) => port = Some(p), diff --git a/crates/relay-server/src/web.rs b/crates/relay-server/src/web.rs index 7f5b7ec5..3288767e 100644 --- a/crates/relay-server/src/web.rs +++ b/crates/relay-server/src/web.rs @@ -42,7 +42,7 @@ pub struct AppState { } impl AppState { - /// Creates a new AppState. + /// Creates a new `AppState`. pub fn new( p2p_config: P2PConfig, secret_key: SecretKey, @@ -211,7 +211,7 @@ pub async fn enr_handler( if tcp_ip != udp_ip { return Err(HandlerError { status: StatusCode::INTERNAL_SERVER_ERROR, - message: format!("conflicting IP addresses: tcp={}, udp={}", tcp_ip, udp_ip), + message: format!("conflicting IP addresses: tcp={tcp_ip}, udp={udp_ip}"), }); } (tcp_ip, tcp_p, udp_p) @@ -237,13 +237,13 @@ pub async fn enr_handler( ) .map_err(|e| HandlerError { status: StatusCode::INTERNAL_SERVER_ERROR, - message: format!("failed to create ENR: {}", e), + message: format!("failed to create ENR: {e}"), })?; Ok(record.to_string()) } -/// Applies IP override from config (external_ip or resolved external_host). +/// Applies IP override from config (`external_ip` or resolved `external_host`). async fn apply_ip_override(state: &AppState, original_ip: Ipv4Addr) -> Ipv4Addr { // First check external_ip config if let Some(external_ip) = &state.p2p_config.external_ip @@ -293,7 +293,7 @@ async fn resolve_external_host_periodically( loop { tokio::select! { biased; - _ = ct.cancelled() => { + () = ct.cancelled() => { info!("External host resolver shutdown complete"); break; } diff --git a/crates/testutil/src/random.rs b/crates/testutil/src/random.rs index 3b32830b..22aa4f8d 100644 --- a/crates/testutil/src/random.rs +++ b/crates/testutil/src/random.rs @@ -39,6 +39,7 @@ impl CryptoRng for ConstReader {} /// Generates a deterministic insecure secp256k1 private key using the provided /// seed. +#[must_use] pub fn generate_insecure_k1_key(seed: u8) -> SecretKey { // Add 1 to seed to avoid passing 0, which could cause issues let mut rng = ConstReader(seed.wrapping_add(1)); diff --git a/crates/tracing/examples/basic.rs b/crates/tracing/examples/basic.rs index 3e0eb577..0604a756 100644 --- a/crates/tracing/examples/basic.rs +++ b/crates/tracing/examples/basic.rs @@ -10,7 +10,7 @@ //! cargo run --example basic //! ``` //! -//! You can see the logs in Grafana at http://localhost:3000. +//! You can see the logs in Grafana at . use std::{collections::HashMap, net::SocketAddr}; use pluto_tracing::{ConsoleConfig, LokiConfig, config::TracingConfig, init::init}; From 7bd4b1d888a67ef685c53b998b17d2eec36dc431 Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:29:38 +0200 Subject: [PATCH 03/10] fix: some of clippy pedantic warnings --- crates/cli/src/commands/create_enr.rs | 2 +- crates/cli/src/commands/enr.rs | 2 +- crates/cli/src/commands/version.rs | 2 +- crates/cluster/src/definition.rs | 22 +++++++------- crates/cluster/src/distvalidator.rs | 4 +-- crates/cluster/src/lock.rs | 14 ++++----- .../src/manifestpb/cluster.manifestpb.v1.rs | 30 +++++++++---------- crates/core/src/qbft/internal_test.rs | 2 +- crates/core/src/qbft/mod.rs | 2 +- crates/eth2util/src/helpers.rs | 4 +-- crates/p2p/examples/p2p.rs | 23 +++++++------- crates/peerinfo/src/failure.rs | 4 +-- crates/peerinfo/src/protocol.rs | 8 ++--- crates/relay-server/src/behaviour.rs | 2 ++ crates/relay-server/src/utils.rs | 2 +- 15 files changed, 60 insertions(+), 63 deletions(-) diff --git a/crates/cli/src/commands/create_enr.rs b/crates/cli/src/commands/create_enr.rs index 430028eb..3c26690c 100644 --- a/crates/cli/src/commands/create_enr.rs +++ b/crates/cli/src/commands/create_enr.rs @@ -29,7 +29,7 @@ pub struct CreateEnrArgs { /// /// Stores a new charon-enr-private-key to disk and prints the ENR for the /// provided config. It returns an error if the key already exists. -pub fn run(args: CreateEnrArgs) -> Result<()> { +pub fn run(args: &CreateEnrArgs) -> Result<()> { if k1::load_priv_key(&args.data_dir).is_ok() { let enr_path = k1::key_path(&args.data_dir); return Err(CliError::PrivateKeyAlreadyExists { enr_path }); diff --git a/crates/cli/src/commands/enr.rs b/crates/cli/src/commands/enr.rs index abcead86..2a7b0035 100644 --- a/crates/cli/src/commands/enr.rs +++ b/crates/cli/src/commands/enr.rs @@ -30,7 +30,7 @@ pub struct EnrArgs { } /// Loads the p2pkey from disk and prints the ENR for the provided config. -pub fn run(args: EnrArgs) -> Result<()> { +pub fn run(args: &EnrArgs) -> Result<()> { let mut writer = io::stdout(); let key = match k1::load_priv_key(&args.data_dir) { diff --git a/crates/cli/src/commands/version.rs b/crates/cli/src/commands/version.rs index 18e26c30..8c2ba2c4 100644 --- a/crates/cli/src/commands/version.rs +++ b/crates/cli/src/commands/version.rs @@ -18,7 +18,7 @@ pub fn run(args: VersionArgs) -> Result<()> { } /// Runs the version command with a custom writer (used for testing). -fn run_with_writer(args: VersionArgs, writer: &mut W) -> Result<()> { +fn run_with_writer(args: &VersionArgs, writer: &mut W) -> Result<()> { let (hash, timestamp) = pluto_core::version::git_commit(); writeln!( writer, diff --git a/crates/cluster/src/definition.rs b/crates/cluster/src/definition.rs index d76dea4b..e64b29be 100644 --- a/crates/cluster/src/definition.rs +++ b/crates/cluster/src/definition.rs @@ -279,9 +279,9 @@ impl Definition { name: String, num_validators: u64, threshold: u64, - fee_recipient_addresses: Vec, - withdrawal_addresses: Vec, - fork_version_hex: String, + fee_recipient_addresses: &[String], + withdrawal_addresses: &[String], + fork_version_hex: impl AsRef, creator: Creator, operators: Vec, deposit_amounts: Vec, @@ -314,7 +314,7 @@ impl Definition { num_validators, threshold, dkg_algorithm: DKG_ALGO.to_string(), - fork_version: Default::default(), + fork_version: Vec::new(), operators, creator, validator_addresses: Vec::new(), @@ -322,8 +322,8 @@ impl Definition { consensus_protocol, target_gas_limit, compounding, - config_hash: Default::default(), - definition_hash: Default::default(), + config_hash: Vec::new(), + definition_hash: Vec::new(), }; def.validator_addresses = fee_recipient_addresses @@ -335,7 +335,7 @@ impl Definition { }) .collect(); - def.fork_version = from_0x_hex_str(&fork_version_hex, FORK_VERSION_LEN)?; + def.fork_version = from_0x_hex_str(fork_version_hex.as_ref(), FORK_VERSION_LEN)?; for opt in opts { opt(&mut def); @@ -1312,7 +1312,7 @@ impl From for Definition { } } -fn repeat_v_addresses(addr: ValidatorAddresses, num_validators: u64) -> Vec { +fn repeat_v_addresses(addr: &ValidatorAddresses, num_validators: u64) -> Vec { let mut validator_addresses = Vec::new(); for _ in 0..num_validators { validator_addresses.push(addr.clone()); @@ -1408,12 +1408,12 @@ mod tests { // Verify deposit amounts assert_eq!(definition.deposit_amounts.len(), 2); - assert_eq!(definition.deposit_amounts[0], 16000000000); - assert_eq!(definition.deposit_amounts[1], 16000000000); + assert_eq!(definition.deposit_amounts[0], 16_000_000_000); + assert_eq!(definition.deposit_amounts[1], 16_000_000_000); // Verify v1.10.0 specific fields assert_eq!(definition.consensus_protocol, "abft"); - assert_eq!(definition.target_gas_limit, 30000000); + assert_eq!(definition.target_gas_limit, 30_000_000); assert!(!definition.compounding); // Verify hashes are present diff --git a/crates/cluster/src/distvalidator.rs b/crates/cluster/src/distvalidator.rs index 4c130f07..f3be943a 100644 --- a/crates/cluster/src/distvalidator.rs +++ b/crates/cluster/src/distvalidator.rs @@ -128,7 +128,7 @@ impl From for DistValidatorV1x0or1 { Self { pub_key: dist_validator.pub_key, pub_shares: dist_validator.pub_shares, - fee_recipient_address: Default::default(), + fee_recipient_address: Vec::new(), } } } @@ -171,7 +171,7 @@ impl From for DistValidatorV1x2to5 { Self { pub_key: dist_validator.pub_key, pub_shares: dist_validator.pub_shares, - fee_recipient_address: Default::default(), + fee_recipient_address: Vec::new(), } } } diff --git a/crates/cluster/src/lock.rs b/crates/cluster/src/lock.rs index 53c4bf5b..5ccbacf9 100644 --- a/crates/cluster/src/lock.rs +++ b/crates/cluster/src/lock.rs @@ -598,7 +598,7 @@ mod tests { .builder_registration .message .gas_limit, - 30000000 + 30_000_000 ); assert_eq!( lock.distributed_validators[0] @@ -606,7 +606,7 @@ mod tests { .message .timestamp .timestamp(), - 1655733600 + 1_655_733_600 ); assert_eq!(lock.distributed_validators[0].builder_registration.message.pub_key, hex::decode("1814be823350eab13935f31d84484517e924aef78ae151c00755925836b7075885650c30ec29a3703934bf50a28da102").unwrap()); assert_eq!(lock.distributed_validators[0].builder_registration.signature, hex::decode("d313c8a3b4c1c0e05447f4ba370eb36dbcfdec90b302dcdc3b9ef522e2a6f1ed0afec1f8e20faabedf6b162e717d3a748a58677a0c56348f8921a266b11d0f334c62fe52ba53af19779cb2948b6570ffa0b773963c130ad797ddeafe4e3ad29b").unwrap()); @@ -631,7 +631,7 @@ mod tests { ); assert_eq!( lock.distributed_validators[0].partial_deposit_data[1].amount, - 8817733914007551237 + 8_817_733_914_007_551_237 ); assert_eq!(lock.distributed_validators[0].partial_deposit_data[1].signature, hex::decode("332088a8b07590bafcccbec6177536401d9a2b7f512b54bfc9d00532adf5aaa7c3a96bc59b489f77d9042c5bce26b163defde5ee6a0fbb3e9346cef81f0ae9515ef30fa47a364e75aea9e111d596e685a591121966e031650d510354aa845580").unwrap()); @@ -654,7 +654,7 @@ mod tests { .builder_registration .message .gas_limit, - 30000000 + 30_000_000 ); assert_eq!( lock.distributed_validators[1] @@ -662,7 +662,7 @@ mod tests { .message .timestamp .timestamp(), - 1655733600 + 1_655_733_600 ); assert_eq!(lock.distributed_validators[1].builder_registration.message.pub_key, hex::decode("5125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00ce73bff706f7ff4b6f44090a32711f3208e4e").unwrap()); assert_eq!(lock.distributed_validators[1].builder_registration.signature, hex::decode("e65a31bd5d41e2d2ce9c2b17892f0fea1931a290220777a93143dfdcbfa68406e877073ff08834e197a4034aa48afa3f85b8a62708caebbac880b5b89b93da53810164402104e648b6226a1b78021851f5d9ac0f313a89ddfc454c5f8f72ac89").unwrap()); @@ -677,7 +677,7 @@ mod tests { ); assert_eq!( lock.distributed_validators[1].partial_deposit_data[0].amount, - 534275443587623213 + 534_275_443_587_623_213 ); assert_eq!(lock.distributed_validators[1].partial_deposit_data[0].signature, hex::decode("329cfffd4a75e498320982c85aad70384859c05a4b13a1d5b2f5bfef5a6ed92da482caa9568e5b6fe9d8a9ddd9eb09277b92cef9046efa18500944cbe800a0b1527ea64729a861d2f6497a3235c37f4192779ec1d96b3b1c5424fce0b727b030").unwrap()); @@ -689,7 +689,7 @@ mod tests { ); assert_eq!( lock.distributed_validators[1].partial_deposit_data[1].amount, - 2408919902728845389 + 2_408_919_902_728_845_389 ); assert_eq!(lock.distributed_validators[1].partial_deposit_data[1].signature, hex::decode("ce24eb65491622558fdf297b9fa007864bafd7cd4ca1b2fb5766ab431a032b72b9a7e937ed648d0801f29055d3090d2463718254f9442483c7b98b938045da519843854b0ed3f7ba951a493f321f0966603022c1dfc579b99ed9d20d573ad531").unwrap()); diff --git a/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs b/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs index 84f4d5e7..f4468589 100644 --- a/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs +++ b/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs @@ -2,10 +2,10 @@ /// Cluster represents the manifest of a cluster after applying a sequence of mutations. #[derive(Clone, PartialEq, ::prost::Message)] pub struct Cluster { - /// InitialMutationHash is the hash of first signed mutation, uniquely identifying cluster, aka "cluster hash". It must be 32 bytes. + /// `InitialMutationHash` is the hash of first signed mutation, uniquely identifying cluster, aka "cluster hash". It must be 32 bytes. #[prost(bytes = "bytes", tag = "1")] pub initial_mutation_hash: ::prost::bytes::Bytes, - /// LatestMutationHash is the hash of last signed mutation, identifying this specific cluster iteration. It must be 32 bytes. + /// `LatestMutationHash` is the hash of last signed mutation, identifying this specific cluster iteration. It must be 32 bytes. #[prost(bytes = "bytes", tag = "2")] pub latest_mutation_hash: ::prost::bytes::Bytes, /// Name is the name of the cluster. @@ -14,10 +14,10 @@ pub struct Cluster { /// Threshold is the threshold of the cluster. #[prost(int32, tag = "4")] pub threshold: i32, - /// DKGAlgorithm is the DKG algorithm used to create the validator keys of the cluster. + /// `DKGAlgorithm` is the DKG algorithm used to create the validator keys of the cluster. #[prost(string, tag = "5")] pub dkg_algorithm: ::prost::alloc::string::String, - /// ForkVersion is the fork version (network/chain) of the cluster. It must be 4 bytes. + /// `ForkVersion` is the fork version (network/chain) of the cluster. It must be 4 bytes. #[prost(bytes = "bytes", tag = "6")] pub fork_version: ::prost::bytes::Bytes, /// Operators is the list of operators of the cluster. @@ -26,10 +26,10 @@ pub struct Cluster { /// Validators is the list of validators of the cluster. #[prost(message, repeated, tag = "8")] pub validators: ::prost::alloc::vec::Vec, - /// ConsensusProtocol is the consensus protocol name preferred by the cluster, e.g. "abft". + /// `ConsensusProtocol` is the consensus protocol name preferred by the cluster, e.g. "abft". #[prost(string, tag = "9")] pub consensus_protocol: ::prost::alloc::string::String, - /// TargetGasLimit is the custom target gas limit for transactions. + /// `TargetGasLimit` is the custom target gas limit for transactions. #[prost(uint32, tag = "10")] pub target_gas_limit: u32, /// Compounding is the flag to enable compounding rewards. @@ -49,7 +49,7 @@ pub struct Mutation { #[prost(message, optional, tag = "3")] pub data: ::core::option::Option<::prost_types::Any>, } -/// SignedMutation is a mutation signed by a signer. +/// `SignedMutation` is a mutation signed by a signer. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct SignedMutation { /// Mutation is the mutation. @@ -62,7 +62,7 @@ pub struct SignedMutation { #[prost(bytes = "bytes", tag = "3")] pub signature: ::prost::bytes::Bytes, } -/// SignedMutationList is a list of signed mutations. +/// `SignedMutationList` is a list of signed mutations. #[derive(Clone, PartialEq, ::prost::Message)] pub struct SignedMutationList { /// Mutations is the list of mutations. @@ -82,30 +82,30 @@ pub struct Operator { /// Validator represents a distributed validator managed by the DV cluster. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct Validator { - /// PublicKey is the group public key of the validator. + /// `PublicKey` is the group public key of the validator. #[prost(bytes = "bytes", tag = "1")] pub public_key: ::prost::bytes::Bytes, - /// PubShares is the ordered list of public shares of the validator. + /// `PubShares` is the ordered list of public shares of the validator. #[prost(bytes = "bytes", repeated, tag = "2")] pub pub_shares: ::prost::alloc::vec::Vec<::prost::bytes::Bytes>, - /// FeeRecipientAddress is the fee recipient Ethereum address of the validator. + /// `FeeRecipientAddress` is the fee recipient Ethereum address of the validator. #[prost(string, tag = "3")] pub fee_recipient_address: ::prost::alloc::string::String, - /// WithdrawalAddress is the withdrawal Ethereum address of the validator. + /// `WithdrawalAddress` is the withdrawal Ethereum address of the validator. #[prost(string, tag = "4")] pub withdrawal_address: ::prost::alloc::string::String, - /// BuilderRegistration is the pre-generated json-formatted builder-API validator registration of the validator. + /// `BuilderRegistration` is the pre-generated json-formatted builder-API validator registration of the validator. #[prost(bytes = "bytes", tag = "5")] pub builder_registration_json: ::prost::bytes::Bytes, } -/// ValidatorList is a list of validators. +/// `ValidatorList` is a list of validators. #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidatorList { /// Validators is the list of validators. #[prost(message, repeated, tag = "1")] pub validators: ::prost::alloc::vec::Vec, } -/// LegacyLock represents a json formatted legacy cluster lock file. +/// `LegacyLock` represents a json formatted legacy cluster lock file. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct LegacyLock { #[prost(bytes = "bytes", tag = "1")] diff --git a/crates/core/src/qbft/internal_test.rs b/crates/core/src/qbft/internal_test.rs index 39b03914..347b5b1f 100644 --- a/crates/core/src/qbft/internal_test.rs +++ b/crates/core/src/qbft/internal_test.rs @@ -259,7 +259,7 @@ fn test_qbft(test: Test) { let q_commit = res.expect(READ_CHAN_ERR); for commit in q_commit.clone() { - for (_, previous) in &results { + for previous in results.values() { assert_eq!(previous.value(), commit.value(), "commit values"); } diff --git a/crates/core/src/qbft/mod.rs b/crates/core/src/qbft/mod.rs index d12b62fd..1792bc94 100644 --- a/crates/core/src/qbft/mod.rs +++ b/crates/core/src/qbft/mod.rs @@ -780,7 +780,7 @@ where V: PartialEq, { // Get all RoundChange messages with round (rj) higher than current round (ri) - assert!(((frc.len() as i64) >= d.faulty() + 1), "bug: Frc too short"); + assert!(((frc.len() as i64) > d.faulty()), "bug: Frc too short"); // Get the smallest round in the set. let mut rmin = i64::MAX; diff --git a/crates/eth2util/src/helpers.rs b/crates/eth2util/src/helpers.rs index 5a8f0c95..418d1e71 100644 --- a/crates/eth2util/src/helpers.rs +++ b/crates/eth2util/src/helpers.rs @@ -338,7 +338,7 @@ mod tests { for tt in tests { let parsed = parse_http_headers(&tt.headers); assert!( - !parsed.is_err(), + parsed.is_ok(), "Test '{}': Header ({:?}) failed to parse", tt.name, tt.headers @@ -351,7 +351,7 @@ mod tests { tt.name, parsed, tt.want - ) + ); } } } diff --git a/crates/p2p/examples/p2p.rs b/crates/p2p/examples/p2p.rs index 2d971323..be1b8373 100644 --- a/crates/p2p/examples/p2p.rs +++ b/crates/p2p/examples/p2p.rs @@ -62,10 +62,7 @@ async fn main() -> Result<()> { .await .ok_or(anyhow::anyhow!("Swarm event is None"))? { - SwarmEvent::NewListenAddr { .. } => {} - SwarmEvent::Dialing { .. } => {} - SwarmEvent::ConnectionEstablished { .. } => {} - SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( + SwarmEvent::NewListenAddr { .. } | SwarmEvent::Dialing { .. } | SwarmEvent::ConnectionEstablished { .. } || SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( PlutoBehaviourEvent::Ping(_), )) => {} SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( @@ -80,7 +77,7 @@ async fn main() -> Result<()> { .. }), )) => { - println!("Relay told us our observed address: {}", observed_addr); + println!("Relay told us our observed address: {observed_addr}"); learned_observed_addr = true; } event => panic!("{event:?}"), @@ -91,7 +88,7 @@ async fn main() -> Result<()> { } } - println!("ENR: {}", enr); + println!("ENR: {enr}"); swarm.listen_on(format!("/ip4/0.0.0.0/udp/{}/quic-v1", args.port).parse()?)?; swarm.listen_on(format!("/ip4/0.0.0.0/tcp/{}", args.port).parse()?)?; @@ -104,14 +101,14 @@ async fn main() -> Result<()> { event = swarm.select_next_some() => match event { SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(PlutoBehaviourEvent::Identify(identify::Event::Received { info: identify::Info { observed_addr, .. }, .. }))) => { swarm.add_external_address(observed_addr.clone()); - println!("Address observed {}", observed_addr); + println!("Address observed {observed_addr}"); } SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(PlutoBehaviourEvent::Relay(event))) => { - println!("Got relay event: {:?}", event); + println!("Got relay event: {event:?}"); }, SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Mdns(libp2p::mdns::Event::Discovered(nodes))) => { for node in nodes { - println!("Discovered node: {:?}", node); + println!("Discovered node: {node:?}"); swarm.dial(node.1)?; } } @@ -119,16 +116,16 @@ async fn main() -> Result<()> { println!("Local node is listening on {address}"); } SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(PlutoBehaviourEvent::Ping(ping_event))) => { - println!("Got ping event: {:?}", ping_event); + println!("Got ping event: {ping_event:?}"); } SwarmEvent::IncomingConnection { connection_id, local_addr, send_back_addr } => { - println!("Incoming connection (id={connection_id}) from {:?} (send on {:?})", local_addr, send_back_addr); + println!("Incoming connection (id={connection_id}) from {local_addr:?} (send on {send_back_addr:?})"); } SwarmEvent::IncomingConnectionError {peer_id,connection_id,error, local_addr, send_back_addr } => { - println!("Incoming connection (id={connection_id}) error from {:?} (send on {:?} to {:?}): {:?}", peer_id, local_addr, send_back_addr, error); + println!("Incoming connection (id={connection_id}) error from {peer_id:?} (send on {local_addr:?} to {send_back_addr:?}): {error:?}"); } event => { - println!("{:?}", event); + println!("{event:?}"); } }, _ = signal::ctrl_c() => { diff --git a/crates/peerinfo/src/failure.rs b/crates/peerinfo/src/failure.rs index 56859ff4..12dc6c39 100644 --- a/crates/peerinfo/src/failure.rs +++ b/crates/peerinfo/src/failure.rs @@ -54,9 +54,7 @@ impl fmt::Display for Failure { impl Error for Failure { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { - Failure::Timeout => None, - Failure::Unsupported => None, - Failure::InvalidResponse { .. } => None, + Failure::Timeout | Failure::Unsupported | Failure::InvalidResponse { .. } => None, Failure::Other { error } => Some(&**error), } } diff --git a/crates/peerinfo/src/protocol.rs b/crates/peerinfo/src/protocol.rs index d8d0ef28..33d4e92c 100644 --- a/crates/peerinfo/src/protocol.rs +++ b/crates/peerinfo/src/protocol.rs @@ -428,12 +428,12 @@ mod tests { pluto_version: "v1.7.1".to_string(), lock_hash: (1u8..=32).collect::>().into(), sent_at: Some(prost_types::Timestamp { - seconds: 1736944245, // 2025-01-15T13:00:45Z + seconds: 1_736_944_245, // 2025-01-15T13:00:45Z nanos: 0, }), git_hash: "a1b2c3d".to_string(), started_at: Some(prost_types::Timestamp { - seconds: 1736935200, // 2025-01-15T10:30:00Z + seconds: 1_736_935_200, // 2025-01-15T10:30:00Z nanos: 0, }), builder_api_enabled: true, @@ -447,12 +447,12 @@ mod tests { pluto_version: "v1.5.0".to_string(), lock_hash: vec![0xff, 0xff, 0xff, 0xff].into(), sent_at: Some(prost_types::Timestamp { - seconds: 1733011200, // 2024-12-01T00:00:00Z + seconds: 1_733_011_200, // 2024-12-01T00:00:00Z nanos: 0, }), git_hash: "1234567".to_string(), started_at: Some(prost_types::Timestamp { - seconds: 1733007600, // 2024-11-30T23:00:00Z + seconds: 1_733_007_600, // 2024-11-30T23:00:00Z nanos: 0, }), builder_api_enabled: false, diff --git a/crates/relay-server/src/behaviour.rs b/crates/relay-server/src/behaviour.rs index 6e88259c..8bcc7908 100644 --- a/crates/relay-server/src/behaviour.rs +++ b/crates/relay-server/src/behaviour.rs @@ -72,6 +72,7 @@ impl RelayServerBehaviourBuilder { } /// Sets the identify protocol string. + #[must_use] pub fn with_identify_protocol(mut self, protocol: impl Into) -> Self { self.identify_protocol = protocol.into(); self @@ -85,6 +86,7 @@ impl RelayServerBehaviourBuilder { } /// Sets the user agent string. + #[must_use] pub fn with_user_agent(mut self, user_agent: impl Into) -> Self { self.user_agent = Some(user_agent.into()); self diff --git a/crates/relay-server/src/utils.rs b/crates/relay-server/src/utils.rs index 294a7293..a865340b 100644 --- a/crates/relay-server/src/utils.rs +++ b/crates/relay-server/src/utils.rs @@ -26,7 +26,7 @@ pub(crate) fn is_public_addr(addr: &Multiaddr) -> bool { Protocol::Ip6(ip) => { return !ip.is_loopback() && !ip.is_unspecified(); } - _ => continue, + _ => {}, } } false From 53b37e0ff3efd61f61e525ac36523941ceeacec9 Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 11:31:21 +0200 Subject: [PATCH 04/10] fix: some of clippy pedantic warnings --- crates/cli/src/commands/version.rs | 10 +++++----- crates/cli/src/main.rs | 6 +++--- crates/cluster/src/definition.rs | 6 +++--- crates/core/src/corepb/v1/priority.rs | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/crates/cli/src/commands/version.rs b/crates/cli/src/commands/version.rs index 8c2ba2c4..0b2b84cd 100644 --- a/crates/cli/src/commands/version.rs +++ b/crates/cli/src/commands/version.rs @@ -13,8 +13,8 @@ pub struct VersionArgs { } /// Runs the version command. -pub fn run(args: VersionArgs) -> Result<()> { - run_with_writer(args, &mut io::stdout()) +pub fn run(args: &VersionArgs) -> Result<()> { + run_with_writer(&args, &mut io::stdout()) } /// Runs the version command with a custom writer (used for testing). @@ -54,9 +54,9 @@ mod tests { #[test] fn test_run_version_cmd_default() { let mut buf = Vec::new(); - let args = VersionArgs { verbose: false }; + let args = &VersionArgs { verbose: false }; - let result = run_with_writer(args, &mut buf); + let result = run_with_writer(&args, &mut buf); assert!(result.is_ok()); let output = String::from_utf8(buf).expect("valid UTF-8 output"); @@ -102,7 +102,7 @@ mod tests { let mut buf = Vec::new(); let args = VersionArgs { verbose: true }; - let result = run_with_writer(args, &mut buf); + let result = run_with_writer(&args, &mut buf); assert!(result.is_ok()); let output = String::from_utf8(buf).expect("valid UTF-8 output"); diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 72703017..b17f9b67 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -18,10 +18,10 @@ fn main() -> ExitResult { let result = match cli.command { Commands::Create(args) => match args.command { - CreateCommands::Enr(args) => commands::create_enr::run(args), + CreateCommands::Enr(args) => commands::create_enr::run(&args), }, - Commands::Enr(args) => commands::enr::run(args), - Commands::Version(args) => commands::version::run(args), + Commands::Enr(args) => commands::enr::run(&args), + Commands::Version(args) => commands::version::run(&args), }; ExitResult(result) diff --git a/crates/cluster/src/definition.rs b/crates/cluster/src/definition.rs index e64b29be..da591348 100644 --- a/crates/cluster/src/definition.rs +++ b/crates/cluster/src/definition.rs @@ -639,7 +639,7 @@ impl TryFrom for Definition { }; let validator_addresses = - repeat_v_addresses(validator_addresses, definition.num_validators); + repeat_v_addresses(&validator_addresses, definition.num_validators); Ok(Self { name: definition.name, @@ -750,7 +750,7 @@ impl TryFrom for Definition { }; let validator_addresses = - repeat_v_addresses(validator_addresses, definition.num_validators); + repeat_v_addresses(&validator_addresses, definition.num_validators); Ok(Self { name: definition.name, @@ -865,7 +865,7 @@ impl TryFrom for Definition { }; let validator_addresses = - repeat_v_addresses(validator_addresses, definition.num_validators); + repeat_v_addresses(&validator_addresses, definition.num_validators); Ok(Self { name: definition.name, diff --git a/crates/core/src/corepb/v1/priority.rs b/crates/core/src/corepb/v1/priority.rs index dd723bea..04df8d43 100644 --- a/crates/core/src/corepb/v1/priority.rs +++ b/crates/core/src/corepb/v1/priority.rs @@ -4,7 +4,7 @@ #![allow(clippy::all)] #![allow(rustdoc::all)] -/// PriorityResult defines a cluster wide priority result of the Prioritiser protocol. +/// `PriorityResult` defines a cluster wide priority result of the Prioritiser protocol. #[derive(Clone, PartialEq, ::prost::Message)] pub struct PriorityResult { #[prost(message, repeated, tag = "1")] @@ -12,7 +12,7 @@ pub struct PriorityResult { #[prost(message, repeated, tag = "2")] pub topics: ::prost::alloc::vec::Vec, } -/// PriorityMsg defines all the priorities and metadata of a single peer in the Prioritiser protocol. +/// `PriorityMsg` defines all the priorities and metadata of a single peer in the Prioritiser protocol. #[derive(Clone, PartialEq, ::prost::Message)] pub struct PriorityMsg { #[prost(message, optional, tag = "1")] @@ -24,7 +24,7 @@ pub struct PriorityMsg { #[prost(bytes = "bytes", tag = "4")] pub signature: ::prost::bytes::Bytes, } -/// PriorityTopicProposal defines a single peers proposed priorities for a single topic in the Prioritiser protocol. +/// `PriorityTopicProposal` defines a single peers proposed priorities for a single topic in the Prioritiser protocol. #[derive(Clone, PartialEq, ::prost::Message)] pub struct PriorityTopicProposal { #[prost(message, optional, tag = "1")] @@ -32,7 +32,7 @@ pub struct PriorityTopicProposal { #[prost(message, repeated, tag = "2")] pub priorities: ::prost::alloc::vec::Vec<::prost_types::Any>, } -/// PriorityTopicResult defines the cluster wide resulting priorities for a +/// `PriorityTopicResult` defines the cluster wide resulting priorities for a /// single topic in the Prioritiser protocol. #[derive(Clone, PartialEq, ::prost::Message)] pub struct PriorityTopicResult { @@ -42,7 +42,7 @@ pub struct PriorityTopicResult { #[prost(message, repeated, tag = "2")] pub priorities: ::prost::alloc::vec::Vec, } -/// PriorityScoredResult defines the cluster wide priority score in the Prioritiser protocol. +/// `PriorityScoredResult` defines the cluster wide priority score in the Prioritiser protocol. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct PriorityScoredResult { #[prost(message, optional, tag = "1")] From 4f33763a0f7d86aff4f03076a43a70a9088d2a47 Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 12:09:02 +0200 Subject: [PATCH 05/10] fix: some of clippy pedantic warnings --- crates/cli/src/commands/version.rs | 4 +-- crates/cluster/src/lock.rs | 2 +- .../src/manifestpb/cluster.manifestpb.v1.rs | 30 +++++++++---------- crates/core/src/corepb/v1/priority.rs | 10 +++---- crates/eth2util/src/network.rs | 14 ++++----- crates/p2p/examples/p2p.rs | 2 +- crates/p2p/src/peer.rs | 6 ++-- 7 files changed, 34 insertions(+), 34 deletions(-) diff --git a/crates/cli/src/commands/version.rs b/crates/cli/src/commands/version.rs index 0b2b84cd..1055c521 100644 --- a/crates/cli/src/commands/version.rs +++ b/crates/cli/src/commands/version.rs @@ -14,7 +14,7 @@ pub struct VersionArgs { /// Runs the version command. pub fn run(args: &VersionArgs) -> Result<()> { - run_with_writer(&args, &mut io::stdout()) + run_with_writer(args, &mut io::stdout()) } /// Runs the version command with a custom writer (used for testing). @@ -56,7 +56,7 @@ mod tests { let mut buf = Vec::new(); let args = &VersionArgs { verbose: false }; - let result = run_with_writer(&args, &mut buf); + let result = run_with_writer(args, &mut buf); assert!(result.is_ok()); let output = String::from_utf8(buf).expect("valid UTF-8 output"); diff --git a/crates/cluster/src/lock.rs b/crates/cluster/src/lock.rs index 5ccbacf9..7e3e629a 100644 --- a/crates/cluster/src/lock.rs +++ b/crates/cluster/src/lock.rs @@ -621,7 +621,7 @@ mod tests { ); assert_eq!( lock.distributed_validators[0].partial_deposit_data[0].amount, - 5919415281453547599 + 5_919_415_281_453_547_599 ); assert_eq!(lock.distributed_validators[0].partial_deposit_data[1].pub_key, hex::decode("1814be823350eab13935f31d84484517e924aef78ae151c00755925836b7075885650c30ec29a3703934bf50a28da102").unwrap()); assert_eq!( diff --git a/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs b/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs index f4468589..84f4d5e7 100644 --- a/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs +++ b/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs @@ -2,10 +2,10 @@ /// Cluster represents the manifest of a cluster after applying a sequence of mutations. #[derive(Clone, PartialEq, ::prost::Message)] pub struct Cluster { - /// `InitialMutationHash` is the hash of first signed mutation, uniquely identifying cluster, aka "cluster hash". It must be 32 bytes. + /// InitialMutationHash is the hash of first signed mutation, uniquely identifying cluster, aka "cluster hash". It must be 32 bytes. #[prost(bytes = "bytes", tag = "1")] pub initial_mutation_hash: ::prost::bytes::Bytes, - /// `LatestMutationHash` is the hash of last signed mutation, identifying this specific cluster iteration. It must be 32 bytes. + /// LatestMutationHash is the hash of last signed mutation, identifying this specific cluster iteration. It must be 32 bytes. #[prost(bytes = "bytes", tag = "2")] pub latest_mutation_hash: ::prost::bytes::Bytes, /// Name is the name of the cluster. @@ -14,10 +14,10 @@ pub struct Cluster { /// Threshold is the threshold of the cluster. #[prost(int32, tag = "4")] pub threshold: i32, - /// `DKGAlgorithm` is the DKG algorithm used to create the validator keys of the cluster. + /// DKGAlgorithm is the DKG algorithm used to create the validator keys of the cluster. #[prost(string, tag = "5")] pub dkg_algorithm: ::prost::alloc::string::String, - /// `ForkVersion` is the fork version (network/chain) of the cluster. It must be 4 bytes. + /// ForkVersion is the fork version (network/chain) of the cluster. It must be 4 bytes. #[prost(bytes = "bytes", tag = "6")] pub fork_version: ::prost::bytes::Bytes, /// Operators is the list of operators of the cluster. @@ -26,10 +26,10 @@ pub struct Cluster { /// Validators is the list of validators of the cluster. #[prost(message, repeated, tag = "8")] pub validators: ::prost::alloc::vec::Vec, - /// `ConsensusProtocol` is the consensus protocol name preferred by the cluster, e.g. "abft". + /// ConsensusProtocol is the consensus protocol name preferred by the cluster, e.g. "abft". #[prost(string, tag = "9")] pub consensus_protocol: ::prost::alloc::string::String, - /// `TargetGasLimit` is the custom target gas limit for transactions. + /// TargetGasLimit is the custom target gas limit for transactions. #[prost(uint32, tag = "10")] pub target_gas_limit: u32, /// Compounding is the flag to enable compounding rewards. @@ -49,7 +49,7 @@ pub struct Mutation { #[prost(message, optional, tag = "3")] pub data: ::core::option::Option<::prost_types::Any>, } -/// `SignedMutation` is a mutation signed by a signer. +/// SignedMutation is a mutation signed by a signer. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct SignedMutation { /// Mutation is the mutation. @@ -62,7 +62,7 @@ pub struct SignedMutation { #[prost(bytes = "bytes", tag = "3")] pub signature: ::prost::bytes::Bytes, } -/// `SignedMutationList` is a list of signed mutations. +/// SignedMutationList is a list of signed mutations. #[derive(Clone, PartialEq, ::prost::Message)] pub struct SignedMutationList { /// Mutations is the list of mutations. @@ -82,30 +82,30 @@ pub struct Operator { /// Validator represents a distributed validator managed by the DV cluster. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct Validator { - /// `PublicKey` is the group public key of the validator. + /// PublicKey is the group public key of the validator. #[prost(bytes = "bytes", tag = "1")] pub public_key: ::prost::bytes::Bytes, - /// `PubShares` is the ordered list of public shares of the validator. + /// PubShares is the ordered list of public shares of the validator. #[prost(bytes = "bytes", repeated, tag = "2")] pub pub_shares: ::prost::alloc::vec::Vec<::prost::bytes::Bytes>, - /// `FeeRecipientAddress` is the fee recipient Ethereum address of the validator. + /// FeeRecipientAddress is the fee recipient Ethereum address of the validator. #[prost(string, tag = "3")] pub fee_recipient_address: ::prost::alloc::string::String, - /// `WithdrawalAddress` is the withdrawal Ethereum address of the validator. + /// WithdrawalAddress is the withdrawal Ethereum address of the validator. #[prost(string, tag = "4")] pub withdrawal_address: ::prost::alloc::string::String, - /// `BuilderRegistration` is the pre-generated json-formatted builder-API validator registration of the validator. + /// BuilderRegistration is the pre-generated json-formatted builder-API validator registration of the validator. #[prost(bytes = "bytes", tag = "5")] pub builder_registration_json: ::prost::bytes::Bytes, } -/// `ValidatorList` is a list of validators. +/// ValidatorList is a list of validators. #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidatorList { /// Validators is the list of validators. #[prost(message, repeated, tag = "1")] pub validators: ::prost::alloc::vec::Vec, } -/// `LegacyLock` represents a json formatted legacy cluster lock file. +/// LegacyLock represents a json formatted legacy cluster lock file. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct LegacyLock { #[prost(bytes = "bytes", tag = "1")] diff --git a/crates/core/src/corepb/v1/priority.rs b/crates/core/src/corepb/v1/priority.rs index 04df8d43..dd723bea 100644 --- a/crates/core/src/corepb/v1/priority.rs +++ b/crates/core/src/corepb/v1/priority.rs @@ -4,7 +4,7 @@ #![allow(clippy::all)] #![allow(rustdoc::all)] -/// `PriorityResult` defines a cluster wide priority result of the Prioritiser protocol. +/// PriorityResult defines a cluster wide priority result of the Prioritiser protocol. #[derive(Clone, PartialEq, ::prost::Message)] pub struct PriorityResult { #[prost(message, repeated, tag = "1")] @@ -12,7 +12,7 @@ pub struct PriorityResult { #[prost(message, repeated, tag = "2")] pub topics: ::prost::alloc::vec::Vec, } -/// `PriorityMsg` defines all the priorities and metadata of a single peer in the Prioritiser protocol. +/// PriorityMsg defines all the priorities and metadata of a single peer in the Prioritiser protocol. #[derive(Clone, PartialEq, ::prost::Message)] pub struct PriorityMsg { #[prost(message, optional, tag = "1")] @@ -24,7 +24,7 @@ pub struct PriorityMsg { #[prost(bytes = "bytes", tag = "4")] pub signature: ::prost::bytes::Bytes, } -/// `PriorityTopicProposal` defines a single peers proposed priorities for a single topic in the Prioritiser protocol. +/// PriorityTopicProposal defines a single peers proposed priorities for a single topic in the Prioritiser protocol. #[derive(Clone, PartialEq, ::prost::Message)] pub struct PriorityTopicProposal { #[prost(message, optional, tag = "1")] @@ -32,7 +32,7 @@ pub struct PriorityTopicProposal { #[prost(message, repeated, tag = "2")] pub priorities: ::prost::alloc::vec::Vec<::prost_types::Any>, } -/// `PriorityTopicResult` defines the cluster wide resulting priorities for a +/// PriorityTopicResult defines the cluster wide resulting priorities for a /// single topic in the Prioritiser protocol. #[derive(Clone, PartialEq, ::prost::Message)] pub struct PriorityTopicResult { @@ -42,7 +42,7 @@ pub struct PriorityTopicResult { #[prost(message, repeated, tag = "2")] pub priorities: ::prost::alloc::vec::Vec, } -/// `PriorityScoredResult` defines the cluster wide priority score in the Prioritiser protocol. +/// PriorityScoredResult defines the cluster wide priority score in the Prioritiser protocol. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct PriorityScoredResult { #[prost(message, optional, tag = "1")] diff --git a/crates/eth2util/src/network.rs b/crates/eth2util/src/network.rs index 69cd5a0c..51e576d7 100644 --- a/crates/eth2util/src/network.rs +++ b/crates/eth2util/src/network.rs @@ -75,7 +75,7 @@ mod predefined { chain_id: 1, name: "mainnet", genesis_fork_version_hex: "0x00000000", - genesis_timestamp: 1606824023, + genesis_timestamp: 1_606_824_023, capella_hard_fork: "0x03000000", }; @@ -93,7 +93,7 @@ mod predefined { chain_id: 100, name: "gnosis", genesis_fork_version_hex: "0x00000064", - genesis_timestamp: 1638993340, + genesis_timestamp: 1_638_993_340, capella_hard_fork: "0x03000064", }; @@ -102,16 +102,16 @@ mod predefined { chain_id: 10200, name: "chiado", genesis_fork_version_hex: "0x0000006f", - genesis_timestamp: 1665396300, + genesis_timestamp: 1_665_396_300, capella_hard_fork: "0x0300006f", }; /// Sepolia network. pub const SEPOLIA: Network = Network { - chain_id: 11155111, + chain_id: 11_155_111, name: "sepolia", genesis_fork_version_hex: "0x90000069", - genesis_timestamp: 1655733600, + genesis_timestamp: 1_655_733_600, capella_hard_fork: "0x90000072", }; @@ -120,7 +120,7 @@ mod predefined { chain_id: 17000, name: "holesky", genesis_fork_version_hex: "0x01017000", - genesis_timestamp: 1696000704, + genesis_timestamp: 1_696_000_704, capella_hard_fork: "0x04017000", }; @@ -129,7 +129,7 @@ mod predefined { chain_id: 560048, name: "hoodi", genesis_fork_version_hex: "0x10000910", - genesis_timestamp: 1742213400, + genesis_timestamp: 1_742_213_400, capella_hard_fork: "0x40000910", }; } diff --git a/crates/p2p/examples/p2p.rs b/crates/p2p/examples/p2p.rs index be1b8373..66f8df53 100644 --- a/crates/p2p/examples/p2p.rs +++ b/crates/p2p/examples/p2p.rs @@ -62,7 +62,7 @@ async fn main() -> Result<()> { .await .ok_or(anyhow::anyhow!("Swarm event is None"))? { - SwarmEvent::NewListenAddr { .. } | SwarmEvent::Dialing { .. } | SwarmEvent::ConnectionEstablished { .. } || SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( + SwarmEvent::NewListenAddr { .. } | SwarmEvent::Dialing { .. } | SwarmEvent::ConnectionEstablished { .. } | SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( PlutoBehaviourEvent::Ping(_), )) => {} SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( diff --git a/crates/p2p/src/peer.rs b/crates/p2p/src/peer.rs index 415e136a..ce635127 100644 --- a/crates/p2p/src/peer.rs +++ b/crates/p2p/src/peer.rs @@ -334,19 +334,19 @@ mod tests { } #[test] - #[ignore] + #[ignore = "add this test after implementing p2p.NewNode function"] fn test_new_tcp_host() { todo!("add this test after implementing p2p.NewNode function"); } #[test] - #[ignore] + #[ignore = "add this test after implementing cluster.NewForT function"] fn test_verify_p2p_key() { todo!("add this test after implementing cluster.NewForT function"); } #[test] - #[ignore] + #[ignore = "add this test after implementing peer_id_key function"] fn test_peer_id_key() { todo!("add this test after implementing peer_id_key function"); } From a4559691fa764f7e0bb9f69721fd7a59c8512b8a Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:54:11 +0200 Subject: [PATCH 06/10] fix: some of clippy pedantic warnings --- crates/core/src/qbft/mod.rs | 9 ++++----- crates/crypto/src/blst_impl.rs | 14 +++++++------- crates/crypto/src/types.rs | 2 +- crates/k1util/src/k1util.rs | 2 +- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/crates/core/src/qbft/mod.rs b/crates/core/src/qbft/mod.rs index 1792bc94..b3b5cb12 100644 --- a/crates/core/src/qbft/mod.rs +++ b/crates/core/src/qbft/mod.rs @@ -711,7 +711,7 @@ where } let prepares = - filter_by_round_and_value(&flatten(buffer), MSG_PREPARE, msg.round(), msg.value()); + filter_by_round_and_value(&flatten(buffer), MSG_PREPARE, msg.round(), &msg.value()); if prepares.len() as i64 >= d.quorum() { (UPON_QUORUM_PREPARES, Some(prepares)) @@ -726,7 +726,7 @@ where } let commits = - filter_by_round_and_value(&flatten(buffer), MSG_COMMIT, msg.round(), msg.value()); + filter_by_round_and_value(&flatten(buffer), MSG_COMMIT, msg.round(), &msg.value()); if commits.len() as i64 >= d.quorum() { (UPON_QUORUM_COMMITS, Some(commits)) } else { @@ -812,8 +812,7 @@ where { match msg.type_() { MSG_PRE_PREPARE => is_justified_pre_prepare(d, instance, msg, compare_failure_round), - MSG_PREPARE => true, - MSG_COMMIT => true, + MSG_PREPARE | MSG_COMMIT => true, MSG_ROUND_CHANGE => is_justified_round_change(d, msg), MSG_DECIDED => is_justified_decided(d, msg), _ => panic!("bug: invalid message type"), @@ -1194,7 +1193,7 @@ fn filter_by_round_and_value( msgs: &Vec>, message_type: MessageType, round: i64, - value: V, + value: &V, ) -> Vec> where V: PartialEq, diff --git a/crates/crypto/src/blst_impl.rs b/crates/crypto/src/blst_impl.rs index cfe88082..337aadcc 100644 --- a/crates/crypto/src/blst_impl.rs +++ b/crates/crypto/src/blst_impl.rs @@ -331,7 +331,7 @@ fn lagrange_interpolate_signature( let coeffs = compute_lagrange_coefficients(indices)?; // Multiply each signature by its Lagrange coefficient and aggregate - let first_sig_scaled = signature_mult(&signatures[0], &coeffs[0])?; + let first_sig_scaled = signature_mult(&signatures[0], &coeffs[0]); let mut result_p2 = blst::blst_p2::default(); unsafe { @@ -340,7 +340,7 @@ fn lagrange_interpolate_signature( blst::blst_p2_from_affine(&raw mut result_p2, first_affine); for i in 1..signatures.len() { - let sig_scaled = signature_mult(&signatures[i], &coeffs[i])?; + let sig_scaled = signature_mult(&signatures[i], &coeffs[i]); let sig_affine: &blst::blst_p2_affine = (&sig_scaled).into(); blst::blst_p2_add_or_double_affine( &raw mut result_p2, @@ -388,7 +388,7 @@ fn compute_lagrange_coefficients(indices: &[Index]) -> Result Result Result { +fn signature_mult(sig: &BlstSignature, scalar: &blst::blst_scalar) -> BlstSignature { let mut sig_proj = blst::blst_p2::default(); let mut result_p2 = blst::blst_p2::default(); let mut result_affine = blst::blst_p2_affine::default(); @@ -454,7 +454,7 @@ fn signature_mult(sig: &BlstSignature, scalar: &blst::blst_scalar) -> Result Result { +fn scalar_negate(a: &blst::blst_scalar) -> blst::blst_scalar { // To negate in the field, we compute (r - a) where r is the curve order // But blst doesn't expose this directly, so we use: -a ≡ r - a // We can compute this as: 0 - a @@ -506,7 +506,7 @@ fn scalar_negate(a: &blst::blst_scalar) -> Result { blst::blst_scalar_from_fr(&raw mut result_scalar, &raw const result_fr); } - Ok(result_scalar) + result_scalar } /// Divide two scalars (multiply by inverse) diff --git a/crates/crypto/src/types.rs b/crates/crypto/src/types.rs index 1e0dd6b2..9ec088e4 100644 --- a/crates/crypto/src/types.rs +++ b/crates/crypto/src/types.rs @@ -179,7 +179,7 @@ impl From for BlsError { BLST_ERROR::BLST_VERIFY_FAIL => Self::VerifyFailed, BLST_ERROR::BLST_PK_IS_INFINITY => Self::InvalidPublicKey, BLST_ERROR::BLST_BAD_SCALAR => Self::InvalidScalar, - _ => Self::Unknown, + BLST_ERROR::BLST_SUCCESS => Self::Unknown, } } } diff --git a/crates/k1util/src/k1util.rs b/crates/k1util/src/k1util.rs index 923efa47..d06ebdd9 100644 --- a/crates/k1util/src/k1util.rs +++ b/crates/k1util/src/k1util.rs @@ -13,7 +13,7 @@ use libp2p::identity::PublicKey as Libp2pPublicKey; /// `SCALAR_LEN` is the length of secp256k1 scalar. pub const SCALAR_LEN: usize = 32; -/// `K1_HASH_LEN`` is the length of secp256k1 signature hash/digest. +/// `K1_HASH_LEN` is the length of secp256k1 signature hash/digest. pub const K1_HASH_LEN: usize = 32; /// `SIGNATURE_LEN` is the length of secp256k1 signature. From b7f10ddf0f3ec98ba9d3770b91a28fd7ecd0719a Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:07:58 +0200 Subject: [PATCH 07/10] fix: some of clippy pedantic warnings --- crates/cli/src/commands/create_enr.rs | 2 +- crates/cli/src/commands/enr.rs | 2 +- .../src/manifestpb/cluster.manifestpb.v1.rs | 30 +++++++++---------- crates/core/src/qbft/internal_test.rs | 4 +-- crates/core/src/qbft/mod.rs | 10 +++---- crates/eth2util/src/enr.rs | 8 ++--- crates/eth2util/src/network.rs | 4 +-- crates/p2p/examples/p2p.rs | 2 +- crates/p2p/src/peer.rs | 2 +- crates/peerinfo/examples/peerinfo.rs | 2 +- crates/relay-server/src/web.rs | 2 +- 11 files changed, 34 insertions(+), 34 deletions(-) diff --git a/crates/cli/src/commands/create_enr.rs b/crates/cli/src/commands/create_enr.rs index 3c26690c..e4fd661c 100644 --- a/crates/cli/src/commands/create_enr.rs +++ b/crates/cli/src/commands/create_enr.rs @@ -37,7 +37,7 @@ pub fn run(args: &CreateEnrArgs) -> Result<()> { let key = k1::new_saved_priv_key(&args.data_dir)?; - let record = Record::new(key, Vec::new())?; + let record = Record::new(&key, Vec::new())?; let key_path = k1::key_path(&args.data_dir); let mut writer = io::stdout(); diff --git a/crates/cli/src/commands/enr.rs b/crates/cli/src/commands/enr.rs index 2a7b0035..8d3d80ca 100644 --- a/crates/cli/src/commands/enr.rs +++ b/crates/cli/src/commands/enr.rs @@ -47,7 +47,7 @@ pub fn run(args: &EnrArgs) -> Result<()> { } }; - let record = Record::new(key.clone(), vec![])?; + let record = Record::new(&key, vec![])?; writeln!(writer, "{record}")?; diff --git a/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs b/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs index 84f4d5e7..f4468589 100644 --- a/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs +++ b/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs @@ -2,10 +2,10 @@ /// Cluster represents the manifest of a cluster after applying a sequence of mutations. #[derive(Clone, PartialEq, ::prost::Message)] pub struct Cluster { - /// InitialMutationHash is the hash of first signed mutation, uniquely identifying cluster, aka "cluster hash". It must be 32 bytes. + /// `InitialMutationHash` is the hash of first signed mutation, uniquely identifying cluster, aka "cluster hash". It must be 32 bytes. #[prost(bytes = "bytes", tag = "1")] pub initial_mutation_hash: ::prost::bytes::Bytes, - /// LatestMutationHash is the hash of last signed mutation, identifying this specific cluster iteration. It must be 32 bytes. + /// `LatestMutationHash` is the hash of last signed mutation, identifying this specific cluster iteration. It must be 32 bytes. #[prost(bytes = "bytes", tag = "2")] pub latest_mutation_hash: ::prost::bytes::Bytes, /// Name is the name of the cluster. @@ -14,10 +14,10 @@ pub struct Cluster { /// Threshold is the threshold of the cluster. #[prost(int32, tag = "4")] pub threshold: i32, - /// DKGAlgorithm is the DKG algorithm used to create the validator keys of the cluster. + /// `DKGAlgorithm` is the DKG algorithm used to create the validator keys of the cluster. #[prost(string, tag = "5")] pub dkg_algorithm: ::prost::alloc::string::String, - /// ForkVersion is the fork version (network/chain) of the cluster. It must be 4 bytes. + /// `ForkVersion` is the fork version (network/chain) of the cluster. It must be 4 bytes. #[prost(bytes = "bytes", tag = "6")] pub fork_version: ::prost::bytes::Bytes, /// Operators is the list of operators of the cluster. @@ -26,10 +26,10 @@ pub struct Cluster { /// Validators is the list of validators of the cluster. #[prost(message, repeated, tag = "8")] pub validators: ::prost::alloc::vec::Vec, - /// ConsensusProtocol is the consensus protocol name preferred by the cluster, e.g. "abft". + /// `ConsensusProtocol` is the consensus protocol name preferred by the cluster, e.g. "abft". #[prost(string, tag = "9")] pub consensus_protocol: ::prost::alloc::string::String, - /// TargetGasLimit is the custom target gas limit for transactions. + /// `TargetGasLimit` is the custom target gas limit for transactions. #[prost(uint32, tag = "10")] pub target_gas_limit: u32, /// Compounding is the flag to enable compounding rewards. @@ -49,7 +49,7 @@ pub struct Mutation { #[prost(message, optional, tag = "3")] pub data: ::core::option::Option<::prost_types::Any>, } -/// SignedMutation is a mutation signed by a signer. +/// `SignedMutation` is a mutation signed by a signer. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct SignedMutation { /// Mutation is the mutation. @@ -62,7 +62,7 @@ pub struct SignedMutation { #[prost(bytes = "bytes", tag = "3")] pub signature: ::prost::bytes::Bytes, } -/// SignedMutationList is a list of signed mutations. +/// `SignedMutationList` is a list of signed mutations. #[derive(Clone, PartialEq, ::prost::Message)] pub struct SignedMutationList { /// Mutations is the list of mutations. @@ -82,30 +82,30 @@ pub struct Operator { /// Validator represents a distributed validator managed by the DV cluster. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct Validator { - /// PublicKey is the group public key of the validator. + /// `PublicKey` is the group public key of the validator. #[prost(bytes = "bytes", tag = "1")] pub public_key: ::prost::bytes::Bytes, - /// PubShares is the ordered list of public shares of the validator. + /// `PubShares` is the ordered list of public shares of the validator. #[prost(bytes = "bytes", repeated, tag = "2")] pub pub_shares: ::prost::alloc::vec::Vec<::prost::bytes::Bytes>, - /// FeeRecipientAddress is the fee recipient Ethereum address of the validator. + /// `FeeRecipientAddress` is the fee recipient Ethereum address of the validator. #[prost(string, tag = "3")] pub fee_recipient_address: ::prost::alloc::string::String, - /// WithdrawalAddress is the withdrawal Ethereum address of the validator. + /// `WithdrawalAddress` is the withdrawal Ethereum address of the validator. #[prost(string, tag = "4")] pub withdrawal_address: ::prost::alloc::string::String, - /// BuilderRegistration is the pre-generated json-formatted builder-API validator registration of the validator. + /// `BuilderRegistration` is the pre-generated json-formatted builder-API validator registration of the validator. #[prost(bytes = "bytes", tag = "5")] pub builder_registration_json: ::prost::bytes::Bytes, } -/// ValidatorList is a list of validators. +/// `ValidatorList` is a list of validators. #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidatorList { /// Validators is the list of validators. #[prost(message, repeated, tag = "1")] pub validators: ::prost::alloc::vec::Vec, } -/// LegacyLock represents a json formatted legacy cluster lock file. +/// `LegacyLock` represents a json formatted legacy cluster lock file. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct LegacyLock { #[prost(bytes = "bytes", tag = "1")] diff --git a/crates/core/src/qbft/internal_test.rs b/crates/core/src/qbft/internal_test.rs index 347b5b1f..8fbebf5a 100644 --- a/crates/core/src/qbft/internal_test.rs +++ b/crates/core/src/qbft/internal_test.rs @@ -220,7 +220,7 @@ fn test_qbft(test: Test) { &test.instance, i, v_chan_rx, - vs_chan_rx, + &vs_chan_rx, )) .expect(WRITE_CHAN_ERR); }); @@ -781,7 +781,7 @@ fn duplicate_pre_prepare_rules() { &0, NO_LEADER, input_value_ch, - input_value_source_ch, + &input_value_source_ch, ); assert!(res.is_ok()); diff --git a/crates/core/src/qbft/mod.rs b/crates/core/src/qbft/mod.rs index b3b5cb12..fe07d504 100644 --- a/crates/core/src/qbft/mod.rs +++ b/crates/core/src/qbft/mod.rs @@ -1,5 +1,5 @@ -//! Package `qbft` is an implementation of ["The Istanbul BFT Consensus Algorithm"](https://arxiv.org/pdf/2002.03613.pdf) by Henrique Moniz -//! as referenced by the [QBFT spec](https://github.com/ConsenSys/qbft-formal-spec-and-verification). +//! Package `qbft` is an implementation of [`The Istanbul BFT Consensus Algorithm`](https://arxiv.org/pdf/2002.03613.pdf) by Henrique Moniz +//! as referenced by the [`QBFT spec`](https://github.com/ConsenSys/qbft-formal-spec-and-verification). //! //! ## Features //! @@ -299,7 +299,7 @@ pub fn run( instance: &I, process: i64, mut input_value_ch: mpmc::Receiver, - input_value_source_ch: mpmc::Receiver, + input_value_source_ch: &mpmc::Receiver, ) -> Result<()> where V: PartialEq + Eq + Hash + Default, @@ -1198,7 +1198,7 @@ fn filter_by_round_and_value( where V: PartialEq, { - filter_msgs(msgs, message_type, round, Some(&value), None, None) + filter_msgs(msgs, message_type, round, Some(value), None, None) } /// Returns all round change messages for the provided round. @@ -1283,7 +1283,7 @@ where /// Construct a function that returns true if the message is from a unique /// source. -fn uniq_source(vec: Vec>) -> Box) -> bool> +fn uniq_source(vec: Vec>) -> impl for<'a> FnMut(&'a std::sync::Arc<(dyn SomeMsg + 'static)>) -> bool where V: PartialEq, { diff --git a/crates/eth2util/src/enr.rs b/crates/eth2util/src/enr.rs index a727a5a4..aa181096 100644 --- a/crates/eth2util/src/enr.rs +++ b/crates/eth2util/src/enr.rs @@ -134,7 +134,7 @@ pub fn with_udp_impl(udp: u16) -> OptionFn { impl Record { /// Creates a new record. - pub fn new(secret_key: SecretKey, opts: Vec) -> Result { + pub fn new(secret_key: &SecretKey, opts: Vec) -> Result { let mut kvs: HashMap> = HashMap::new(); kvs.insert(KEY_ID.to_string(), VAL_ID.as_bytes().to_vec()); @@ -373,7 +373,7 @@ mod tests { fn test_encode_decode() { let secret_key: SecretKey = SecretKey::random(&mut OsRng); - let r1 = Record::new(secret_key, vec![]).expect("Failed to create record"); + let r1 = Record::new(&secret_key, vec![]).expect("Failed to create record"); let r2 = Record::try_from(r1.to_string().as_str()).expect("Failed to parse record"); @@ -392,7 +392,7 @@ mod tests { let expect_udp = 9000; let r1 = Record::new( - secret_key, + &secret_key, vec![ with_ip_impl(expect_ip), with_tcp_impl(expect_tcp), @@ -428,7 +428,7 @@ mod tests { fn test_new() { let secret_key: SecretKey = generate_insecure_k1_key(0); - let r = Record::new(secret_key, vec![]).expect("Failed to create record"); + let r = Record::new(&secret_key, vec![]).expect("Failed to create record"); assert_eq!( r.to_string(), diff --git a/crates/eth2util/src/network.rs b/crates/eth2util/src/network.rs index 51e576d7..6855341b 100644 --- a/crates/eth2util/src/network.rs +++ b/crates/eth2util/src/network.rs @@ -117,7 +117,7 @@ mod predefined { /// Holesky network. Metadata taken from . pub const HOLESKY: Network = Network { - chain_id: 17000, + chain_id: 17_000, name: "holesky", genesis_fork_version_hex: "0x01017000", genesis_timestamp: 1_696_000_704, @@ -126,7 +126,7 @@ mod predefined { /// Hoodi network. Metadata taken from . pub const HOODI: Network = Network { - chain_id: 560048, + chain_id: 560_048, name: "hoodi", genesis_fork_version_hex: "0x10000910", genesis_timestamp: 1_742_213_400, diff --git a/crates/p2p/examples/p2p.rs b/crates/p2p/examples/p2p.rs index 66f8df53..4399761c 100644 --- a/crates/p2p/examples/p2p.rs +++ b/crates/p2p/examples/p2p.rs @@ -48,7 +48,7 @@ async fn main() -> Result<()> { let swarm = &mut p2p.swarm; - let enr = Record::new(key.clone(), vec![])?; + let enr = Record::new(&key, vec![])?; if let Some(relay_url) = &args.relay_url { swarm.dial(relay_url.clone())?; diff --git a/crates/p2p/src/peer.rs b/crates/p2p/src/peer.rs index ce635127..5ca2aee1 100644 --- a/crates/p2p/src/peer.rs +++ b/crates/p2p/src/peer.rs @@ -323,7 +323,7 @@ mod tests { fn test_new_peer() { let p2p_key = generate_insecure_k1_key(1); - let record = Record::new(p2p_key, vec![]).unwrap(); + let record = Record::new(&p2p_key, vec![]).unwrap(); let peer = Peer::from_enr(&record, 0).unwrap(); diff --git a/crates/peerinfo/examples/peerinfo.rs b/crates/peerinfo/examples/peerinfo.rs index 269bfa6f..f31f0ed1 100644 --- a/crates/peerinfo/examples/peerinfo.rs +++ b/crates/peerinfo/examples/peerinfo.rs @@ -227,7 +227,7 @@ async fn main() -> anyhow::Result<()> { }; let enr = pluto_eth2util::enr::Record::new( - key.clone(), + &key, vec![ pluto_eth2util::enr::with_ip_impl(Ipv4Addr::from([0, 0, 0, 0])), pluto_eth2util::enr::with_tcp_impl(args.port), diff --git a/crates/relay-server/src/web.rs b/crates/relay-server/src/web.rs index 3288767e..e02d6eee 100644 --- a/crates/relay-server/src/web.rs +++ b/crates/relay-server/src/web.rs @@ -228,7 +228,7 @@ pub async fn enr_handler( // Create ENR record let record = pluto_eth2util::enr::Record::new( - state.secret_key.clone(), + &state.secret_key, vec![ pluto_eth2util::enr::with_ip_impl(ip), pluto_eth2util::enr::with_tcp_impl(tcp_port), From ab4593c3efbee8eab5de54a49e275f29a73248b2 Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:08:17 +0200 Subject: [PATCH 08/10] fix: linter --- crates/core/src/qbft/mod.rs | 4 +++- crates/p2p/examples/p2p.rs | 5 ++++- crates/relay-server/src/utils.rs | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/core/src/qbft/mod.rs b/crates/core/src/qbft/mod.rs index fe07d504..2497424c 100644 --- a/crates/core/src/qbft/mod.rs +++ b/crates/core/src/qbft/mod.rs @@ -1283,7 +1283,9 @@ where /// Construct a function that returns true if the message is from a unique /// source. -fn uniq_source(vec: Vec>) -> impl for<'a> FnMut(&'a std::sync::Arc<(dyn SomeMsg + 'static)>) -> bool +fn uniq_source( + vec: Vec>, +) -> impl for<'a> FnMut(&'a std::sync::Arc<(dyn SomeMsg + 'static)>) -> bool where V: PartialEq, { diff --git a/crates/p2p/examples/p2p.rs b/crates/p2p/examples/p2p.rs index 4399761c..c7f296a8 100644 --- a/crates/p2p/examples/p2p.rs +++ b/crates/p2p/examples/p2p.rs @@ -62,7 +62,10 @@ async fn main() -> Result<()> { .await .ok_or(anyhow::anyhow!("Swarm event is None"))? { - SwarmEvent::NewListenAddr { .. } | SwarmEvent::Dialing { .. } | SwarmEvent::ConnectionEstablished { .. } | SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( + SwarmEvent::NewListenAddr { .. } + | SwarmEvent::Dialing { .. } + | SwarmEvent::ConnectionEstablished { .. } + | SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( PlutoBehaviourEvent::Ping(_), )) => {} SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto( diff --git a/crates/relay-server/src/utils.rs b/crates/relay-server/src/utils.rs index a865340b..02169a99 100644 --- a/crates/relay-server/src/utils.rs +++ b/crates/relay-server/src/utils.rs @@ -26,7 +26,7 @@ pub(crate) fn is_public_addr(addr: &Multiaddr) -> bool { Protocol::Ip6(ip) => { return !ip.is_loopback() && !ip.is_unspecified(); } - _ => {}, + _ => {} } } false From 485c106d7d745ad4ffc918f9912720455afa696c Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:15:28 +0200 Subject: [PATCH 09/10] fix: linter --- .../src/manifestpb/cluster.manifestpb.v1.rs | 30 +++++++++---------- crates/core/src/qbft/mod.rs | 2 +- crates/eth2util/src/enr.rs | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs b/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs index f4468589..84f4d5e7 100644 --- a/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs +++ b/crates/cluster/src/manifestpb/cluster.manifestpb.v1.rs @@ -2,10 +2,10 @@ /// Cluster represents the manifest of a cluster after applying a sequence of mutations. #[derive(Clone, PartialEq, ::prost::Message)] pub struct Cluster { - /// `InitialMutationHash` is the hash of first signed mutation, uniquely identifying cluster, aka "cluster hash". It must be 32 bytes. + /// InitialMutationHash is the hash of first signed mutation, uniquely identifying cluster, aka "cluster hash". It must be 32 bytes. #[prost(bytes = "bytes", tag = "1")] pub initial_mutation_hash: ::prost::bytes::Bytes, - /// `LatestMutationHash` is the hash of last signed mutation, identifying this specific cluster iteration. It must be 32 bytes. + /// LatestMutationHash is the hash of last signed mutation, identifying this specific cluster iteration. It must be 32 bytes. #[prost(bytes = "bytes", tag = "2")] pub latest_mutation_hash: ::prost::bytes::Bytes, /// Name is the name of the cluster. @@ -14,10 +14,10 @@ pub struct Cluster { /// Threshold is the threshold of the cluster. #[prost(int32, tag = "4")] pub threshold: i32, - /// `DKGAlgorithm` is the DKG algorithm used to create the validator keys of the cluster. + /// DKGAlgorithm is the DKG algorithm used to create the validator keys of the cluster. #[prost(string, tag = "5")] pub dkg_algorithm: ::prost::alloc::string::String, - /// `ForkVersion` is the fork version (network/chain) of the cluster. It must be 4 bytes. + /// ForkVersion is the fork version (network/chain) of the cluster. It must be 4 bytes. #[prost(bytes = "bytes", tag = "6")] pub fork_version: ::prost::bytes::Bytes, /// Operators is the list of operators of the cluster. @@ -26,10 +26,10 @@ pub struct Cluster { /// Validators is the list of validators of the cluster. #[prost(message, repeated, tag = "8")] pub validators: ::prost::alloc::vec::Vec, - /// `ConsensusProtocol` is the consensus protocol name preferred by the cluster, e.g. "abft". + /// ConsensusProtocol is the consensus protocol name preferred by the cluster, e.g. "abft". #[prost(string, tag = "9")] pub consensus_protocol: ::prost::alloc::string::String, - /// `TargetGasLimit` is the custom target gas limit for transactions. + /// TargetGasLimit is the custom target gas limit for transactions. #[prost(uint32, tag = "10")] pub target_gas_limit: u32, /// Compounding is the flag to enable compounding rewards. @@ -49,7 +49,7 @@ pub struct Mutation { #[prost(message, optional, tag = "3")] pub data: ::core::option::Option<::prost_types::Any>, } -/// `SignedMutation` is a mutation signed by a signer. +/// SignedMutation is a mutation signed by a signer. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct SignedMutation { /// Mutation is the mutation. @@ -62,7 +62,7 @@ pub struct SignedMutation { #[prost(bytes = "bytes", tag = "3")] pub signature: ::prost::bytes::Bytes, } -/// `SignedMutationList` is a list of signed mutations. +/// SignedMutationList is a list of signed mutations. #[derive(Clone, PartialEq, ::prost::Message)] pub struct SignedMutationList { /// Mutations is the list of mutations. @@ -82,30 +82,30 @@ pub struct Operator { /// Validator represents a distributed validator managed by the DV cluster. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct Validator { - /// `PublicKey` is the group public key of the validator. + /// PublicKey is the group public key of the validator. #[prost(bytes = "bytes", tag = "1")] pub public_key: ::prost::bytes::Bytes, - /// `PubShares` is the ordered list of public shares of the validator. + /// PubShares is the ordered list of public shares of the validator. #[prost(bytes = "bytes", repeated, tag = "2")] pub pub_shares: ::prost::alloc::vec::Vec<::prost::bytes::Bytes>, - /// `FeeRecipientAddress` is the fee recipient Ethereum address of the validator. + /// FeeRecipientAddress is the fee recipient Ethereum address of the validator. #[prost(string, tag = "3")] pub fee_recipient_address: ::prost::alloc::string::String, - /// `WithdrawalAddress` is the withdrawal Ethereum address of the validator. + /// WithdrawalAddress is the withdrawal Ethereum address of the validator. #[prost(string, tag = "4")] pub withdrawal_address: ::prost::alloc::string::String, - /// `BuilderRegistration` is the pre-generated json-formatted builder-API validator registration of the validator. + /// BuilderRegistration is the pre-generated json-formatted builder-API validator registration of the validator. #[prost(bytes = "bytes", tag = "5")] pub builder_registration_json: ::prost::bytes::Bytes, } -/// `ValidatorList` is a list of validators. +/// ValidatorList is a list of validators. #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidatorList { /// Validators is the list of validators. #[prost(message, repeated, tag = "1")] pub validators: ::prost::alloc::vec::Vec, } -/// `LegacyLock` represents a json formatted legacy cluster lock file. +/// LegacyLock represents a json formatted legacy cluster lock file. #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct LegacyLock { #[prost(bytes = "bytes", tag = "1")] diff --git a/crates/core/src/qbft/mod.rs b/crates/core/src/qbft/mod.rs index 2497424c..fd0253ed 100644 --- a/crates/core/src/qbft/mod.rs +++ b/crates/core/src/qbft/mod.rs @@ -480,7 +480,7 @@ where ct, d, &msg, - &input_value_source_ch, + input_value_source_ch, input_value_source.clone(), &timer_chan, ); diff --git a/crates/eth2util/src/enr.rs b/crates/eth2util/src/enr.rs index aa181096..78e63a1f 100644 --- a/crates/eth2util/src/enr.rs +++ b/crates/eth2util/src/enr.rs @@ -147,7 +147,7 @@ impl Record { opt(&mut kvs); } - let signature = sign(&secret_key, &encode_elements(&[], &kvs))?; + let signature = sign(secret_key, &encode_elements(&[], &kvs))?; Ok(Record { public_key: Some(secret_key.public_key()), From d7899d61efb6d1cf2635f9d4badbb4611714af5d Mon Sep 17 00:00:00 2001 From: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:22:48 +0200 Subject: [PATCH 10/10] fix: compilation --- crates/core/src/qbft/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/qbft/mod.rs b/crates/core/src/qbft/mod.rs index fd0253ed..b78b925e 100644 --- a/crates/core/src/qbft/mod.rs +++ b/crates/core/src/qbft/mod.rs @@ -1285,7 +1285,7 @@ where /// source. fn uniq_source( vec: Vec>, -) -> impl for<'a> FnMut(&'a std::sync::Arc<(dyn SomeMsg + 'static)>) -> bool +) -> impl for<'a> FnMut(&'a std::sync::Arc + 'static>) -> bool where V: PartialEq, {