Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/app/src/eth2wrap/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ enum BeaconNodeVersionError {

static MINIMUM_BEACON_NODE_VERSIONS: LazyLock<std::collections::HashMap<&str, version::SemVer>> =
LazyLock::new(|| {
#[allow(clippy::unwrap_used, reason = "literals should be valid semver")]
#[expect(clippy::unwrap_used, reason = "literals should be valid semver")]
std::collections::HashMap::from([
("lighthouse", version::SemVer::parse("v8.0.0-rc.0").unwrap()),
("teku", version::SemVer::parse("v25.9.3").unwrap()),
Expand Down
4 changes: 2 additions & 2 deletions crates/app/src/health/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub(crate) struct Check {
pub(crate) name: &'static str,
/// Human-readable description. Not yet surfaced anywhere; retained for
/// completeness.
#[allow(
#[expect(
dead_code,
reason = "retained for completeness; surfaced by future tooling"
)]
Expand All @@ -68,7 +68,7 @@ fn label(name: &str, value: &str) -> LabelPair {
}

/// Lossy `i64` → `f64` conversion used only for threshold comparisons.
#[allow(
#[expect(
clippy::cast_precision_loss,
reason = "validator/peer counts are small; threshold comparison does not require exactness"
)]
Expand Down
2 changes: 1 addition & 1 deletion crates/app/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ fn production_parsigex_seam(handles: &CoreHandles) -> ParSigExSeam {

/// Spawns and supervises the node's long-lived tasks, then performs an ordered
/// shutdown on cancellation or first-task failure.
#[allow(
#[expect(
clippy::too_many_arguments,
reason = "aggregates independent long-lived inputs (swarm, consensus, wired components, monitoring); a single config struct would just move the coupling"
)]
Expand Down
2 changes: 1 addition & 1 deletion crates/app/src/retry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ pub async fn do_async<
let deadline = (options.deadline_fn)(t);
let now = options.clock.now();

#[allow(
#[expect(
clippy::arithmetic_side_effects,
reason = "chrono to std conversion is safe for negative values"
)]
Expand Down
14 changes: 8 additions & 6 deletions crates/cli/src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,14 +648,16 @@ pub struct RunConfig {
/// Beacon node submission request timeout.
pub beacon_node_submit_timeout: StdDuration,
/// \[DISABLED\] Jaeger tracing address.
// Accepted for Charon flag parity; `RunConfig::try_from` already warns
// when set, and the field is never read again.
#[allow(dead_code)]
#[expect(
dead_code,
reason = "accepted for Charon flag parity; `RunConfig::try_from` already warns when set, and the field is never read again"
)]
pub jaeger_addr: String,
/// \[DISABLED\] Jaeger tracing service name.
// Accepted for Charon flag parity; `RunConfig::try_from` already warns
// when set, and the field is never read again.
#[allow(dead_code)]
#[expect(
dead_code,
reason = "accepted for Charon flag parity; `RunConfig::try_from` already warns when set, and the field is never read again"
)]
pub jaeger_service: String,
/// OTLP gRPC tracing backend address.
pub otlp_address: String,
Expand Down
57 changes: 45 additions & 12 deletions crates/cli/src/commands/test/beacon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,17 +969,29 @@ async fn single_cluster_simulation(cancel: CancellationToken, target: &str) -> S
let mut slot = get_current_slot(target).await.unwrap_or(1);

let now = Instant::now();
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small fixed interval to a fresh Instant cannot overflow in practice"
)]
let mut slot_interval = interval_at(now + SLOT_TIME, SLOT_TIME);
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small fixed interval to a fresh Instant cannot overflow in practice"
)]
let mut interval_12_slots = interval_at(
now + SLOT_TIME.saturating_mul(12),
SLOT_TIME.saturating_mul(12),
);
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small fixed interval to a fresh Instant cannot overflow in practice"
)]
let mut interval_10_sec =
interval_at(now + StdDuration::from_secs(10), StdDuration::from_secs(10));
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small fixed interval to a fresh Instant cannot overflow in practice"
)]
let mut interval_minute =
interval_at(now + StdDuration::from_secs(60), StdDuration::from_secs(60));

Expand Down Expand Up @@ -1293,7 +1305,10 @@ async fn attestation_duty(
{
return Default::default();
}
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small tick interval to a fresh Instant cannot overflow in practice"
)]
let mut interval = interval_at(Instant::now() + tick_time, tick_time);
let mut slot = cancel
.run_until_cancelled(get_current_slot(target))
Expand Down Expand Up @@ -1346,7 +1361,10 @@ async fn aggregation_duty(
{
return Default::default();
}
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small tick interval to a fresh Instant cannot overflow in practice"
)]
let mut interval = interval_at(Instant::now() + tick_time, tick_time);

loop {
Expand Down Expand Up @@ -1392,7 +1410,10 @@ async fn proposal_duty(
{
return Default::default();
}
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small tick interval to a fresh Instant cannot overflow in practice"
)]
let mut interval = interval_at(Instant::now() + tick_time, tick_time);
let mut slot = cancel
.run_until_cancelled(get_current_slot(target))
Expand Down Expand Up @@ -1426,7 +1447,10 @@ async fn proposal_duty(
(produce_all, publish_all)
}

#[allow(clippy::too_many_arguments)]
#[expect(
clippy::too_many_arguments,
reason = "orchestrates several independent sync-committee duty streams; splitting the arguments into a struct would not improve clarity"
)]
async fn sync_committee_duties(
cancel: CancellationToken,
target: &str,
Expand Down Expand Up @@ -1459,7 +1483,10 @@ async fn sync_committee_duties(
{
return;
}
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small tick interval to a fresh Instant cannot overflow in practice"
)]
let mut interval = interval_at(Instant::now() + tick_time_subscribe, tick_time_subscribe);

loop {
Expand Down Expand Up @@ -1491,7 +1518,10 @@ async fn sync_committee_contribution_duty(
{
return;
}
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small tick interval to a fresh Instant cannot overflow in practice"
)]
let mut interval = interval_at(Instant::now() + tick_time, tick_time);
let mut slot = cancel
.run_until_cancelled(get_current_slot(target))
Expand Down Expand Up @@ -1543,7 +1573,10 @@ async fn sync_committee_message_duty(
{
return;
}
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a small tick interval to a fresh Instant cannot overflow in practice"
)]
let mut interval = interval_at(Instant::now() + tick_time, tick_time);

loop {
Expand Down Expand Up @@ -1634,7 +1667,7 @@ fn generate_simulation_values(durations: &[StdDuration], endpoint: &str) -> Simu
tracing::warn!("Failed to convert duration length to u32");
u32::MAX
});
#[allow(
#[expect(
clippy::arithmetic_side_effects,
reason = "count is non-zero (early return above)"
)]
Expand Down
4 changes: 4 additions & 0 deletions crates/cli/src/commands/test/infra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ struct FioResultSingle {
bw: f64,
}

// `expect` cannot be used here: the lint does not fire under the current
// toolchain, so it would be flagged as an unfulfilled expectation. Kept as
// `allow` for forward compatibility. Reason: internal trait not part of the
// public API; no need for the `Send` bound the lint guards against.
#[allow(async_fn_in_trait)]
trait DiskTestTool {
async fn check_availability(&self) -> Result<()>;
Expand Down
6 changes: 4 additions & 2 deletions crates/cli/src/commands/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
//! cluster setup, including tests for peers, beacon nodes, validator clients,
//! MEV relays, and infrastructure.

// TODO: Foundation for the test command, the detail will be implemented later
#![allow(dead_code)]
#![expect(
dead_code,
reason = "foundation for the test command; the detail will be implemented later"
)]

pub mod all;
pub mod beacon;
Expand Down
25 changes: 19 additions & 6 deletions crates/cli/src/commands/test/peers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ struct TestBehaviour {
#[derive(Debug)]
enum TestBehaviourEvent {
Relay(relay::client::Event),
RelayManager(#[allow(dead_code)] pluto_p2p::relay::RelayManagerEvent),
RelayManager(
#[expect(
dead_code,
reason = "event payload is never read; only the variant tag matters"
)]
pluto_p2p::relay::RelayManagerEvent,
),
}

impl From<relay::client::Event> for TestBehaviourEvent {
Expand Down Expand Up @@ -98,9 +104,10 @@ pub struct TestPeersArgs {
pub test_config: TestConfigArgs,

/// [REQUIRED] Comma-separated list of each peer ENR address.
// Doc comment doubles as clap help text, so the brackets must stay
// literal rather than becoming a rustdoc link.
#[allow(rustdoc::broken_intra_doc_links)]
#[expect(
rustdoc::broken_intra_doc_links,
reason = "doc comment doubles as clap help text, so the brackets must stay literal rather than becoming a rustdoc link"
)]
#[arg(long = "enrs", value_delimiter = ',')]
pub enrs: Option<Vec<String>>,

Expand Down Expand Up @@ -657,7 +664,10 @@ struct PeerState {
identify_received: bool,
}

#[allow(clippy::too_many_arguments)]
#[expect(
clippy::too_many_arguments,
reason = "drives the peer test event loop from many independent inputs; grouping them into a struct would not improve clarity"
)]
async fn run_peer_event_loop(
mut node: Node<TestBehaviour>,
cluster_peers: &[Peer],
Expand Down Expand Up @@ -1045,7 +1055,10 @@ async fn keep_node_alive(
ct: CancellationToken,
) {
tracing::info!("Keeping TCP node alive until keep-alive time is reached...");
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "adding a bounded keep-alive interval to a fresh Instant cannot overflow in practice"
)]
let deadline = tokio::time::Instant::now() + keep_alive;
loop {
let remaining = deadline.saturating_duration_since(tokio::time::Instant::now());
Expand Down
10 changes: 7 additions & 3 deletions crates/cli/src/commands/test/speedtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,14 @@ pub(super) fn bytes_to_mbps(bytes: usize, elapsed: Duration) -> f64 {
return 0.0;
}

#[allow(
// `arithmetic_side_effects` cannot be an `expect`: the arithmetic below is
// all floating-point, which the lint never fires on, so it would be an
// unfulfilled expectation. Kept as `allow`. Reason: arithmetic overflow is
// impossible for realistic network speeds.
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::cast_precision_loss,
clippy::arithmetic_side_effects,
reason = "precision loss requires >8PB transferred; arithmetic overflow is impossible for realistic network speeds"
reason = "precision loss requires >8PB transferred"
)]
let bytes: f64 = bytes as f64;
bytes * 8.0 / secs / 1_000_000.0
Expand Down
26 changes: 20 additions & 6 deletions crates/cli/src/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ impl Duration {
}

/// Rounds the duration based on its magnitude
#[allow(clippy::cast_possible_truncation, clippy::arithmetic_side_effects)]
#[expect(
clippy::cast_possible_truncation,
clippy::arithmetic_side_effects,
reason = "rounding arithmetic on bounded millisecond/microsecond values cannot overflow, and the u128->u64 casts fit the rounded magnitudes"
)]
pub fn round(self) -> Self {
let rounded = if self.inner > StdDuration::from_secs(1) {
// Round to 10ms
Expand Down Expand Up @@ -183,10 +187,11 @@ pub fn parse_go_duration(s: &str) -> Result<StdDuration, String> {
if frac > 0 {
// Match Go: float64 is nanosecond-accurate for fractions of the
// largest unit (hours).
#[allow(
#[expect(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss
clippy::cast_sign_loss,
reason = "matches Go: float64 is nanosecond-accurate for fractions of the largest unit (hours), and the result is bounded by GO_MAX_DURATION_NANOS"
)]
let frac_nanos = (frac as f64 * (unit as f64 / scale)) as u64;
nanos = nanos
Expand Down Expand Up @@ -274,7 +279,10 @@ impl fmt::Display for Duration {
}

/// Formats a duration like Go's `time.Duration.String()`.
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "buffer index and unit arithmetic operate on a fixed 32-byte buffer sized for the maximum u64 duration, so it cannot overflow or underflow"
)]
fn format_go_duration(duration: StdDuration) -> String {
let nanos_u128 = duration.as_nanos();
let mut u: u64 = u64::try_from(nanos_u128).unwrap_or(u64::MAX);
Expand Down Expand Up @@ -354,7 +362,10 @@ fn format_go_duration(duration: StdDuration) -> String {

/// Formats the fraction of `v / 10**prec` into the tail of `buf`, omitting
/// trailing zeros. Returns the new start index and `v / 10**prec`.
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "buffer index arithmetic stays within the caller's fixed buffer and prec is bounded, so it cannot overflow or underflow"
)]
fn fmt_frac(buf: &mut [u8], mut v: u64, prec: usize) -> (usize, u64) {
// Omit trailing zeros up to and including decimal point.
let mut w = buf.len();
Expand All @@ -380,7 +391,10 @@ fn fmt_frac(buf: &mut [u8], mut v: u64, prec: usize) -> (usize, u64) {

/// Formats `v` into the tail of `buf`. Returns the index where the output
/// begins.
#[allow(clippy::arithmetic_side_effects)]
#[expect(
clippy::arithmetic_side_effects,
reason = "buffer index arithmetic stays within the caller's fixed buffer sized for the maximum u64, so it cannot overflow or underflow"
)]
fn fmt_int(buf: &mut [u8], mut v: u64) -> usize {
let mut w = buf.len();
if v == 0 {
Expand Down
5 changes: 4 additions & 1 deletion crates/cluster/src/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,10 @@ pub enum InvalidGasLimitError {

impl Definition {
/// Create a new cluster definition.
#[allow(clippy::too_many_arguments)]
#[expect(
clippy::too_many_arguments,
reason = "constructor mirrors the full cluster definition field set"
)]
pub fn new(
name: String,
num_validators: u64,
Expand Down
4 changes: 2 additions & 2 deletions crates/cluster/src/test_cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ pub fn new_for_test(

for i in 0..n {
// Generate ENR
#[allow(
#[expect(
clippy::arithmetic_side_effects,
reason = "matches the original implementation, test code only"
)]
#[allow(
#[expect(
clippy::cast_possible_truncation,
reason = "intentional truncation for testing purposes"
)]
Expand Down
6 changes: 4 additions & 2 deletions crates/core/src/bcast/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ pub(crate) fn instrument_duty(duty: &Duty, delay: Option<Duration>) {
BCAST_METRICS.broadcast_total[&duty_type].inc();

if let Some(delay) = delay {
// Delays never approach f64's 2^53 ms exact range, so the cast is exact.
#[allow(clippy::cast_precision_loss)]
#[expect(
clippy::cast_precision_loss,
reason = "delays never approach f64's 2^53 ms exact range, so the cast is exact"
)]
let seconds = delay.num_milliseconds() as f64 / 1_000.0;
BCAST_METRICS.broadcast_delay_seconds[&duty_type].observe(seconds);
}
Expand Down
Loading
Loading