From be7d69c3cb1282be4f8ad57243b799515c8dbaf4 Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 25 May 2021 13:42:45 +1000 Subject: [PATCH] Try arbitrary leap seconds --- zebra-chain/src/serialization/arbitrary.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/zebra-chain/src/serialization/arbitrary.rs b/zebra-chain/src/serialization/arbitrary.rs index 71e8cdd67..e4a9b9c16 100644 --- a/zebra-chain/src/serialization/arbitrary.rs +++ b/zebra-chain/src/serialization/arbitrary.rs @@ -4,19 +4,27 @@ use proptest::{arbitrary::any, prelude::*}; /// Returns a strategy that produces an arbitrary [`chrono::DateTime`], /// based on the full valid range of the type. /// -/// Both the seconds and nanoseconds values are randomised. But leap nanoseconds -/// are never present. -/// https://docs.rs/chrono/0.4.19/chrono/struct.DateTime.html#method.timestamp_subsec_nanos +/// Both the seconds and nanoseconds values are randomised, including leap seconds: +/// https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveTime.html#leap-second-handling /// -/// Zebra uses these times internally, via [`Utc::now`]. +/// Wherever possible, Zebra should handle leap seconds by: +/// - making durations and intervals 3 seconds or longer, +/// - avoiding complex time-based calculations, and +/// - avoiding relying on subsecond precision or time order. +/// When monotonic times are needed, use the opaque `std::time::Instant` type. +/// +/// # Usage +/// +/// Zebra uses these times internally, typically via [`Utc::now`]. /// /// Some parts of the Zcash network protocol ([`Version`] messages) also use times /// with an 8-byte seconds value. Unlike this function, they have zero -/// nanoseconds values. +/// nanoseconds values. (So they never have `chrono` leap seconds.) pub fn datetime_full() -> impl Strategy> { ( + // TODO: should we be subtracting 1 from the maximum timestamp? MIN_DATETIME.timestamp()..=MAX_DATETIME.timestamp(), - 0..1_000_000_000_u32, + 0..2_000_000_000_u32, ) .prop_map(|(secs, nsecs)| Utc.timestamp(secs, nsecs)) }