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 {