eclipse-zenoh / zenoh

zenoh unifies data in motion, data in-use, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks.
https://zenoh.io
Other
1.41k stars 146 forks source link

Zenoh timestamps will roll over in 12 years #1252

Open andrew-otiv opened 1 month ago

andrew-otiv commented 1 month ago

Describe the bug

The 32 bit seconds-since-unix-epoch format used by the uhlc crate, based on the 32 bit seconds in NTP, will roll over in only 12 years (2036). I've seen in a few places on the internet that the likely resolution will be for NTP's seconds to be upgraded to u64 seconds. Protobufs already use a 64 bit seconds, 32 bit nanoseconds format (but truncated to ). This seems compatible with the hybrid logical clock concept.

The rust protobuf library we're using is prost, which has a type: https://docs.rs/prost-types/latest/prost_types/struct.Timestamp.html

Using an EPOCH other than the unix epoch would extend the usefulness of zenoh timestamps, but I think that would be more error prone for users than using a higher capacity clock.

To reproduce

Time travel a baker's decade into the future and watch systems build on zenoh fail.

System info

affects all platforms, unless I'm missing something.

noxpardalis commented 1 month ago

Hi, I'm not from the Zenoh team (from the Cyclone DDS sister project :tornado: instead :wave:) but I wanted to chime-in with a clarification that the 2038 roll-over is if you're using 32-bit signed integers for representing the time since Unix epoch. If you're using unsigned integers the boundary is 7 February 2106 at 06:28:15 UTC (2106-07-02T06:28:15Z).

When doing some quick testing with the uhlc crate by @JEnoch:

use uhlc::Timestamp;

fn main() {
    let timestamp_valid = Timestamp::parse_rfc3339("2106-02-07T06:28:15Z/33");
    println!("{timestamp_valid:?}");
    println!("{:#}", timestamp_valid.unwrap());
    let timestamp_panic = Timestamp::parse_rfc3339("2106-02-07T06:28:16Z/33");
    println!("it panics");
}

You'll have the first timestamp on the boundary parse and the subsequent timestamp panic.

Ok(18446744069414584321/33)
2106-02-07T06:28:15.000000000Z/33
thread 'main' panicked at .../.cargo/registry/src/index.crates.io-6f17d22bba15001f/uhlc-0.8.0/src/ntp64.rs:281:9:
assertion failed: secs <= MAX_NB_SEC

The MAX_NB_SEC constant is defined here as:

// maximal number of seconds that can be represented in the 32-bits part
const MAX_NB_SEC: u64 = (1u64 << 32) - 1;

According to https://datatracker.ietf.org/doc/html/rfc5905#section-6 the representation used in the NTP 64-bit timestamp format is capable of supporting 136 years per era which from Unix epoch indeed corresponds to 2106. So I think the boundary here is defintely more than 13 years away.

Mallets commented 1 month ago

Thanks @noxpardalis , very insightful! Then I believe we are safe for now and for another 82 years...

andrew-otiv commented 1 month ago

I stand corrected! I didn't dig deep enough... and just saw that uhlc was guaranteed to be close to NTP timestamps in the HLC paper: https://cse.buffalo.edu/tech-reports/2014-04.pdf

and that NTP Timestamps have issues starting in 2038: https://www.ntp.org/reflib/y2k/#:~:text=An%20NTP%20timestamp%20is%20a,a%20precision%20of%20232%20ps.

For your entertainment, we are writing software for electric locomotives. They're expensive and do not get replaced frequently. Not counting old steam locomotives that are only kept alive for tourism, the oldest loco still in service, Amtrak 737, was built in 1942, so 82 years old. If we shipped our software on a brand new locomotive today, if the entire subsystem never gets ripped out and replaced, if we never had the opportunity to update our software for 82 years, and if nothing else dooms the locomotive to obsolescence first, then there is still an absurdly small remaining chance that the uint32 seconds in our zenoh dependency will be the first thing that breaks in exactly 82 years!