From 1f40b32b6aedaaff2016cb20f9e2a3d9c681c651 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Wed, 3 Dec 2025 11:44:08 +0000 Subject: [PATCH] protocol: provide more information for invalid timestamps The invalid timestamp error will only tell the timestamp of the offending node's message. Currently, there are issues where that error is occurring but the timestamp seems legitimate. This patch adds the running node's timestamp to help debug the issue. --- crates/radicle-node/src/tests.rs | 4 ++-- crates/radicle-protocol/src/service.rs | 2 +- crates/radicle-protocol/src/service/session.rs | 14 +++++++++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/crates/radicle-node/src/tests.rs b/crates/radicle-node/src/tests.rs index f7894cb8..ea8ba45e 100644 --- a/crates/radicle-node/src/tests.rs +++ b/crates/radicle-node/src/tests.rs @@ -457,8 +457,8 @@ fn test_inventory_relay_bad_timestamp() { ); assert_matches!( alice.outbox().next(), - Some(Io::Disconnect(addr, DisconnectReason::Session(session::Error::InvalidTimestamp(t)))) - if addr == bob.id() && t == timestamp + Some(Io::Disconnect(addr, DisconnectReason::Session(session::Error::InvalidTimestamp(session::InvalidTimestamp::Future { theirs, .. })))) + if addr == bob.id() && theirs == timestamp ); } diff --git a/crates/radicle-protocol/src/service.rs b/crates/radicle-protocol/src/service.rs index 5743a19a..fc114f17 100644 --- a/crates/radicle-protocol/src/service.rs +++ b/crates/radicle-protocol/src/service.rs @@ -1461,7 +1461,7 @@ where // Don't allow messages from too far in the future. if timestamp.saturating_sub(now.as_millis()) > MAX_TIME_DELTA.as_millis() as u64 { - return Err(session::Error::InvalidTimestamp(timestamp)); + return Err(session::Error::future_timestamp(timestamp, now.into())); } // We don't process announcements from nodes we don't know, since the node announcement is diff --git a/crates/radicle-protocol/src/service/session.rs b/crates/radicle-protocol/src/service/session.rs index 1bf41594..e7094f49 100644 --- a/crates/radicle-protocol/src/service/session.rs +++ b/crates/radicle-protocol/src/service/session.rs @@ -21,7 +21,7 @@ pub enum Error { /// The remote peer sent an invalid announcement timestamp, /// for eg. a timestamp far in the future. #[error("invalid announcement timestamp: {0}")] - InvalidTimestamp(Timestamp), + InvalidTimestamp(InvalidTimestamp), /// The remote peer sent git protocol messages while we were expecting /// gossip messages. Or vice-versa. #[error("protocol mismatch")] @@ -34,6 +34,18 @@ pub enum Error { Timeout, } +impl Error { + pub(crate) fn future_timestamp(theirs: Timestamp, ours: Timestamp) -> Self { + Self::InvalidTimestamp(InvalidTimestamp::Future { theirs, ours }) + } +} + +#[derive(thiserror::Error, Debug, Clone, Copy)] +pub enum InvalidTimestamp { + #[error("{theirs} appears too far in the future compared to {ours}")] + Future { theirs: Timestamp, ours: Timestamp }, +} + impl Error { /// Return the severity for this error. pub fn severity(&self) -> Severity {