From 9527352bada57d64fcfa80fd7863f2784c7158b4 Mon Sep 17 00:00:00 2001
From: Pierre Krieger <pierre.krieger1708@gmail.com>
Date: Wed, 26 Apr 2023 14:32:25 +0200
Subject: [PATCH 1/7] Use the wasi functions for time retrieval

---
 .../src/instance/bindings-smoldot-light.ts    | 11 ---
 .../javascript/src/instance/bindings-wasi.ts  | 40 +++++++++
 wasm-node/javascript/src/instance/buffer.ts   | 12 +++
 .../javascript/src/instance/raw-instance.ts   |  2 +-
 wasm-node/rust/src/bindings.rs                | 32 --------
 wasm-node/rust/src/cpu_rate_limiter.rs        |  6 +-
 wasm-node/rust/src/lib.rs                     | 81 +------------------
 wasm-node/rust/src/platform.rs                | 15 ++--
 wasm-node/rust/src/timers.rs                  |  4 +-
 9 files changed, 65 insertions(+), 138 deletions(-)

diff --git a/wasm-node/javascript/src/instance/bindings-smoldot-light.ts b/wasm-node/javascript/src/instance/bindings-smoldot-light.ts
index 5088a45ec6..566f8da0d4 100644
--- a/wasm-node/javascript/src/instance/bindings-smoldot-light.ts
+++ b/wasm-node/javascript/src/instance/bindings-smoldot-light.ts
@@ -33,11 +33,6 @@ export interface Config {
      */
     bufferIndices: Array<Uint8Array>,
 
-    /**
-     * Returns the number of milliseconds since an arbitrary epoch.
-     */
-    performanceNow: () => number,
-
     /**
      * Tries to open a new connection using the given configuration.
      *
@@ -307,12 +302,6 @@ export default function (config: Config): { imports: WebAssembly.ModuleImports,
             }
         },
 
-        // Must return the UNIX time in milliseconds.
-        unix_time_ms: () => Date.now(),
-
-        // Must return the value of a monotonic clock in milliseconds.
-        monotonic_clock_ms: () => config.performanceNow(),
-
         // Must call `timer_finished` after the given number of milliseconds has elapsed.
         start_timer: (id: number, ms: number) => {
             if (killedTracked.killed) return;
diff --git a/wasm-node/javascript/src/instance/bindings-wasi.ts b/wasm-node/javascript/src/instance/bindings-wasi.ts
index ee222bd257..01540b8872 100644
--- a/wasm-node/javascript/src/instance/bindings-wasi.ts
+++ b/wasm-node/javascript/src/instance/bindings-wasi.ts
@@ -34,6 +34,11 @@ export interface Config {
      */
     getRandomValues: (buffer: Uint8Array) => void,
 
+    /**
+     * Returns the number of milliseconds since an arbitrary epoch.
+     */
+    performanceNow: () => number,
+
     /**
      * List of environment variables to feed to the Rust program. An array of strings.
      * Example: `["RUST_BACKTRACE=1", "RUST_LOG=foo"];`
@@ -75,6 +80,41 @@ export default (config: Config): WebAssembly.ModuleImports => {
             return 0;
         },
 
+        clock_time_get: (clockId: number, _precision: bigint, outPtr: number): number => {
+            // See <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/wasi/time.rs>
+            // and <docs.rs/wasi/> for help.
+
+            const instance = config.instance!;
+            const mem = new Uint8Array(instance.exports.memory.buffer);
+            outPtr >>>= 0;
+
+            // We ignore the precision, as it can't be implemented anyway.
+
+            switch (clockId) {
+                case 0: {
+                    // Realtime clock.
+                    const now = BigInt(Date.now()) * BigInt(1_000_000);
+                    buffer.writeUInt64LE(mem, outPtr, now)
+
+                    // Success.
+                    return 0;
+                }
+                case 1: {
+                    // Monotonic clock.
+                    const nowMs = config.performanceNow();
+                    const now = BigInt(Math.floor(nowMs)) * BigInt(1_000_000) +
+                        BigInt(Math.floor(((nowMs - Math.floor(nowMs)) * 1_000_000)));
+                    buffer.writeUInt64LE(mem, outPtr, now)
+
+                    // Success.
+                    return 0;
+                }
+                default:
+                    // Return an `EINVAL` error.
+                    return 28
+            }
+        },
+
         // Writing to a file descriptor is used in order to write to stdout/stderr.
         fd_write: (fd: number, addr: number, num: number, outPtr: number) => {
             const instance = config.instance!;
diff --git a/wasm-node/javascript/src/instance/buffer.ts b/wasm-node/javascript/src/instance/buffer.ts
index c259039c3b..9aa72f53ef 100644
--- a/wasm-node/javascript/src/instance/buffer.ts
+++ b/wasm-node/javascript/src/instance/buffer.ts
@@ -47,6 +47,18 @@ export function writeUInt32LE(buffer: Uint8Array, offset: number, value: number)
     buffer[offset] = value & 0xff
 }
 
+export function writeUInt64LE(buffer: Uint8Array, offset: number, value: bigint) {
+    checkRange(buffer, offset, 8);
+    buffer[offset + 7] = Number((value >> BigInt(56)) & BigInt(0xff))
+    buffer[offset + 6] = Number((value >> BigInt(48)) & BigInt(0xff))
+    buffer[offset + 5] = Number((value >> BigInt(40)) & BigInt(0xff))
+    buffer[offset + 4] = Number((value >> BigInt(32)) & BigInt(0xff))
+    buffer[offset + 3] = Number((value >> BigInt(24)) & BigInt(0xff))
+    buffer[offset + 2] = Number((value >> BigInt(16)) & BigInt(0xff))
+    buffer[offset + 1] = Number((value >> BigInt(8)) & BigInt(0xff))
+    buffer[offset] = Number(value & BigInt(0xff))
+}
+
 function checkRange(buffer: Uint8Array, offset: number, length: number) {
     if (!Number.isInteger(offset) || offset < 0)
         throw new RangeError()
diff --git a/wasm-node/javascript/src/instance/raw-instance.ts b/wasm-node/javascript/src/instance/raw-instance.ts
index 93d9ee94c4..724d3dc9b8 100644
--- a/wasm-node/javascript/src/instance/raw-instance.ts
+++ b/wasm-node/javascript/src/instance/raw-instance.ts
@@ -105,7 +105,6 @@ export async function startInstance(config: Config, platformBindings: PlatformBi
     // Used to bind with the smoldot-light bindings. See the `bindings-smoldot-light.js` file.
     const smoldotJsConfig: SmoldotBindingsConfig = {
         bufferIndices,
-        performanceNow: platformBindings.performanceNow,
         connect: platformBindings.connect,
         onPanic: (message) => {
             killAll();
@@ -119,6 +118,7 @@ export async function startInstance(config: Config, platformBindings: PlatformBi
     const wasiConfig: WasiConfig = {
         envVars: [],
         getRandomValues: platformBindings.getRandomValues,
+        performanceNow: platformBindings.performanceNow,
         onProcExit: (retCode) => {
             killAll();
             config.onWasmPanic(`proc_exit called: ${retCode}`)
diff --git a/wasm-node/rust/src/bindings.rs b/wasm-node/rust/src/bindings.rs
index 2d6bbbaa6b..030e5a323a 100644
--- a/wasm-node/rust/src/bindings.rs
+++ b/wasm-node/rust/src/bindings.rs
@@ -130,38 +130,6 @@ extern "C" {
     /// virtual machine at offset `ptr` and with length `len`.
     pub fn log(level: u32, target_ptr: u32, target_len: u32, message_ptr: u32, message_len: u32);
 
-    /// Must return the number of milliseconds that have passed since the UNIX epoch, ignoring
-    /// leap seconds.
-    ///
-    /// Must never return `NaN` or infinite.
-    ///
-    /// This is typically implemented by calling `Date.now()`.
-    ///
-    /// See <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now>
-    ///
-    /// > **Note**: Ideally this function isn't needed. The wasi target supports clocks through
-    /// >           the `clock_time_get` syscall. However, since `clock_time_get` uses `u64s`, and
-    /// >           browsers don't support `u64s`, using it causes an unbypassable exception. See
-    /// >           also <https://github.com/dcodeIO/webassembly/issues/26#issuecomment-410157370>.
-    pub fn unix_time_ms() -> f64;
-
-    /// Must return the number of milliseconds that have passed since an arbitrary point in time.
-    ///
-    /// Must never return `NaN` or infinite.
-    ///
-    /// Contrary to [`unix_time_ms`], the returned value must never be inferior to a value
-    /// previously returned. Consequently, this must not be implemented using `Date.now()`, whose
-    /// value can decrease if the user adjusts their machine's clock, but rather with
-    /// `Performance.now()` or similar.
-    ///
-    /// See <https://developer.mozilla.org/fr/docs/Web/API/Performance/now>
-    ///
-    /// > **Note**: Ideally this function isn't needed. The wasi target supports clocks through
-    /// >           the `clock_time_get` syscall. However, since `clock_time_get` uses `u64s`, and
-    /// >           browsers don't support `u64s`, using it causes an unbypassable exception. See
-    /// >           also <https://github.com/dcodeIO/webassembly/issues/26#issuecomment-410157370>.
-    pub fn monotonic_clock_ms() -> f64;
-
     /// After at least `milliseconds` milliseconds have passed, must call [`timer_finished`] with
     /// the `id` passed as parameter.
     ///
diff --git a/wasm-node/rust/src/cpu_rate_limiter.rs b/wasm-node/rust/src/cpu_rate_limiter.rs
index e2178261dd..1799806ec3 100644
--- a/wasm-node/rust/src/cpu_rate_limiter.rs
+++ b/wasm-node/rust/src/cpu_rate_limiter.rs
@@ -22,6 +22,8 @@ use core::{
     time::Duration,
 };
 
+use std::time::Instant;
+
 /// Wraps around a `Future` and enforces an upper bound to the CPU consumed by the polling of
 /// this `Future`.
 ///
@@ -75,12 +77,12 @@ impl<T: Future> Future for CpuRateLimiter<T> {
             return Poll::Pending;
         }
 
-        let before_polling = crate::Instant::now();
+        let before_polling = Instant::now();
 
         match this.inner.poll(cx) {
             Poll::Ready(value) => Poll::Ready(value),
             Poll::Pending => {
-                let after_polling = crate::Instant::now();
+                let after_polling = Instant::now();
 
                 // Time it took to execute `poll`.
                 let poll_duration = after_polling - before_polling;
diff --git a/wasm-node/rust/src/lib.rs b/wasm-node/rust/src/lib.rs
index 73d762618f..37c25185a3 100644
--- a/wasm-node/rust/src/lib.rs
+++ b/wasm-node/rust/src/lib.rs
@@ -20,15 +20,7 @@
 #![deny(rustdoc::broken_intra_doc_links)]
 #![deny(unused_crate_dependencies)]
 
-use core::{
-    cmp::Ordering,
-    num::NonZeroU32,
-    ops::{Add, Sub},
-    pin::Pin,
-    str,
-    sync::atomic,
-    time::Duration,
-};
+use core::{num::NonZeroU32, pin::Pin, str, sync::atomic, time::Duration};
 use futures_util::{stream, FutureExt as _, Stream as _, StreamExt as _};
 use smoldot_light::HandleRpcError;
 use std::{
@@ -54,77 +46,6 @@ fn start_timer_wrap(duration: Duration, closure: impl FnOnce() + 'static) {
     unsafe { bindings::start_timer(timer_id, duration.as_secs_f64() * 1000.0) }
 }
 
-#[derive(Debug, Copy, Clone)]
-pub struct Instant {
-    /// Milliseconds.
-    inner: f64,
-}
-
-impl PartialEq for Instant {
-    fn eq(&self, other: &Instant) -> bool {
-        debug_assert!(self.inner.is_finite());
-        self.inner == other.inner
-    }
-}
-
-// This trait is ok to implement because `self.inner` is always finite.
-impl Eq for Instant {}
-
-impl PartialOrd for Instant {
-    fn partial_cmp(&self, other: &Instant) -> Option<Ordering> {
-        self.inner.partial_cmp(&other.inner)
-    }
-}
-
-impl Ord for Instant {
-    fn cmp(&self, other: &Self) -> Ordering {
-        debug_assert!(self.inner.is_finite());
-        self.inner.partial_cmp(&other.inner).unwrap()
-    }
-}
-
-impl Instant {
-    pub fn now() -> Instant {
-        let value = unsafe { bindings::monotonic_clock_ms() };
-        debug_assert!(value.is_finite());
-        Instant { inner: value }
-    }
-}
-
-impl Add<Duration> for Instant {
-    type Output = Instant;
-
-    fn add(self, other: Duration) -> Instant {
-        let new_val = self.inner + other.as_millis() as f64;
-        // Just like the `Add` implementation of the actual `Instant`, we panic if the value can't
-        // be represented.
-        assert!(new_val.is_finite());
-        Instant { inner: new_val }
-    }
-}
-
-impl Sub<Duration> for Instant {
-    type Output = Instant;
-
-    fn sub(self, other: Duration) -> Instant {
-        let new_val = self.inner - other.as_millis() as f64;
-        // Just like the `Sub` implementation of the actual `Instant`, we panic if the value can't
-        // be represented.
-        assert!(new_val.is_finite());
-        Instant { inner: new_val }
-    }
-}
-
-impl Sub<Instant> for Instant {
-    type Output = Duration;
-
-    fn sub(self, other: Instant) -> Duration {
-        let ms = self.inner - other.inner;
-        assert!(ms >= 0.0);
-        Duration::from_millis(ms as u64)
-    }
-}
-
 static CLIENT: Mutex<Option<init::Client<platform::Platform, ()>>> = Mutex::new(None);
 
 fn init(
diff --git a/wasm-node/rust/src/platform.rs b/wasm-node/rust/src/platform.rs
index 3ef35d8577..eaa97b7d63 100644
--- a/wasm-node/rust/src/platform.rs
+++ b/wasm-node/rust/src/platform.rs
@@ -30,6 +30,7 @@ use std::{
         atomic::{AtomicU64, Ordering},
         Mutex,
     },
+    time::{Instant, SystemTime, UNIX_EPOCH},
 };
 
 /// Total number of bytes that all the connections created through [`Platform`] combined have
@@ -57,7 +58,7 @@ impl Platform {
 impl smoldot_light::platform::PlatformRef for Platform {
     type Delay = Delay;
     type Yield = Yield;
-    type Instant = crate::Instant;
+    type Instant = Instant;
     type Connection = ConnectionWrapper; // Entry in the ̀`CONNECTIONS` map.
     type Stream = StreamWrapper; // Entry in the ̀`STREAMS` map and a read buffer.
     type ConnectFuture = future::BoxFuture<
@@ -77,19 +78,15 @@ impl smoldot_light::platform::PlatformRef for Platform {
     >;
 
     fn now_from_unix_epoch(&self) -> Duration {
-        let value = unsafe { bindings::unix_time_ms() };
-        debug_assert!(value.is_finite());
         // The documentation of `now_from_unix_epoch()` mentions that it's ok to panic if we're
         // before the UNIX epoch.
-        assert!(
-            value >= 0.0,
-            "running before the UNIX epoch isn't supported"
-        );
-        Duration::from_secs_f64(value / 1000.0)
+        SystemTime::now()
+            .duration_since(UNIX_EPOCH)
+            .unwrap_or_else(|_| panic!())
     }
 
     fn now(&self) -> Self::Instant {
-        crate::Instant::now()
+        Instant::now()
     }
 
     fn sleep(&self, duration: Duration) -> Self::Delay {
diff --git a/wasm-node/rust/src/timers.rs b/wasm-node/rust/src/timers.rs
index 3584d83168..f13587a03c 100644
--- a/wasm-node/rust/src/timers.rs
+++ b/wasm-node/rust/src/timers.rs
@@ -30,7 +30,7 @@ use core::{
     time::Duration,
 };
 use futures_util::future;
-use std::{collections::BinaryHeap, sync::Mutex};
+use std::{collections::BinaryHeap, sync::Mutex, time::Instant};
 
 pub(crate) fn timer_finished(timer_id: u32) {
     let callback = {
@@ -41,8 +41,6 @@ pub(crate) fn timer_finished(timer_id: u32) {
     callback();
 }
 
-use super::Instant;
-
 /// `Future` that automatically wakes up after a certain amount of time has elapsed.
 pub struct Delay {
     /// Index in `TIMERS::timers`. Guaranteed to have `is_obsolete` equal to `false`.

From b53068c67e9ea7bd4bca4eb1f6178ccc17f66247 Mon Sep 17 00:00:00 2001
From: Pierre Krieger <pierre.krieger1708@gmail.com>
Date: Wed, 26 Apr 2023 14:36:19 +0200
Subject: [PATCH 2/7] Docfix

---
 wasm-node/rust/src/bindings.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/wasm-node/rust/src/bindings.rs b/wasm-node/rust/src/bindings.rs
index 030e5a323a..3acb75ecf7 100644
--- a/wasm-node/rust/src/bindings.rs
+++ b/wasm-node/rust/src/bindings.rs
@@ -137,8 +137,8 @@ extern "C" {
     /// have passed, and this will likely cause smoldot to restart a new timer for the remainder
     /// of the duration.
     ///
-    /// When [`timer_finished`] is called, the value of [`monotonic_clock_ms`] must have increased
-    /// by at least the given number of `milliseconds`.
+    /// When [`timer_finished`] is called, the value of the monotonic clock (in the WASI bindings)
+    /// must have increased by at least the given number of `milliseconds`.
     ///
     /// If `milliseconds` is 0, [`timer_finished`] should be called as soon as possible.
     ///

From 1e7fb2918751830af4e939490fd1e587179a33d2 Mon Sep 17 00:00:00 2001
From: Pierre Krieger <pierre.krieger1708@gmail.com>
Date: Wed, 26 Apr 2023 14:36:22 +0200
Subject: [PATCH 3/7] Minor change

---
 wasm-node/javascript/src/instance/bindings-wasi.ts | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/wasm-node/javascript/src/instance/bindings-wasi.ts b/wasm-node/javascript/src/instance/bindings-wasi.ts
index 01540b8872..0111b8bae3 100644
--- a/wasm-node/javascript/src/instance/bindings-wasi.ts
+++ b/wasm-node/javascript/src/instance/bindings-wasi.ts
@@ -102,8 +102,9 @@ export default (config: Config): WebAssembly.ModuleImports => {
                 case 1: {
                     // Monotonic clock.
                     const nowMs = config.performanceNow();
-                    const now = BigInt(Math.floor(nowMs)) * BigInt(1_000_000) +
-                        BigInt(Math.floor(((nowMs - Math.floor(nowMs)) * 1_000_000)));
+                    const nowMsInt = Math.floor(nowMs);
+                    const now = BigInt(nowMsInt) * BigInt(1_000_000) +
+                        BigInt(Math.floor(((nowMs - nowMsInt) * 1_000_000)));
                     buffer.writeUInt64LE(mem, outPtr, now)
 
                     // Success.

From acd73312050cab3f77c9d2291492f8ae2951dc08 Mon Sep 17 00:00:00 2001
From: Pierre Krieger <pierre.krieger1708@gmail.com>
Date: Wed, 26 Apr 2023 14:37:25 +0200
Subject: [PATCH 4/7] Not sure Date.now() is an integer

---
 wasm-node/javascript/src/instance/bindings-wasi.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/wasm-node/javascript/src/instance/bindings-wasi.ts b/wasm-node/javascript/src/instance/bindings-wasi.ts
index 0111b8bae3..b2c7de5fe6 100644
--- a/wasm-node/javascript/src/instance/bindings-wasi.ts
+++ b/wasm-node/javascript/src/instance/bindings-wasi.ts
@@ -93,7 +93,7 @@ export default (config: Config): WebAssembly.ModuleImports => {
             switch (clockId) {
                 case 0: {
                     // Realtime clock.
-                    const now = BigInt(Date.now()) * BigInt(1_000_000);
+                    const now = BigInt(Math.floor(Date.now())) * BigInt(1_000_000);
                     buffer.writeUInt64LE(mem, outPtr, now)
 
                     // Success.

From 0cbdb4216e32e61a847e57f5af1cadf7498490f7 Mon Sep 17 00:00:00 2001
From: Pierre Krieger <pierre.krieger1708@gmail.com>
Date: Wed, 26 Apr 2023 16:37:41 +0200
Subject: [PATCH 5/7] Remove obsolete comment

---
 wasm-node/rust/src/cpu_rate_limiter.rs | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/wasm-node/rust/src/cpu_rate_limiter.rs b/wasm-node/rust/src/cpu_rate_limiter.rs
index 1799806ec3..16c2ce86e7 100644
--- a/wasm-node/rust/src/cpu_rate_limiter.rs
+++ b/wasm-node/rust/src/cpu_rate_limiter.rs
@@ -90,9 +90,6 @@ impl<T: Future> Future for CpuRateLimiter<T> {
                 // In order to enforce the rate limiting, we prevent `poll` from executing
                 // for a certain amount of time.
                 // The base equation here is: `(after_poll_sleep + poll_duration) * rate_limit == poll_duration * u32::max_value()`.
-                // Because `Duration::mul_f64` and `Duration::from_secs_f64` panic in case of
-                // overflow, we need to do the operation of multiplying and checking the bounds
-                // manually.
                 let after_poll_sleep =
                     poll_duration.as_secs_f64() * *this.max_divided_by_rate_limit_minus_one;
                 debug_assert!(after_poll_sleep >= 0.0 && !after_poll_sleep.is_nan());

From 622b82048be11a5fffd555a3b6a585f3b1fd2de9 Mon Sep 17 00:00:00 2001
From: Pierre Krieger <pierre.krieger1708@gmail.com>
Date: Wed, 26 Apr 2023 18:01:28 +0200
Subject: [PATCH 6/7] Yield less often to the JS engine

---
 wasm-node/CHANGELOG.md                 |  1 +
 wasm-node/rust/src/cpu_rate_limiter.rs | 20 +++++++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/wasm-node/CHANGELOG.md b/wasm-node/CHANGELOG.md
index 51287a0709..f83d2ca701 100644
--- a/wasm-node/CHANGELOG.md
+++ b/wasm-node/CHANGELOG.md
@@ -6,6 +6,7 @@
 
 - As NodeJS v14 reaches its end of life on April 30th 2023, the minimum NodeJS version required to run smoldot is now v16. The smoldot Wasm binary now has SIMD enabled, meaning that the minimum Deno version required to run smoldot is now v1.9.
 - When receiving an identify request through the libp2p protocol, smoldot now sends back `smoldot-light-wasm vX.X.X` (with proper version numbers) as its agent name and version, instead of previously just `smoldot`. ([#417](https://github.com/smol-dot/smoldot/pull/417))
+- Yielding to the browser using `setTimeout` and `setImmediate` is now done less frequently in order to reduce the overhead of doing so. ([#481](https://github.com/smol-dot/smoldot/pull/481))
 
 ### Fixed
 
diff --git a/wasm-node/rust/src/cpu_rate_limiter.rs b/wasm-node/rust/src/cpu_rate_limiter.rs
index 16c2ce86e7..2d37240862 100644
--- a/wasm-node/rust/src/cpu_rate_limiter.rs
+++ b/wasm-node/rust/src/cpu_rate_limiter.rs
@@ -36,6 +36,10 @@ pub struct CpuRateLimiter<T> {
     inner: T,
     max_divided_by_rate_limit_minus_one: f64,
 
+    /// Instead of sleeping regularly for short amounts of time, we instead continue running only
+    /// until the time we have to sleep reaches a certain threshold.
+    sleep_deprevation_sec: f64,
+
     /// Prevent `self.inner.poll` from being called before this `Delay` is ready.
     #[pin]
     prevent_poll_until: crate::timers::Delay,
@@ -57,6 +61,7 @@ impl<T> CpuRateLimiter<T> {
         CpuRateLimiter {
             inner,
             max_divided_by_rate_limit_minus_one,
+            sleep_deprevation_sec: 0.0,
             prevent_poll_until: crate::timers::Delay::new(Duration::new(0, 0)),
         }
     }
@@ -93,11 +98,16 @@ impl<T: Future> Future for CpuRateLimiter<T> {
                 let after_poll_sleep =
                     poll_duration.as_secs_f64() * *this.max_divided_by_rate_limit_minus_one;
                 debug_assert!(after_poll_sleep >= 0.0 && !after_poll_sleep.is_nan());
-
-                this.prevent_poll_until.set(crate::timers::Delay::new_at(
-                    after_polling
-                        + Duration::try_from_secs_f64(after_poll_sleep).unwrap_or(Duration::MAX),
-                ));
+                *this.sleep_deprevation_sec += after_poll_sleep;
+
+                if *this.sleep_deprevation_sec > 5.0 {
+                    this.prevent_poll_until.set(crate::timers::Delay::new_at(
+                        after_polling
+                            + Duration::try_from_secs_f64(*this.sleep_deprevation_sec)
+                                .unwrap_or(Duration::MAX),
+                    ));
+                    *this.sleep_deprevation_sec = 0.0;
+                }
 
                 Poll::Pending
             }

From f2153c49e5e5e2716fdcca64d016dc67ce19e3dd Mon Sep 17 00:00:00 2001
From: Pierre Krieger <pierre.krieger1708@gmail.com>
Date: Wed, 26 Apr 2023 18:01:54 +0200
Subject: [PATCH 7/7] Whoops, it's in seconds and not milliseconds

---
 wasm-node/rust/src/cpu_rate_limiter.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/wasm-node/rust/src/cpu_rate_limiter.rs b/wasm-node/rust/src/cpu_rate_limiter.rs
index 2d37240862..a1256fae7d 100644
--- a/wasm-node/rust/src/cpu_rate_limiter.rs
+++ b/wasm-node/rust/src/cpu_rate_limiter.rs
@@ -100,7 +100,7 @@ impl<T: Future> Future for CpuRateLimiter<T> {
                 debug_assert!(after_poll_sleep >= 0.0 && !after_poll_sleep.is_nan());
                 *this.sleep_deprevation_sec += after_poll_sleep;
 
-                if *this.sleep_deprevation_sec > 5.0 {
+                if *this.sleep_deprevation_sec > 0.005 {
                     this.prevent_poll_until.set(crate::timers::Delay::new_at(
                         after_polling
                             + Duration::try_from_secs_f64(*this.sleep_deprevation_sec)