From 60e32c9d3b4bee42ac698791e917e1587eaa1388 Mon Sep 17 00:00:00 2001 From: Yiannis Marangos Date: Tue, 11 Jun 2024 01:17:16 +0300 Subject: [PATCH] fix(ping): Fix panic in WASM caused by retrying on dial upgrade errors This PR workarounds async-rs/futures-timer#74 issue. Fixes #5442 Pull-Request: #5447. --- protocols/ping/CHANGELOG.md | 3 +++ protocols/ping/src/handler.rs | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/protocols/ping/CHANGELOG.md b/protocols/ping/CHANGELOG.md index 507bf7532ba..7c7d7f3a54f 100644 --- a/protocols/ping/CHANGELOG.md +++ b/protocols/ping/CHANGELOG.md @@ -3,6 +3,9 @@ - Use `web-time` instead of `instant`. See [PR 5347](https://github.com/libp2p/rust-libp2p/pull/5347). +- Fix panic in WASM caused by retrying on dial upgrade errors. + See [PR 5447](https://github.com/libp2p/rust-libp2p/pull/5447). + ## 0.44.1 - Impose `Sync` on `ping::Failure::Other`. diff --git a/protocols/ping/src/handler.rs b/protocols/ping/src/handler.rs index b9bd25c52ea..2816cdc4048 100644 --- a/protocols/ping/src/handler.rs +++ b/protocols/ping/src/handler.rs @@ -184,6 +184,18 @@ impl Handler { ) { self.outbound = None; // Request a new substream on the next `poll`. + // Timer is already polled and expired before substream request is initiated + // and will be polled again later on in our `poll` because we reset `self.outbound`. + // + // `futures-timer` allows an expired timer to be polled again and returns + // immediately `Poll::Ready`. However in its WASM implementation there is + // a bug that causes the expired timer to panic. + // This is a workaround until a proper fix is merged and released. + // See libp2p/rust-libp2p#5447 for more info. + // + // TODO: remove when async-rs/futures-timer#74 gets merged. + self.interval.reset(Duration::new(0, 0)); + let error = match error { StreamUpgradeError::NegotiationFailed => { debug_assert_eq!(self.state, State::Active);