From: Matt Corallo Date: Fri, 8 Jul 2022 01:16:05 +0000 (+0000) Subject: Avoid panicking on wallclock time going backwards across restart X-Git-Tag: v0.0.110~19^2 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=refs%2Fheads%2F2022-07-no-backwards-time;p=rust-lightning Avoid panicking on wallclock time going backwards across restart Because we serialize `Instant`s using wallclock time in `ProbabilisticScorer`, if time goes backwards across restarts we may end up with `Instant`s in the future, which causes rustc prior to 1.60 to panic when calculating durations. Here we simply avoid this by setting the time to `now` if we get a time in the future. --- diff --git a/lightning/src/routing/scoring.rs b/lightning/src/routing/scoring.rs index 524f0ed31..95bb25590 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -1177,10 +1177,22 @@ impl Readable for ChannelLiquidity { (2, max_liquidity_offset_msat, required), (4, duration_since_epoch, required), }); + // On rust prior to 1.60 `Instant::duration_since` will panic if time goes backwards. + // We write `last_updated` as wallclock time even though its ultimately an `Instant` (which + // is a time from a monotonic clock usually represented as an offset against boot time). + // Thus, we have to construct an `Instant` by subtracting the difference in wallclock time + // from the one that was written. However, because `Instant` can panic if we construct one + // in the future, we must handle wallclock time jumping backwards, which we do by simply + // using `Instant::now()` in that case. + let wall_clock_now = T::duration_since_epoch(); + let now = T::now(); + let last_updated = if wall_clock_now > duration_since_epoch { + now - (wall_clock_now - duration_since_epoch) + } else { now }; Ok(Self { min_liquidity_offset_msat, max_liquidity_offset_msat, - last_updated: T::now() - (T::duration_since_epoch() - duration_since_epoch), + last_updated, }) } }