summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/arti-bench/Cargo.toml1
-rw-r--r--crates/arti-bench/src/main.rs18
-rw-r--r--crates/arti-client/Cargo.toml1
-rw-r--r--crates/arti-client/src/builder.rs11
-rw-r--r--crates/arti-client/src/status.rs9
-rw-r--r--crates/arti/Cargo.toml2
-rw-r--r--crates/arti/src/logging/time.rs8
-rw-r--r--crates/retry-error/Cargo.toml4
-rw-r--r--crates/retry-error/src/lib.rs37
-rw-r--r--crates/tor-basic-utils/Cargo.toml1
-rw-r--r--crates/tor-basic-utils/src/rangebounds.rs4
-rw-r--r--crates/tor-cert-x509/Cargo.toml1
-rw-r--r--crates/tor-cert-x509/src/lib.rs5
-rw-r--r--crates/tor-cert/Cargo.toml1
-rw-r--r--crates/tor-cert/src/encode.rs4
-rw-r--r--crates/tor-cert/src/lib.rs11
-rw-r--r--crates/tor-cert/src/rsa/encode.rs5
-rw-r--r--crates/tor-chanmgr/Cargo.toml1
-rw-r--r--crates/tor-chanmgr/src/event.rs20
-rw-r--r--crates/tor-checkable/Cargo.toml1
-rw-r--r--crates/tor-checkable/src/lib.rs3
-rw-r--r--crates/tor-checkable/src/timed.rs16
-rw-r--r--crates/tor-circmgr/Cargo.toml1
-rw-r--r--crates/tor-circmgr/src/build.rs2
-rw-r--r--crates/tor-circmgr/src/err.rs3
-rw-r--r--crates/tor-circmgr/src/hspool.rs6
-rw-r--r--crates/tor-circmgr/src/hspool/pool.rs2
-rw-r--r--crates/tor-circmgr/src/impls.rs3
-rw-r--r--crates/tor-circmgr/src/lib.rs5
-rw-r--r--crates/tor-circmgr/src/mgr.rs5
-rw-r--r--crates/tor-circmgr/src/mocks.rs3
-rw-r--r--crates/tor-circmgr/src/path/exitpath.rs7
-rw-r--r--crates/tor-circmgr/src/path/hspath.rs7
-rw-r--r--crates/tor-circmgr/src/preemptive.rs14
-rw-r--r--crates/tor-circmgr/src/usage.rs5
-rw-r--r--crates/tor-dirclient/Cargo.toml1
-rw-r--r--crates/tor-dirclient/src/lib.rs3
-rw-r--r--crates/tor-dirclient/src/request.rs3
-rw-r--r--crates/tor-dirmgr/Cargo.toml1
-rw-r--r--crates/tor-dirmgr/src/bootstrap.rs3
-rw-r--r--crates/tor-dirmgr/src/bridgedesc.rs2
-rw-r--r--crates/tor-dirmgr/src/event.rs3
-rw-r--r--crates/tor-dirmgr/src/lib.rs4
-rw-r--r--crates/tor-dirmgr/src/storage/sqlite.rs26
-rw-r--r--crates/tor-error/Cargo.toml3
-rw-r--r--crates/tor-error/src/retriable.rs18
-rw-r--r--crates/tor-guardmgr/Cargo.toml1
-rw-r--r--crates/tor-guardmgr/src/bridge/descs.rs6
-rw-r--r--crates/tor-guardmgr/src/dirstatus.rs5
-rw-r--r--crates/tor-guardmgr/src/err.rs4
-rw-r--r--crates/tor-guardmgr/src/fallback.rs7
-rw-r--r--crates/tor-guardmgr/src/guard.rs39
-rw-r--r--crates/tor-guardmgr/src/lib.rs2
-rw-r--r--crates/tor-guardmgr/src/pending.rs2
-rw-r--r--crates/tor-guardmgr/src/sample.rs51
-rw-r--r--crates/tor-guardmgr/src/skew.rs11
-rw-r--r--crates/tor-guardmgr/src/util.rs3
-rw-r--r--crates/tor-hsclient/Cargo.toml1
-rw-r--r--crates/tor-hsclient/src/connect.rs4
-rw-r--r--crates/tor-hsclient/src/pow/v1.rs4
-rw-r--r--crates/tor-hsclient/src/state.rs2
-rw-r--r--crates/tor-hscrypto/Cargo.toml1
-rw-r--r--crates/tor-hscrypto/src/pk.rs4
-rw-r--r--crates/tor-hscrypto/src/time.rs6
-rw-r--r--crates/tor-hsservice/Cargo.toml1
-rw-r--r--crates/tor-hsservice/src/internal_prelude.rs2
-rw-r--r--crates/tor-hsservice/src/pow/v1.rs10
-rw-r--r--crates/tor-hsservice/src/publish.rs1
-rw-r--r--crates/tor-hsservice/src/publish/reupload_timer.rs4
-rw-r--r--crates/tor-hsservice/src/rend_handshake.rs8
-rw-r--r--crates/tor-hsservice/src/time_store.rs7
-rw-r--r--crates/tor-hsservice/src/timeout_track.rs5
-rw-r--r--crates/tor-keymgr/Cargo.toml1
-rw-r--r--crates/tor-keymgr/src/keystore/arti.rs2
-rw-r--r--crates/tor-keymgr/src/mgr.rs4
-rw-r--r--crates/tor-log-ratelim/Cargo.toml1
-rw-r--r--crates/tor-log-ratelim/src/ratelim.rs2
-rw-r--r--crates/tor-netdir/Cargo.toml1
-rw-r--r--crates/tor-netdir/src/testnet.rs4
-rw-r--r--crates/tor-netdir/src/weight.rs3
-rw-r--r--crates/tor-netdoc/Cargo.toml1
-rw-r--r--crates/tor-netdoc/src/doc/authcert/build.rs5
-rw-r--r--crates/tor-netdoc/src/doc/hsdesc/build.rs3
-rw-r--r--crates/tor-netdoc/src/doc/netstatus/build/each_flavor.rs4
-rw-r--r--crates/tor-persist/Cargo.toml1
-rw-r--r--crates/tor-persist/src/fs.rs8
-rw-r--r--crates/tor-persist/src/fs/clean.rs13
-rw-r--r--crates/tor-persist/src/slug/timestamp.rs2
-rw-r--r--crates/tor-persist/src/state_dir.rs11
-rw-r--r--crates/tor-proto/Cargo.toml1
-rw-r--r--crates/tor-proto/src/channel/handshake.rs8
-rw-r--r--crates/tor-proto/src/channel/padding.rs4
-rw-r--r--crates/tor-proto/src/circuit/circhop.rs2
-rw-r--r--crates/tor-proto/src/client.rs2
-rw-r--r--crates/tor-proto/src/client/channel/handshake.rs2
-rw-r--r--crates/tor-proto/src/client/circuit.rs5
-rw-r--r--crates/tor-proto/src/client/circuit/padding/maybenot_padding.rs2
-rw-r--r--crates/tor-proto/src/client/circuit/padding/maybenot_padding/backend.rs4
-rw-r--r--crates/tor-proto/src/client/reactor/circuit.rs2
-rw-r--r--crates/tor-proto/src/client/reactor/circuit/circhop.rs2
-rw-r--r--crates/tor-proto/src/congestion/rtt.rs6
-rw-r--r--crates/tor-proto/src/congestion/vegas.rs8
-rw-r--r--crates/tor-proto/src/relay/channel/handshake.rs4
-rw-r--r--crates/tor-proto/src/relay/channel/responder.rs5
-rw-r--r--crates/tor-proto/src/streammap.rs5
-rw-r--r--crates/tor-proto/src/util/skew.rs3
-rw-r--r--crates/tor-proto/src/util/token_bucket/bucket.rs2
-rw-r--r--crates/tor-proto/src/util/token_bucket/writer.rs6
-rw-r--r--crates/tor-proto/src/util/tunnel_activity.rs9
-rw-r--r--crates/tor-ptmgr/Cargo.toml1
-rw-r--r--crates/tor-ptmgr/src/ipc.rs8
-rw-r--r--crates/tor-relay-crypto/Cargo.toml1
-rw-r--r--crates/tor-relay-crypto/src/certs.rs7
-rw-r--r--crates/tor-relay-crypto/src/pk.rs2
-rw-r--r--crates/tor-rtcompat/Cargo.toml1
-rw-r--r--crates/tor-rtcompat/src/compound.rs2
-rw-r--r--crates/tor-rtcompat/src/dyn_time.rs2
-rw-r--r--crates/tor-rtcompat/src/lib.rs12
-rw-r--r--crates/tor-rtcompat/src/scheduler.rs10
-rw-r--r--crates/tor-rtcompat/src/timer.rs5
-rw-r--r--crates/tor-rtcompat/src/traits.rs6
-rw-r--r--crates/tor-rtmock/Cargo.toml1
-rw-r--r--crates/tor-rtmock/src/simple_time.rs8
-rw-r--r--crates/tor-rtmock/src/sleep_runtime.rs2
-rw-r--r--crates/tor-rtmock/src/time.rs13
-rw-r--r--crates/tor-rtmock/src/time_core.rs2
-rw-r--r--crates/tor-rtmock/src/util.rs2
-rw-r--r--crates/tor-rtmock/tests/rtcompat_timing.rs4
-rw-r--r--crates/web-time-compat/Cargo.toml26
-rw-r--r--crates/web-time-compat/README.md37
-rw-r--r--crates/web-time-compat/src/lib.rs112
-rw-r--r--crates/web-time-compat/src/stdlib.rs21
-rw-r--r--crates/web-time-compat/src/wasm.rs20
133 files changed, 626 insertions, 312 deletions
diff --git a/crates/arti-bench/Cargo.toml b/crates/arti-bench/Cargo.toml
index 370a0b773..1fb43d641 100644
--- a/crates/arti-bench/Cargo.toml
+++ b/crates/arti-bench/Cargo.toml
@@ -32,6 +32,7 @@ tor-config = { path = "../tor-config", version = "0.40.0" }
tor-rtcompat = { path = "../tor-rtcompat", version = "0.40.0", features = ["tokio", "native-tls"] }
tracing = "0.1.36"
tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
[features]
full = [
diff --git a/crates/arti-bench/src/main.rs b/crates/arti-bench/src/main.rs
index d76c36a4f..1ee55dab7 100644
--- a/crates/arti-bench/src/main.rs
+++ b/crates/arti-bench/src/main.rs
@@ -71,12 +71,12 @@ use std::ops::Deref;
use std::str::FromStr;
use std::sync::Arc;
use std::thread::JoinHandle;
-use std::time::SystemTime;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
use tokio_socks::tcp::Socks5Stream;
use tor_config::{ConfigurationSource, ConfigurationSources};
use tor_rtcompat::ToplevelRuntime;
use tracing::info;
+use web_time_compat::{SystemTime, SystemTimeExt};
/// Generate a random payload of bytes of the given size
fn random_payload(size: usize) -> Vec<u8> {
@@ -181,18 +181,18 @@ fn run_timing(mut stream: TcpStream, send: &Arc<[u8]>, receive: &Arc<[u8]>) -> R
let mut total_read = 0;
info!("Accepted connection from {}", peer_addr);
- let accepted_ts = SystemTime::now();
+ let accepted_ts = SystemTime::get();
let mut data: &[u8] = send.deref();
let copied = std::io::copy(&mut data, &mut stream)?;
stream.flush()?;
- let copied_ts = SystemTime::now();
+ let copied_ts = SystemTime::get();
assert_eq!(copied, send.len() as u64);
info!("Copied {} bytes payload to {}.", copied, peer_addr);
let read = stream.read(&mut received)?;
if read == 0 {
panic!("unexpected EOF");
}
- let first_byte_ts = SystemTime::now();
+ let first_byte_ts = SystemTime::get();
if received[0..read] != expected[0..read] {
mismatch = true;
}
@@ -209,7 +209,7 @@ fn run_timing(mut stream: TcpStream, send: &Arc<[u8]>, receive: &Arc<[u8]>) -> R
expected = &expected[read..];
total_read += read;
}
- let read_done_ts = SystemTime::now();
+ let read_done_ts = SystemTime::get();
info!("Received {} bytes payload from {}.", total_read, peer_addr);
// Check we actually got what we thought we would get.
if mismatch {
@@ -252,22 +252,22 @@ async fn client<S: AsyncRead + AsyncWrite + Unpin>(
) -> Result<ClientTiming> {
// Do this potentially costly allocation before we do all the timing stuff.
let mut received = vec![0_u8; receive.len()];
- let started_ts = SystemTime::now();
+ let started_ts = SystemTime::get();
let read = socket.read(&mut received).await?;
if read == 0 {
return Err(anyhow!("unexpected EOF"));
}
- let first_byte_ts = SystemTime::now();
+ let first_byte_ts = SystemTime::get();
socket.read_exact(&mut received[read..]).await?;
- let read_done_ts = SystemTime::now();
+ let read_done_ts = SystemTime::get();
info!("Received {} bytes payload.", received.len());
let mut send_data = &send as &[u8];
tokio::io::copy(&mut send_data, &mut socket).await?;
socket.flush().await?;
info!("Sent {} bytes payload.", send.len());
- let copied_ts = SystemTime::now();
+ let copied_ts = SystemTime::get();
// Check we actually got what we thought we would get.
if received != receive.deref() {
diff --git a/crates/arti-client/Cargo.toml b/crates/arti-client/Cargo.toml
index 69a14e72c..6c2235473 100644
--- a/crates/arti-client/Cargo.toml
+++ b/crates/arti-client/Cargo.toml
@@ -215,6 +215,7 @@ tor-rtcompat = { path = "../tor-rtcompat", version = "0.40.0" }
tracing = "0.1.36"
visibility = { version = "0.1.0", optional = true }
void = "1"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
# TODO wasm: Remove this once there is a supported wasm StateMgr.
[target.'cfg(all(target_arch="wasm32", target_os="unknown"))'.dependencies]
diff --git a/crates/arti-client/src/builder.rs b/crates/arti-client/src/builder.rs
index 0fea83741..2520658d3 100644
--- a/crates/arti-client/src/builder.rs
+++ b/crates/arti-client/src/builder.rs
@@ -5,15 +5,12 @@
use crate::{
BootstrapBehavior, InertTorClient, Result, TorClient, TorClientConfig, err::ErrorDetail,
};
-use std::{
- result::Result as StdResult,
- sync::Arc,
- time::{Duration, Instant},
-};
+use std::{result::Result as StdResult, sync::Arc};
use tor_dirmgr::{DirMgrConfig, DirMgrStore};
use tor_error::{ErrorKind, HasKind as _};
use tor_rtcompat::Runtime;
use tracing::instrument;
+use web_time_compat::{Duration, Instant, InstantExt};
/// An object that knows how to construct some kind of DirProvider.
///
@@ -187,11 +184,11 @@ impl<R: Runtime> TorClientBuilder<R> {
#[instrument(skip_all, level = "trace")]
pub fn create_unbootstrapped(&self) -> Result<TorClient<R>> {
let timeout = self.local_resource_timeout_or(Duration::from_millis(0))?;
- let give_up_at = Instant::now() + timeout;
+ let give_up_at = Instant::get() + timeout;
let mut first_attempt = true;
loop {
- match self.create_unbootstrapped_inner(Instant::now, give_up_at, first_attempt) {
+ match self.create_unbootstrapped_inner(Instant::get, give_up_at, first_attempt) {
Err(delay) => {
first_attempt = false;
std::thread::sleep(delay);
diff --git a/crates/arti-client/src/status.rs b/crates/arti-client/src/status.rs
index 36e12ce51..2fb131a1b 100644
--- a/crates/arti-client/src/status.rs
+++ b/crates/arti-client/src/status.rs
@@ -1,7 +1,7 @@
//! Code to collect and publish information about a client's bootstrapping
//! status.
-use std::{borrow::Cow, fmt, fmt::Display, time::SystemTime};
+use std::{borrow::Cow, fmt, fmt::Display};
use educe::Educe;
use futures::{Stream, StreamExt};
@@ -10,6 +10,7 @@ use tor_chanmgr::{ConnBlockage, ConnStatus, ConnStatusEvents};
use tor_circmgr::{ClockSkewEvents, SkewEstimate};
use tor_dirmgr::{DirBlockage, DirBootstrapStatus};
use tracing::debug;
+use web_time_compat::{SystemTime, SystemTimeExt};
/// Information about how ready a [`crate::TorClient`] is to handle requests.
///
@@ -40,7 +41,7 @@ impl BootstrapStatus {
/// 0 is defined as "just started"; 1 is defined as "ready to use."
pub fn as_frac(&self) -> f32 {
// Coefficients chosen arbitrarily.
- self.conn_status.frac() * 0.15 + self.dir_status.frac_at(SystemTime::now()) * 0.85
+ self.conn_status.frac() * 0.15 + self.dir_status.frac_at(SystemTime::get()) * 0.85
}
/// Return true if the status indicates that the client is ready for
@@ -49,7 +50,7 @@ impl BootstrapStatus {
/// For the purposes of this function, the client is "ready for traffic" if,
/// as far as we know, we can start acting on a new client request immediately.
pub fn ready_for_traffic(&self) -> bool {
- let now = SystemTime::now();
+ let now = SystemTime::get();
self.conn_status.usable() && self.dir_status.usable_at(now)
}
@@ -84,7 +85,7 @@ impl BootstrapStatus {
} else {
Some(Blockage { kind, message })
}
- } else if let Some(b) = self.dir_status.blockage(SystemTime::now()) {
+ } else if let Some(b) = self.dir_status.blockage(SystemTime::get()) {
let message = b.to_string().into();
let kind = b.into();
Some(Blockage { kind, message })
diff --git a/crates/arti/Cargo.toml b/crates/arti/Cargo.toml
index 3a92b56f1..e61404b82 100644
--- a/crates/arti/Cargo.toml
+++ b/crates/arti/Cargo.toml
@@ -225,10 +225,10 @@ tor-socksproto = { path = "../tor-socksproto", version = "0.40.0" }
tracing = "0.1.36"
tracing-appender = "0.2.0"
tracing-journald = { version = "0.3.0", optional = true }
-
tracing-opentelemetry = { version = "0.32.0", optional = true }
tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
visibility = { version = "0.1.0", optional = true }
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.8", features = ["winerror"] }
diff --git a/crates/arti/src/logging/time.rs b/crates/arti/src/logging/time.rs
index b2e0ec532..24563c533 100644
--- a/crates/arti/src/logging/time.rs
+++ b/crates/arti/src/logging/time.rs
@@ -7,6 +7,7 @@
use std::num::NonZeroU8;
use time::format_description;
+use web_time_compat::{SystemTime, SystemTimeExt};
/// Construct a new [`FormatTime`](tracing_subscriber::fmt::time::FormatTime)
/// from a given user-supplied description of the desired log granularity.
@@ -215,11 +216,8 @@ impl LogTimer {
impl tracing_subscriber::fmt::time::FormatTime for LogTimer {
fn format_time(&self, w: &mut tracing_subscriber::fmt::format::Writer<'_>) -> std::fmt::Result {
// See NOTE above: This function mustn't panic.
- w.write_str(
- &self
- .time_to_string(time::OffsetDateTime::now_utc())
- .map_err(|_| std::fmt::Error)?,
- )
+ let now_utc: time::OffsetDateTime = SystemTime::get().into();
+ w.write_str(&self.time_to_string(now_utc).map_err(|_| std::fmt::Error)?)
}
}
diff --git a/crates/retry-error/Cargo.toml b/crates/retry-error/Cargo.toml
index f4fc34493..5e439a25f 100644
--- a/crates/retry-error/Cargo.toml
+++ b/crates/retry-error/Cargo.toml
@@ -22,5 +22,9 @@ humantime = "2"
[features]
full = []
+
[package.metadata.docs.rs]
all-features = true
+
+[target.'cfg(all(target_arch="wasm32", target_os="unknown"))'.dependencies]
+web-time = "1.1.0"
diff --git a/crates/retry-error/src/lib.rs b/crates/retry-error/src/lib.rs
index 5d00eb4aa..2ca7a9893 100644
--- a/crates/retry-error/src/lib.rs
+++ b/crates/retry-error/src/lib.rs
@@ -49,7 +49,13 @@
use std::error::Error;
use std::fmt::{self, Debug, Display, Error as FmtError, Formatter};
use std::iter;
-use std::time::{Duration, Instant, SystemTime};
+use std::time::{Duration, SystemTime};
+
+#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
+use web_time::Instant;
+
+#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
+use std::time::Instant;
/// An error type for use when we're going to do something a few times,
/// and they might all fail.
@@ -135,6 +141,7 @@ impl<E> RetryError<E> {
///
/// # Example
/// ```
+ /// # #![allow(clippy::disallowed_methods)]
/// # use retry_error::RetryError;
/// # use std::time::{Instant, SystemTime};
/// let mut retry_err: RetryError<&str> = RetryError::in_attempt_to("connect");
@@ -169,7 +176,7 @@ impl<E> RetryError<E> {
where
T: Into<E>,
{
- self.push_timed(err, Instant::now(), Some(SystemTime::now()));
+ self.push_timed(err, current_instant(), Some(current_system_time()));
}
/// Return an iterator over all of the reasons that the attempt
@@ -515,6 +522,32 @@ pub fn fmt_error_with_sources(mut e: &dyn Error, f: &mut fmt::Formatter) -> fmt:
Ok(())
}
+/// Return the current system time.
+///
+/// (This is a separate method for compatibility with wasm32.)
+#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
+fn current_system_time() -> SystemTime {
+ use web_time::web::SystemTimeExt as _;
+ web_time::SystemTime::now().to_std()
+}
+
+/// Return the current system time.
+///
+/// (This is a separate method for compatibility with wasm32.)
+#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
+fn current_system_time() -> SystemTime {
+ #![allow(clippy::disallowed_methods)]
+ SystemTime::now()
+}
+
+/// Return the current Instant.
+///
+/// (This is a separate method for compatibility with wasm32.)
+fn current_instant() -> Instant {
+ #![allow(clippy::disallowed_methods)]
+ Instant::now()
+}
+
#[cfg(test)]
mod test {
// @@ begin test lint list maintained by maint/add_warning @@
diff --git a/crates/tor-basic-utils/Cargo.toml b/crates/tor-basic-utils/Cargo.toml
index 783a38bd5..ade411c07 100644
--- a/crates/tor-basic-utils/Cargo.toml
+++ b/crates/tor-basic-utils/Cargo.toml
@@ -24,6 +24,7 @@ slab = "0.4.7"
smallvec = "1.10"
thiserror = "2"
weak-table = "0.3.0"
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
[dev-dependencies]
derive_more = { version = "2.0.1", features = ["full"] }
diff --git a/crates/tor-basic-utils/src/rangebounds.rs b/crates/tor-basic-utils/src/rangebounds.rs
index 14c8f9c75..77a353484 100644
--- a/crates/tor-basic-utils/src/rangebounds.rs
+++ b/crates/tor-basic-utils/src/rangebounds.rs
@@ -114,7 +114,7 @@ mod test {
use super::*;
use Bound::{Excluded as Excl, Included as Incl, Unbounded};
use std::fmt::Debug;
- use std::time::{Duration, SystemTime};
+ use web_time_compat::{Duration, SystemTime, SystemTimeExt};
/// A helper that computes the intersection of `range1` and `range2`.
///
@@ -247,7 +247,7 @@ mod test {
// [t1, t2]: [.......]
// [t3, t4]: [.......]
// intersection: [...]
- let now = SystemTime::now();
+ let now = SystemTime::get();
let t1 = now;
let t2 = now + 2 * MIN;
diff --git a/crates/tor-cert-x509/Cargo.toml b/crates/tor-cert-x509/Cargo.toml
index 3ab1499bd..97c680c99 100644
--- a/crates/tor-cert-x509/Cargo.toml
+++ b/crates/tor-cert-x509/Cargo.toml
@@ -34,3 +34,4 @@ x509-cert = { version = "0.2.5", features = ["builder", "hazmat"] }
[dev-dependencies]
tor-basic-utils = { path = "../tor-basic-utils", version = "0.40.0" }
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
diff --git a/crates/tor-cert-x509/src/lib.rs b/crates/tor-cert-x509/src/lib.rs
index 1e231d7e2..182676573 100644
--- a/crates/tor-cert-x509/src/lib.rs
+++ b/crates/tor-cert-x509/src/lib.rs
@@ -411,6 +411,7 @@ mod test {
use super::*;
use tor_basic_utils::test_rng::testing_rng;
+ use web_time_compat::SystemTimeExt;
#[test]
fn identity_cert_generation() {
@@ -418,7 +419,7 @@ mod test {
let keypair = RsaKeypair::generate(&mut rng).unwrap();
let cert = create_legacy_rsa_id_cert(
&mut rng,
- SystemTime::now(),
+ SystemTime::get(),
"www.house-of-pancakes.example.com",
&keypair,
)
@@ -438,7 +439,7 @@ mod test {
let mut rng = testing_rng();
let certified = TlsKeyAndCert::create(
&mut rng,
- SystemTime::now(),
+ SystemTime::get(),
"foo.example.com",
"bar.example.com",
)
diff --git a/crates/tor-cert/Cargo.toml b/crates/tor-cert/Cargo.toml
index b4e92cb0c..26fa6c909 100644
--- a/crates/tor-cert/Cargo.toml
+++ b/crates/tor-cert/Cargo.toml
@@ -49,6 +49,7 @@ tor-cert-x509 = { path = "../tor-cert-x509", version = "0.40.0", optional = true
tor-checkable = { path = "../tor-checkable", version = "0.40.0" }
tor-error = { path = "../tor-error", version = "0.40.0" }
tor-llcrypto = { path = "../tor-llcrypto", version = "0.40.0" }
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
base64ct = "1.5.1"
diff --git a/crates/tor-cert/src/encode.rs b/crates/tor-cert/src/encode.rs
index de05a8122..ebf7394bb 100644
--- a/crates/tor-cert/src/encode.rs
+++ b/crates/tor-cert/src/encode.rs
@@ -220,14 +220,14 @@ mod test {
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use super::*;
use crate::CertifiedKey;
- use std::time::Duration;
use tor_checkable::{SelfSigned, Timebound};
+ use web_time_compat::{Duration, SystemTimeExt};
#[test]
fn signed_cert_without_key() {
let mut rng = rand::rng();
let keypair = ed25519::Keypair::generate(&mut rng);
- let now = SystemTime::now();
+ let now = SystemTime::get();
let day = Duration::from_secs(86400);
let encoded = Ed25519Cert::constructor()
.expiration(now + day * 30)
diff --git a/crates/tor-cert/src/lib.rs b/crates/tor-cert/src/lib.rs
index 69638af59..07c2f2643 100644
--- a/crates/tor-cert/src/lib.rs
+++ b/crates/tor-cert/src/lib.rs
@@ -57,7 +57,7 @@ use tor_bytes::{Error as BytesError, Result as BytesResult};
use tor_bytes::{Readable, Reader};
use tor_llcrypto::pk::*;
-use std::time;
+use web_time_compat as time;
pub use err::CertError;
@@ -625,7 +625,7 @@ struct ExpiryHours(u32);
/// The number of seconds in an hour.
const SEC_PER_HOUR: u64 = 3600;
-impl From<ExpiryHours> for std::time::SystemTime {
+impl From<ExpiryHours> for time::SystemTime {
fn from(value: ExpiryHours) -> Self {
// TODO MSRV 1.91; use from_hours.
let d = std::time::Duration::from_secs(u64::from(value.0) * SEC_PER_HOUR);
@@ -636,9 +636,9 @@ impl From<ExpiryHours> for std::time::SystemTime {
#[cfg(feature = "encode")]
impl ExpiryHours {
/// Return the earliest possible `ExpiryHours` that is no earlier than `expiry`.
- fn try_from_systemtime_ceil(expiry: std::time::SystemTime) -> Result<Self, CertEncodeError> {
+ fn try_from_systemtime_ceil(expiry: time::SystemTime) -> Result<Self, CertEncodeError> {
let d = expiry
- .duration_since(std::time::SystemTime::UNIX_EPOCH)
+ .duration_since(time::SystemTime::UNIX_EPOCH)
.map_err(|_| CertEncodeError::InvalidExpiration)?;
let sec_ceil = d.as_secs() + if d.subsec_nanos() > 0 { 1 } else { 0 };
let hours = sec_ceil
@@ -684,6 +684,7 @@ mod test {
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use super::*;
use hex_literal::hex;
+ use web_time_compat::SystemTimeExt;
#[test]
fn parse_unrecognized_ext() -> BytesResult<()> {
@@ -736,7 +737,7 @@ mod test {
fn expiry_hours_ceil() {
use std::time::{Duration, SystemTime};
- let now = SystemTime::now();
+ let now = SystemTime::get();
let mut exp = now + Duration::from_secs(24 * 60 * 60);
for _ in 0..=3600 {
let eh = ExpiryHours::try_from_systemtime_ceil(exp).unwrap();
diff --git a/crates/tor-cert/src/rsa/encode.rs b/crates/tor-cert/src/rsa/encode.rs
index 858146ce0..de09f54c3 100644
--- a/crates/tor-cert/src/rsa/encode.rs
+++ b/crates/tor-cert/src/rsa/encode.rs
@@ -1,6 +1,6 @@
//! RSA cross-cert generation
-use std::time::SystemTime;
+use web_time_compat::SystemTime;
use derive_more::{AsRef, Deref, Into};
use tor_bytes::Writer as _;
@@ -81,6 +81,7 @@ mod test {
use tor_basic_utils::test_rng::testing_rng;
use tor_checkable::{ExternallySigned, Timebound};
+ use web_time_compat::SystemTimeExt;
use crate::SEC_PER_HOUR;
use crate::rsa::RsaCrosscert;
@@ -95,7 +96,7 @@ mod test {
ed25519::Ed25519Identity::from_base64("dGhhdW1hdHVyZ3kgaXMgc3RvcmVkIGluIHRoZSBvcmI")
.unwrap();
- let now = SystemTime::now();
+ let now = SystemTime::get();
let expiry = now + Duration::from_secs(24 * SEC_PER_HOUR);
let cert = EncodedRsaCrosscert::encode_and_sign(&keypair, &ed_id, expiry).unwrap();
diff --git a/crates/tor-chanmgr/Cargo.toml b/crates/tor-chanmgr/Cargo.toml
index 537fc35b9..544d4d6fb 100644
--- a/crates/tor-chanmgr/Cargo.toml
+++ b/crates/tor-chanmgr/Cargo.toml
@@ -79,6 +79,7 @@ tor-units = { path = "../tor-units", version = "0.40.0" }
tracing = "0.1.36"
url = "2.5.8"
void = "1"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
float_eq = "1.0.0"
diff --git a/crates/tor-chanmgr/src/event.rs b/crates/tor-chanmgr/src/event.rs
index ef5c4428a..9d016aa2f 100644
--- a/crates/tor-chanmgr/src/event.rs
+++ b/crates/tor-chanmgr/src/event.rs
@@ -4,11 +4,9 @@
use educe::Educe;
use futures::{Stream, StreamExt};
use postage::watch;
-use std::{
- fmt,
- time::{Duration, Instant},
-};
+use std::fmt;
use tor_basic_utils::skip_fmt;
+use web_time_compat::{Duration, Instant, InstantExt};
/// The status of our connection to the internet.
#[derive(Default, Debug, Clone)]
@@ -344,12 +342,12 @@ impl ChanMgrEventSender {
/// Note that an attempt to connect has been started.
pub(crate) fn record_attempt(&mut self) {
self.mgr_status.record_attempt();
- self.push_at(Instant::now());
+ self.push_at(Instant::get());
}
/// Note that we've successfully done a TCP handshake with an alleged relay.
pub(crate) fn record_tcp_success(&mut self) {
- let now = Instant::now();
+ let now = Instant::get();
self.mgr_status.record_tcp_success(now);
self.push_at(now);
}
@@ -358,7 +356,7 @@ impl ChanMgrEventSender {
///
/// (Its identity won't be verified till the next step.)
pub(crate) fn record_tls_finished(&mut self) {
- let now = Instant::now();
+ let now = Instant::get();
self.mgr_status.record_tls_finished(now);
self.push_at(now);
}
@@ -366,7 +364,7 @@ impl ChanMgrEventSender {
/// Record that a handshake has succeeded _except for the certificate
/// timeliness check, which may indicate a skewed clock.
pub(crate) fn record_handshake_done_with_skewed_clock(&mut self) {
- let now = Instant::now();
+ let now = Instant::get();
self.mgr_status.record_handshake_done_with_skewed_clock(now);
self.push_at(now);
}
@@ -376,7 +374,7 @@ impl ChanMgrEventSender {
/// (This includes performing the TLS handshake, and verifying that the
/// relay was indeed the one that we wanted to reach.)
pub(crate) fn record_handshake_done(&mut self) {
- let now = Instant::now();
+ let now = Instant::get();
self.mgr_status.record_handshake_done(now);
self.push_at(now);
}
@@ -388,7 +386,7 @@ pub(crate) fn channel() -> (ChanMgrEventSender, ConnStatusEvents) {
let receiver = ConnStatusEvents { inner: receiver };
let sender = ChanMgrEventSender {
last_conn_status: ConnStatus::default(),
- mgr_status: ChanMgrStatus::new_at(Instant::now()),
+ mgr_status: ChanMgrStatus::new_at(Instant::get()),
sender,
};
(sender, receiver)
@@ -485,7 +483,7 @@ mod test {
#[test]
fn derive_status() {
- let start = Instant::now();
+ let start = Instant::get();
let sec = Duration::from_secs(1);
let hour = Duration::from_secs(3600);
diff --git a/crates/tor-checkable/Cargo.toml b/crates/tor-checkable/Cargo.toml
index 6da1fd288..67c3cf1a3 100644
--- a/crates/tor-checkable/Cargo.toml
+++ b/crates/tor-checkable/Cargo.toml
@@ -22,6 +22,7 @@ humantime = "2"
signature = "2"
thiserror = "2"
tor-llcrypto = { path = "../tor-llcrypto", version = "0.40.0" }
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[package.metadata.docs.rs]
all-features = true
[dev-dependencies]
diff --git a/crates/tor-checkable/src/lib.rs b/crates/tor-checkable/src/lib.rs
index 521ff4e70..3efc5dd8c 100644
--- a/crates/tor-checkable/src/lib.rs
+++ b/crates/tor-checkable/src/lib.rs
@@ -48,6 +48,7 @@
use std::time;
use thiserror::Error;
+use web_time_compat::{SystemTime, SystemTimeExt};
pub mod signed;
pub mod timed;
@@ -93,7 +94,7 @@ pub trait Timebound<T>: Sized {
/// Unwrap this Timebound object if it is valid now.
fn check_valid_now(self) -> Result<T, Self::Error> {
- self.check_valid_at(&time::SystemTime::now())
+ self.check_valid_at(&SystemTime::get())
}
/// Unwrap this object if it is valid at the provided time t.
diff --git a/crates/tor-checkable/src/timed.rs b/crates/tor-checkable/src/timed.rs
index 72fd7dfb9..a187212e2 100644
--- a/crates/tor-checkable/src/timed.rs
+++ b/crates/tor-checkable/src/timed.rs
@@ -1,7 +1,7 @@
//! Convenience implementation of a TimeBound object.
use std::ops::{Bound, Deref, RangeBounds};
-use std::time;
+use web_time_compat as time;
/// A TimeBound object that is valid for a specified range of time.
///
@@ -9,10 +9,10 @@ use std::time;
///
///
/// ```
-/// use std::time::{SystemTime, Duration};
+/// use web_time_compat::{SystemTime, SystemTimeExt, Duration};
/// use tor_checkable::{Timebound, TimeValidityError, timed::TimerangeBound};
///
-/// let now = SystemTime::now();
+/// let now = SystemTime::get();
/// let one_hour = Duration::new(3600, 0);
///
/// // This seven is only valid for another hour!
@@ -222,7 +222,7 @@ mod test {
use super::*;
use crate::{TimeValidityError, Timebound};
use humantime::parse_rfc3339;
- use std::time::{Duration, SystemTime};
+ use web_time_compat::{Duration, SystemTime, SystemTimeExt};
#[test]
fn test_bounds() {
@@ -309,7 +309,7 @@ mod test {
assert_eq!(tr.check_valid_at_opt(None), Ok("hello world"));
let tr = TimerangeBound::new("hello world", de..);
assert_eq!(
- tr.check_valid_at_opt(Some(SystemTime::now())),
+ tr.check_valid_at_opt(Some(SystemTime::get())),
Ok("hello world")
);
let tr = TimerangeBound::new("hello world", ..za);
@@ -318,7 +318,7 @@ mod test {
#[test]
fn test_dangerous() {
- let t1 = SystemTime::now();
+ let t1 = SystemTime::get();
let t2 = t1 + Duration::from_secs(60 * 525600);
let tr = TimerangeBound::new("cups of coffee", t1..=t2);
@@ -332,7 +332,7 @@ mod test {
#[test]
fn test_map() {
- let t1 = SystemTime::now();
+ let t1 = SystemTime::get();
let min = Duration::from_secs(60);
let tb = TimerangeBound::new(17_u32, t1..t1 + 5 * min);
@@ -346,7 +346,7 @@ mod test {
#[test]
fn test_as_ref() {
- let t1 = SystemTime::now();
+ let t1 = SystemTime::get();
let min = Duration::from_secs(60);
let tb1: TimerangeBound<String> = TimerangeBound::new("hi".into(), t1..t1 + 5 * min);
diff --git a/crates/tor-circmgr/Cargo.toml b/crates/tor-circmgr/Cargo.toml
index 6b1380a6e..e28361d92 100644
--- a/crates/tor-circmgr/Cargo.toml
+++ b/crates/tor-circmgr/Cargo.toml
@@ -114,6 +114,7 @@ tracing = "0.1.36"
visibility = { version = "0.1.0", optional = true }
void = "1.0"
weak-table = "0.3.0"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
futures-await-test = "0.3.0"
diff --git a/crates/tor-circmgr/src/build.rs b/crates/tor-circmgr/src/build.rs
index 75edc577e..fed6c6555 100644
--- a/crates/tor-circmgr/src/build.rs
+++ b/crates/tor-circmgr/src/build.rs
@@ -10,7 +10,6 @@ use std::sync::{
Arc,
atomic::{AtomicU32, Ordering},
};
-use std::time::{Duration, Instant};
use tor_chanmgr::{ChanMgr, ChanProvenance, ChannelUsage};
use tor_error::into_internal;
use tor_guardmgr::GuardStatus;
@@ -23,6 +22,7 @@ use tor_rtcompat::SpawnExt;
use tor_rtcompat::{Runtime, SleepProviderExt};
use tor_units::Percentage;
use tracing::instrument;
+use web_time_compat::{Duration, Instant};
#[cfg(all(feature = "vanguards", feature = "hs-common"))]
use tor_guardmgr::vanguards::VanguardMgr;
diff --git a/crates/tor-circmgr/src/err.rs b/crates/tor-circmgr/src/err.rs
index 0570284e0..758614f6d 100644
--- a/crates/tor-circmgr/src/err.rs
+++ b/crates/tor-circmgr/src/err.rs
@@ -1,6 +1,6 @@
//! Declare an error type for tor-circmgr
-use std::{sync::Arc, time::Instant};
+use std::sync::Arc;
use futures::task::SpawnError;
use retry_error::RetryError;
@@ -10,6 +10,7 @@ use oneshot_fused_workaround as oneshot;
use tor_error::{Bug, ErrorKind, HasKind, HasRetryTime};
use tor_linkspec::{LoggedChanTarget, OwnedChanTarget};
use tor_proto::circuit::UniqId;
+use web_time_compat::Instant;
use crate::mgr::RestrictionFailed;
diff --git a/crates/tor-circmgr/src/hspool.rs b/crates/tor-circmgr/src/hspool.rs
index 307c92939..a92bb1da7 100644
--- a/crates/tor-circmgr/src/hspool.rs
+++ b/crates/tor-circmgr/src/hspool.rs
@@ -7,7 +7,6 @@ mod pool;
use std::{
ops::Deref,
sync::{Arc, Mutex, Weak},
- time::Duration,
};
use crate::{
@@ -35,6 +34,7 @@ use tor_rtcompat::{
scheduler::{TaskHandle, TaskSchedule},
};
use tracing::{debug, instrument, trace, warn};
+use web_time_compat::{Duration, Instant, SystemTime};
use std::result::Result as StdResult;
@@ -373,12 +373,12 @@ impl<R: Runtime> HsCircPool<R> {
///
/// This provides mockable time for use in error tracking and other
/// time-sensitive operations.
- pub fn now(&self) -> std::time::Instant {
+ pub fn now(&self) -> Instant {
self.0.circmgr.mgr.peek_runtime().now()
}
/// Return the current wall-clock time from the runtime.
- pub fn wallclock(&self) -> std::time::SystemTime {
+ pub fn wallclock(&self) -> SystemTime {
self.0.circmgr.mgr.peek_runtime().wallclock()
}
}
diff --git a/crates/tor-circmgr/src/hspool/pool.rs b/crates/tor-circmgr/src/hspool/pool.rs
index cf078d044..763665dca 100644
--- a/crates/tor-circmgr/src/hspool/pool.rs
+++ b/crates/tor-circmgr/src/hspool/pool.rs
@@ -1,6 +1,6 @@
//! An internal pool object that we use to implement HsCircPool.
-use std::time::{Duration, Instant};
+use web_time_compat::{Duration, Instant};
use crate::{
AbstractTunnel,
diff --git a/crates/tor-circmgr/src/impls.rs b/crates/tor-circmgr/src/impls.rs
index 01a046e8f..8544b1de1 100644
--- a/crates/tor-circmgr/src/impls.rs
+++ b/crates/tor-circmgr/src/impls.rs
@@ -19,6 +19,7 @@ use tor_proto::circuit::UniqId;
use tor_proto::client::circuit::{CircParameters, Path};
use tor_rtcompat::Runtime;
use tracing::instrument;
+use web_time_compat::Instant;
#[async_trait]
impl mgr::AbstractTunnel for tor_proto::ClientTunnel {
@@ -65,7 +66,7 @@ impl mgr::AbstractTunnel for tor_proto::ClientTunnel {
circ.extend(target, params).await
}
- async fn last_known_to_be_used_at(&self) -> tor_proto::Result<Option<std::time::Instant>> {
+ async fn last_known_to_be_used_at(&self) -> tor_proto::Result<Option<Instant>> {
self.disused_since().await
}
}
diff --git a/crates/tor-circmgr/src/lib.rs b/crates/tor-circmgr/src/lib.rs
index 8b0a56524..9aa7c2c3d 100644
--- a/crates/tor-circmgr/src/lib.rs
+++ b/crates/tor-circmgr/src/lib.rs
@@ -67,9 +67,9 @@ use tor_linkspec::IntoOwnedChanTarget;
use futures::StreamExt;
use std::sync::{Arc, Mutex, Weak};
-use std::time::{Duration, Instant};
use tor_rtcompat::SpawnExt;
use tracing::{debug, info, instrument, trace, warn};
+use web_time_compat::{Duration, Instant, InstantExt};
#[cfg(feature = "testing")]
pub use config::test_config::TestConfig;
@@ -574,7 +574,8 @@ impl<B: AbstractTunnelBuilder<R> + 'static, R: Runtime> CircMgrInner<B, R> {
#[cfg(feature = "geoip")] country_code: Option<CountryCode>,
) -> Result<Arc<B::Tunnel>> {
self.expire_circuits().await;
- let time = Instant::now();
+ // TODO #2428: Shouldn't we look at runtime.now() instead?
+ let time = Instant::get();
{
let mut predictive = self.predictor.lock().expect("preemptive lock poisoned");
if ports.is_empty() {
diff --git a/crates/tor-circmgr/src/mgr.rs b/crates/tor-circmgr/src/mgr.rs
index a8a501491..0e024bf0e 100644
--- a/crates/tor-circmgr/src/mgr.rs
+++ b/crates/tor-circmgr/src/mgr.rs
@@ -47,9 +47,9 @@ use std::fmt::Debug;
use std::hash::Hash;
use std::panic::AssertUnwindSafe;
use std::sync::{self, Arc, Weak};
-use std::time::{Duration, Instant};
use tor_rtcompat::SpawnExt;
use tracing::{debug, instrument, trace, warn};
+use web_time_compat::{Duration, Instant};
mod streams;
/// Alias to force use of RandomState, regardless of features enabled in `weak_tables`.
@@ -1879,6 +1879,7 @@ mod test {
use tor_persist::TestingStateMgr;
use tor_rtcompat::SleepProvider;
use tor_rtmock::MockRuntime;
+ use web_time_compat::InstantExt;
#[allow(deprecated)] // TODO #1885
use tor_rtmock::MockSleepRuntime;
@@ -2432,7 +2433,7 @@ mod test {
let (ep_none, ep_web, ep_full) = get_exit_policies();
let fake_circ = FakeCirc { id: FakeId::next() };
let expiration = ExpirationInfo::Unused {
- created: Instant::now(),
+ created: Instant::get(),
};
let mut entry_none = OpenEntry::new(
diff --git a/crates/tor-circmgr/src/mocks.rs b/crates/tor-circmgr/src/mocks.rs
index 274e6969d..776dd2c9b 100644
--- a/crates/tor-circmgr/src/mocks.rs
+++ b/crates/tor-circmgr/src/mocks.rs
@@ -9,6 +9,7 @@ use tor_persist::StateMgr;
use tor_proto::circuit::UniqId;
use tor_proto::client::circuit::{CircParameters, Path};
use tor_rtcompat::Runtime;
+use web_time_compat::Instant;
use async_trait::async_trait;
use std::sync::{self, Arc};
@@ -74,7 +75,7 @@ impl AbstractTunnel for FakeCirc {
todo!()
}
- async fn last_known_to_be_used_at(&self) -> tor_proto::Result<Option<std::time::Instant>> {
+ async fn last_known_to_be_used_at(&self) -> tor_proto::Result<Option<Instant>> {
Ok(None)
}
}
diff --git a/crates/tor-circmgr/src/path/exitpath.rs b/crates/tor-circmgr/src/path/exitpath.rs
index 793496444..63379cf2d 100644
--- a/crates/tor-circmgr/src/path/exitpath.rs
+++ b/crates/tor-circmgr/src/path/exitpath.rs
@@ -219,6 +219,7 @@ mod test {
use tor_persist::TestingStateMgr;
use tor_relay_selection::LowLevelRelayPredicate;
use tor_rtcompat::SleepProvider;
+ use web_time_compat::SystemTimeExt;
impl<'a> MaybeOwnedRelay<'a> {
fn can_share_circuit(
@@ -283,7 +284,7 @@ mod test {
let guards =
tor_guardmgr::GuardMgr::new(rt.clone(), statemgr, &TestConfig::default()).unwrap();
guards.install_test_netdir(&netdir);
- let now = SystemTime::now();
+ let now = SystemTime::get();
for _ in 0..1000 {
let (path, _, _) = ExitPathBuilder::from_target_ports(ports.clone())
@@ -317,7 +318,7 @@ mod test {
let guards =
tor_guardmgr::GuardMgr::new(rt.clone(), statemgr, &TestConfig::default()).unwrap();
guards.install_test_netdir(&netdir);
- let now = SystemTime::now();
+ let now = SystemTime::get();
let config = PathConfig::default();
for _ in 0..1000 {
@@ -372,7 +373,7 @@ mod test {
tor_guardmgr::GuardMgr::new(rt.clone(), statemgr, &TestConfig::default()).unwrap();
guards.install_test_netdir(&netdir);
let config = PathConfig::default();
- let now = SystemTime::now();
+ let now = SystemTime::get();
// With target ports
let outcome = ExitPathBuilder::from_target_ports(vec![TargetPort::ipv4(80)])
diff --git a/crates/tor-circmgr/src/path/hspath.rs b/crates/tor-circmgr/src/path/hspath.rs
index 2adba60d9..4c581fdf7 100644
--- a/crates/tor-circmgr/src/path/hspath.rs
+++ b/crates/tor-circmgr/src/path/hspath.rs
@@ -429,6 +429,7 @@ mod test {
use tor_netdoc::doc::netstatus::RelayWeight;
use tor_netdoc::types::relay_flags::RelayFlag;
use tor_rtmock::MockRuntime;
+ use web_time_compat::SystemTimeExt;
#[cfg(all(feature = "vanguards", feature = "hs-common"))]
use {
@@ -601,7 +602,8 @@ mod test {
let netdir_provider: Arc<dyn NetDirProvider> = netdir_provider;
guards.install_netdir_provider(&netdir_provider).unwrap();
let config = PathConfig::default();
- let now = SystemTime::now();
+ // TODO #2428. (This is just testing, though)
+ let now = SystemTime::get();
let dirinfo = (netdir).into();
HsPathBuilder::new(target.cloned(), stem_kind, circ_kind)
.pick_path_with_vanguards(&mut rng, dirinfo, &guards, &vanguardmgr, &config, now)
@@ -616,7 +618,8 @@ mod test {
) -> Result<TorPath<'a>> {
let mut rng = testing_rng();
let config = PathConfig::default();
- let now = SystemTime::now();
+ // TODO #2428. (This is just testing, though)
+ let now = SystemTime::get();
let dirinfo = (netdir).into();
let guards = tor_guardmgr::GuardMgr::new(
MockRuntime::new(),
diff --git a/crates/tor-circmgr/src/preemptive.rs b/crates/tor-circmgr/src/preemptive.rs
index 589237e68..ff2ee6e67 100644
--- a/crates/tor-circmgr/src/preemptive.rs
+++ b/crates/tor-circmgr/src/preemptive.rs
@@ -3,8 +3,8 @@
use crate::{PathConfig, PreemptiveCircuitConfig, TargetPort, TargetTunnelUsage};
use std::collections::HashMap;
use std::sync::Arc;
-use std::time::Instant;
use tracing::warn;
+use web_time_compat::{Instant, InstantExt};
/// Predicts what circuits might be used in future based on past activity, and suggests
/// circuits to preemptively build as a result.
@@ -25,11 +25,11 @@ impl PreemptiveCircuitPredictor {
let mut usages = HashMap::new();
for port in &config.initial_predicted_ports {
// TODO(nickm) should this be IPv6? Should we have a way to configure IPv6 initial ports?
- usages.insert(Some(TargetPort::ipv4(*port)), Instant::now());
+ usages.insert(Some(TargetPort::ipv4(*port)), Instant::get());
}
// We want to build circuits for resolving DNS, too.
- usages.insert(None, Instant::now());
+ usages.insert(None, Instant::get());
Self {
usages,
@@ -57,7 +57,7 @@ impl PreemptiveCircuitPredictor {
/// Make some predictions for what circuits should be built.
pub(crate) fn predict(&self, path_config: &PathConfig) -> Vec<TargetTunnelUsage> {
let config = self.config();
- let now = Instant::now();
+ let now = Instant::get();
let circs = config.min_exit_circs_for_port;
self.usages
.iter()
@@ -110,7 +110,7 @@ mod test {
PathConfig, PreemptiveCircuitConfig, PreemptiveCircuitPredictor, TargetPort,
TargetTunnelUsage,
};
- use std::time::{Duration, Instant};
+ use web_time_compat::{Duration, Instant, InstantExt};
use crate::isolation::test::{IsolationTokenEq, assert_isoleq};
@@ -175,7 +175,7 @@ mod test {
}]
);
- predictor.note_usage(Some(TargetPort::ipv4(1234)), Instant::now());
+ predictor.note_usage(Some(TargetPort::ipv4(1234)), Instant::get());
let results = predictor.predict(&path_config);
assert_eq!(results.len(), 2);
@@ -206,7 +206,7 @@ mod test {
cfg.set_initial_predicted_ports(vec![]);
cfg.prediction_lifetime(Duration::from_secs(2));
let mut predictor = PreemptiveCircuitPredictor::new(cfg.build().unwrap());
- let now = Instant::now();
+ let now = Instant::get();
let three_seconds_ago = now - Duration::from_secs(2 + 1);
predictor.note_usage(Some(TargetPort::ipv4(2345)), three_seconds_ago);
diff --git a/crates/tor-circmgr/src/usage.rs b/crates/tor-circmgr/src/usage.rs
index a2b24a8b5..5b0666ee9 100644
--- a/crates/tor-circmgr/src/usage.rs
+++ b/crates/tor-circmgr/src/usage.rs
@@ -620,6 +620,7 @@ pub(crate) mod test {
use tor_llcrypto::pk::ed25519::Ed25519Identity;
use tor_netdir::testnet;
use tor_persist::TestingStateMgr;
+ use web_time_compat::SystemTimeExt;
impl IsolationTokenEq for TargetTunnelUsage {
fn isol_eq(&self, other: &Self) -> bool {
@@ -956,7 +957,7 @@ pub(crate) mod test {
tor_guardmgr::GuardMgr::new(rt.clone(), statemgr.clone(), &TestConfig::default())
.unwrap();
guards.install_test_netdir(&netdir);
- let now = SystemTime::now();
+ let now = SystemTime::get();
// Only doing basic tests for now. We'll test the path
// building code a lot more closely in the tests for TorPath
@@ -1071,7 +1072,7 @@ pub(crate) mod test {
tor_guardmgr::GuardMgr::new(rt.clone(), statemgr.clone(), &TestConfig::default())
.unwrap();
guards.install_test_netdir(&netdir);
- let now = SystemTime::now();
+ let now = SystemTime::get();
#[cfg(all(feature = "vanguards", feature = "hs-common"))]
let vanguards =
diff --git a/crates/tor-dirclient/Cargo.toml b/crates/tor-dirclient/Cargo.toml
index f9dae948b..f04f8ac8c 100644
--- a/crates/tor-dirclient/Cargo.toml
+++ b/crates/tor-dirclient/Cargo.toml
@@ -64,6 +64,7 @@ tor-netdoc = { path = "../tor-netdoc", version = "0.40.0" }
tor-proto = { path = "../tor-proto", version = "0.40.0" }
tor-rtcompat = { path = "../tor-rtcompat", version = "0.40.0" }
tracing = "0.1.36"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
futures-await-test = "0.3.0"
diff --git a/crates/tor-dirclient/src/lib.rs b/crates/tor-dirclient/src/lib.rs
index 5939cc2ba..923423a26 100644
--- a/crates/tor-dirclient/src/lib.rs
+++ b/crates/tor-dirclient/src/lib.rs
@@ -593,6 +593,7 @@ mod test {
use tor_rtmock::io::stream_pair;
use tor_rtmock::simple_time::SimpleMockTimeProvider;
+ use web_time_compat::{SystemTime, SystemTimeExt};
use futures_await_test::async_test;
@@ -633,7 +634,7 @@ mod test {
// We don't need to do anything fancy here, since we aren't simulating
// a timeout.
#[allow(deprecated)] // TODO #1885
- let mock_time = SimpleMockTimeProvider::from_wallclock(std::time::SystemTime::now());
+ let mock_time = SimpleMockTimeProvider::from_wallclock(SystemTime::get());
let mut output = Vec::new();
let mut stream = match get_decoder(data, encoding, AnonymizedRequest::Direct) {
diff --git a/crates/tor-dirclient/src/request.rs b/crates/tor-dirclient/src/request.rs
index ab4412a3f..476b86124 100644
--- a/crates/tor-dirclient/src/request.rs
+++ b/crates/tor-dirclient/src/request.rs
@@ -831,6 +831,7 @@ mod test {
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use super::sealed::RequestableInner;
use super::*;
+ use web_time_compat::SystemTimeExt;
#[test]
fn test_md_request() -> Result<()> {
@@ -915,7 +916,7 @@ mod test {
.unwrap();
let d2 = b"blah blah blah 12 blah blah blah";
- let d3 = SystemTime::now();
+ let d3 = SystemTime::get();
let mut req = ConsensusRequest::default();
let when = httpdate::fmt_http_date(d3);
diff --git a/crates/tor-dirmgr/Cargo.toml b/crates/tor-dirmgr/Cargo.toml
index 41ad825d1..e340f2471 100644
--- a/crates/tor-dirmgr/Cargo.toml
+++ b/crates/tor-dirmgr/Cargo.toml
@@ -115,6 +115,7 @@ tor-protover = { path = "../tor-protover", version = "0.40.0", features = ["serd
tor-rtcompat = { path = "../tor-rtcompat", version = "0.40.0" }
tracing = "0.1.36"
void = "1"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[target.'cfg(not(all(target_arch = "wasm32", target_os = "unknown")))'.dependencies]
fslock = "0.2.0"
diff --git a/crates/tor-dirmgr/src/bootstrap.rs b/crates/tor-dirmgr/src/bootstrap.rs
index f6a38332f..68ccfdd68 100644
--- a/crates/tor-dirmgr/src/bootstrap.rs
+++ b/crates/tor-dirmgr/src/bootstrap.rs
@@ -748,10 +748,11 @@ mod test {
use tor_dircommon::retry::DownloadSchedule;
use tor_netdoc::doc::microdesc::MdDigest;
use tor_rtcompat::SleepProvider;
+ use web_time_compat::SystemTimeExt;
#[test]
fn week() {
- let now = SystemTime::now();
+ let now = SystemTime::get();
let one_day = Duration::new(86400, 0);
assert_eq!(no_more_than_a_week_from(now, None), now + one_day * 7);
diff --git a/crates/tor-dirmgr/src/bridgedesc.rs b/crates/tor-dirmgr/src/bridgedesc.rs
index ecce442c6..b866937a5 100644
--- a/crates/tor-dirmgr/src/bridgedesc.rs
+++ b/crates/tor-dirmgr/src/bridgedesc.rs
@@ -7,7 +7,6 @@ use std::fmt::{self, Debug, Display};
use std::num::NonZeroU8;
use std::panic::AssertUnwindSafe;
use std::sync::{Arc, Mutex, MutexGuard, Weak};
-use std::time::{Duration, Instant, SystemTime};
use async_trait::async_trait;
use derive_more::{Deref, DerefMut};
@@ -29,6 +28,7 @@ use tor_guardmgr::bridge::{BridgeConfig, BridgeDesc};
use tor_guardmgr::bridge::{BridgeDescError, BridgeDescEvent, BridgeDescList, BridgeDescProvider};
use tor_netdoc::doc::routerdesc::RouterDesc;
use tor_rtcompat::{Runtime, SpawnExt as _};
+use web_time_compat::{Duration, Instant, SystemTime};
use crate::event::FlagPublisher;
use crate::storage::CachedBridgeDescriptor;
diff --git a/crates/tor-dirmgr/src/event.rs b/crates/tor-dirmgr/src/event.rs
index 5d9a7e94a..0744206b3 100644
--- a/crates/tor-dirmgr/src/event.rs
+++ b/crates/tor-dirmgr/src/event.rs
@@ -839,6 +839,7 @@ mod test {
use float_eq::assert_float_eq;
use futures::stream::StreamExt;
use tor_rtcompat::test_with_all_runtimes;
+ use web_time_compat::SystemTimeExt;
#[test]
fn subscribe_and_publish() {
@@ -965,7 +966,7 @@ mod test {
#[test]
fn dir_status_basics() {
- let now = SystemTime::now();
+ let now = SystemTime::get();
let hour = Duration::new(3600, 0);
let nothing = DirStatus {
diff --git a/crates/tor-dirmgr/src/lib.rs b/crates/tor-dirmgr/src/lib.rs
index bcdd4c9d4..5398dfa85 100644
--- a/crates/tor-dirmgr/src/lib.rs
+++ b/crates/tor-dirmgr/src/lib.rs
@@ -91,6 +91,7 @@ use tor_netdoc::doc::netstatus::ProtoStatuses;
use tor_rtcompat::scheduler::{TaskHandle, TaskSchedule};
use tor_rtcompat::{Runtime, SpawnExt};
use tracing::{debug, info, instrument, trace, warn};
+use web_time_compat::SystemTimeExt;
use std::marker::PhantomData;
use std::sync::atomic::{AtomicBool, Ordering};
@@ -182,7 +183,8 @@ impl<R: Runtime> NetDirProvider for DirMgr<R> {
.extend_lifetime(netdir.lifetime()),
Timeliness::Unchecked => return Ok(netdir),
};
- let now = SystemTime::now();
+ // TODO #2384 -- we have a runtime here; we should use it.
+ let now = SystemTime::get();
if lifetime.valid_after() > now {
Err(NetDirError::DirNotYetValid)
} else if lifetime.valid_until() < now {
diff --git a/crates/tor-dirmgr/src/storage/sqlite.rs b/crates/tor-dirmgr/src/storage/sqlite.rs
index db42e893e..4967ce6bb 100644
--- a/crates/tor-dirmgr/src/storage/sqlite.rs
+++ b/crates/tor-dirmgr/src/storage/sqlite.rs
@@ -17,6 +17,7 @@ use tor_netdoc::doc::microdesc::MdDigest;
use tor_netdoc::doc::netstatus::{ConsensusFlavor, Lifetime};
#[cfg(feature = "routerdesc")]
use tor_netdoc::doc::routerdesc::RdDigest;
+use web_time_compat::SystemTimeExt;
#[cfg(feature = "bridge-client")]
pub(crate) use {crate::storage::CachedBridgeDescriptor, tor_guardmgr::bridge::BridgeConfig};
@@ -610,7 +611,7 @@ impl Store for SqliteStore {
names
};
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
tx.execute(DROP_OLD_EXTDOCS, [])?;
// In theory bad system clocks might generate table rows with times far in the future.
@@ -1166,6 +1167,11 @@ fn cmeta_from_row(row: &rusqlite::Row<'_>) -> Result<ConsensusMeta> {
))
}
+/// Return `SystemTime::get()` as an OffsetDateTime in UTC.
+fn now_utc() -> OffsetDateTime {
+ SystemTime::get().into()
+}
+
/// Set up the tables for the arti cache schema in a sqlite database.
const INSTALL_V0_SCHEMA: &str = "
-- Helps us version the schema. The schema here corresponds to a
@@ -1538,7 +1544,7 @@ pub(crate) mod test {
fn blobs() -> Result<()> {
let (_tmp_dir, mut store) = new_empty()?;
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
let one_week = 1.weeks();
let fname1 = store.save_blob(
@@ -1598,7 +1604,7 @@ pub(crate) mod test {
use tor_netdoc::doc::netstatus;
let (_tmp_dir, mut store) = new_empty()?;
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
let one_hour = 1.hours();
assert_eq!(
@@ -1702,7 +1708,7 @@ pub(crate) mod test {
#[test]
fn authcerts() -> Result<()> {
let (_tmp_dir, mut store) = new_empty()?;
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
let one_hour = 1.hours();
let keyids = AuthCertKeyIds {
@@ -1729,7 +1735,7 @@ pub(crate) mod test {
fn microdescs() -> Result<()> {
let (_tmp_dir, mut store) = new_empty()?;
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
let one_day = 1.days();
let d1 = [5_u8; 32];
@@ -1770,7 +1776,7 @@ pub(crate) mod test {
fn routerdescs() -> Result<()> {
let (_tmp_dir, mut store) = new_empty()?;
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
let one_day = 1.days();
let long_ago: OffsetDateTime = now - one_day * 100;
let recently = now - one_day;
@@ -1843,7 +1849,7 @@ pub(crate) mod test {
*/
assert_eq!(store.blob_dir.read_directory(".")?.count(), 0);
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
let one_week = 1.weeks();
let _fname_good = store.save_blob(
b"Goodbye, dear friends",
@@ -1880,7 +1886,7 @@ pub(crate) mod test {
fn unreferenced_consensus_blob() -> Result<()> {
let (_tmp_dir, mut store) = new_empty()?;
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
let one_week = 1.weeks();
// Make a blob that claims to be a consensus, and which has not yet expired, but which is
@@ -1918,7 +1924,7 @@ pub(crate) mod test {
fn vanished_blob_cleanup() -> Result<()> {
let (_tmp_dir, mut store) = new_empty()?;
- let now = OffsetDateTime::now_utc();
+ let now = now_utc();
let one_week = 1.weeks();
// Make a few blobs.
@@ -1972,7 +1978,7 @@ pub(crate) mod test {
fn protocol_statuses() -> Result<()> {
let (_tmp_dir, mut store) = new_empty()?;
- let now = SystemTime::now();
+ let now = SystemTime::get();
let hour = 1.hours();
let valid_after = now;
diff --git a/crates/tor-error/Cargo.toml b/crates/tor-error/Cargo.toml
index f801dd950..0cf0c73be 100644
--- a/crates/tor-error/Cargo.toml
+++ b/crates/tor-error/Cargo.toml
@@ -32,12 +32,13 @@ derive_more = { version = "2.0.1", features = ["full"] }
futures = { version = "0.3", optional = true }
http = { version = "1.3.1", optional = true }
paste = "1.0.3"
-retry-error = { path = "../retry-error", version = "0.11.0" } # WRONG should be 0.4.3
+retry-error = { path = "../retry-error", version = "0.11.0" } # WRONG should be 0.4.3
static_assertions = { version = "1", optional = true }
strum = { version = "0.28.0", features = ["derive"] }
thiserror = "2"
tracing = { version = "0.1.36", optional = true }
void = "1"
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
[dev-dependencies]
anyhow = "1.0.72"
diff --git a/crates/tor-error/src/retriable.rs b/crates/tor-error/src/retriable.rs
index 87fcbdd32..8f77e1091 100644
--- a/crates/tor-error/src/retriable.rs
+++ b/crates/tor-error/src/retriable.rs
@@ -1,11 +1,9 @@
//! Declare the `RetryTime` enumeration and related code.
use derive_more::{From, Into};
-use std::{
- cmp::Ordering,
- time::{Duration, Instant},
-};
+use std::{cmp::Ordering, time::Duration};
use strum::EnumDiscriminants;
+use web_time_compat::Instant;
/// A description of when an operation may be retried.
///
@@ -87,7 +85,7 @@ pub enum RetryTime {
/// The operation can be retried at some particular time in the future.
///
/// The recipient of this this `RetryTime` variant should wait until the
- /// current time (as returned by `Instant::now` or `SleepProvider::now` as
+ /// current time (as returned by `Instant::get` or `SleepProvider::now` as
/// appropriate) is at least this given instant.
///
/// This case is appropriate for when we have a failure condition caused by
@@ -274,13 +272,15 @@ mod test {
#![allow(clippy::useless_vec)]
#![allow(clippy::needless_pass_by_value)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
+
use super::*;
+ use web_time_compat::InstantExt;
#[test]
fn comparison() {
use RetryTime as RT;
let sec = Duration::from_secs(1);
- let now = Instant::now();
+ let now = Instant::get();
let sorted = vec![
RT::Immediate,
@@ -304,7 +304,7 @@ mod test {
fn abs_comparison() {
use AbsRetryTime as ART;
let sec = Duration::from_secs(1);
- let now = Instant::now();
+ let now = Instant::get();
let sorted = vec![
ART::Immediate,
@@ -324,7 +324,7 @@ mod test {
#[test]
fn earliest_absolute() {
let sec = Duration::from_secs(1);
- let now = Instant::now();
+ let now = Instant::get();
let times = vec![RetryTime::AfterWaiting, RetryTime::Never];
@@ -337,7 +337,7 @@ mod test {
#[test]
fn abs_from_sum() {
- let base = Instant::now();
+ let base = Instant::get();
let delta = Duration::from_secs(1);
assert_eq!(
AbsRetryTime::from_sum(base, delta),
diff --git a/crates/tor-guardmgr/Cargo.toml b/crates/tor-guardmgr/Cargo.toml
index 60468a9ec..097eefaf6 100644
--- a/crates/tor-guardmgr/Cargo.toml
+++ b/crates/tor-guardmgr/Cargo.toml
@@ -96,6 +96,7 @@ tor-rtcompat = { path = "../tor-rtcompat", version = "0.40.0" }
tor-rtmock = { path = "../tor-rtmock", version = "0.40.0", optional = true }
tor-units = { path = "../tor-units", version = "0.40.0" }
tracing = "0.1.36"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
float_eq = "1.0.0"
diff --git a/crates/tor-guardmgr/src/bridge/descs.rs b/crates/tor-guardmgr/src/bridge/descs.rs
index 7eee3cf25..4dd1a0c14 100644
--- a/crates/tor-guardmgr/src/bridge/descs.rs
+++ b/crates/tor-guardmgr/src/bridge/descs.rs
@@ -5,7 +5,6 @@
use std::collections::HashMap;
use std::sync::Arc;
-use std::time::SystemTime;
use crate::{
bridge::BridgeConfig,
@@ -20,6 +19,7 @@ use tor_linkspec::{ChanTarget, HasChanMethod, HasRelayIds, OwnedChanTarget};
use tor_llcrypto::pk::{ed25519::Ed25519Identity, rsa::RsaIdentity};
use tor_netdir::RelayWeight;
use tor_netdoc::doc::routerdesc::RouterDesc;
+use web_time_compat::{SystemTime, SystemTimeExt};
use super::BridgeRelay;
@@ -239,13 +239,13 @@ impl Universe for BridgeSet {
}
}
- fn timestamp(&self) -> std::time::SystemTime {
+ fn timestamp(&self) -> SystemTime {
// We just use the current time as the timestamp of this BridgeSet.
// This makes the guard code treat a BridgeSet as _continuously updated_:
// anything listed in the guard set is treated as listed right up to this
// moment, and anything unlisted is treated as unlisted right up to this
// moment.
- SystemTime::now()
+ SystemTime::get()
}
/// Note that for a BridgeSet, we always treat the current weight as 0 and
diff --git a/crates/tor-guardmgr/src/dirstatus.rs b/crates/tor-guardmgr/src/dirstatus.rs
index 7b3736e40..d3329da93 100644
--- a/crates/tor-guardmgr/src/dirstatus.rs
+++ b/crates/tor-guardmgr/src/dirstatus.rs
@@ -1,7 +1,7 @@
//! Types and code to track the readiness status of a directory cache.
-use std::time::{Duration, Instant};
use tor_basic_utils::retry::RetryDelay;
+use web_time_compat::{Duration, Instant};
/// Status information about whether a
/// [`FallbackDir`](tor_dircommon::fallback::FallbackDir) or
@@ -78,10 +78,11 @@ mod test {
#![allow(clippy::needless_pass_by_value)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use super::*;
+ use web_time_compat::InstantExt;
#[test]
fn status_basics() {
- let now = Instant::now();
+ let now = Instant::get();
/// floor to use for testing.
const FLOOR: Duration = Duration::from_secs(99);
diff --git a/crates/tor-guardmgr/src/err.rs b/crates/tor-guardmgr/src/err.rs
index a93183e5e..f59544c45 100644
--- a/crates/tor-guardmgr/src/err.rs
+++ b/crates/tor-guardmgr/src/err.rs
@@ -2,9 +2,9 @@
use futures::task::SpawnError;
use std::sync::Arc;
-use std::time::Instant;
use tor_basic_utils::iter::FilterCount;
use tor_error::{Bug, ErrorKind, HasKind};
+use web_time_compat::{Instant, InstantExt};
/// A error caused by a failure to pick a guard.
#[derive(Clone, Debug, thiserror::Error)]
@@ -19,7 +19,7 @@ pub enum PickGuardError {
suitable.display_frac_rejected(),
filtered.display_frac_rejected(),
if let Some(retry_at) = retry_at {
- format!(" Retrying in {}.", humantime::format_duration(*retry_at - Instant::now()))
+ format!(" Retrying in {}.", humantime::format_duration(*retry_at - Instant::get()))
} else {
"".to_string()
},
diff --git a/crates/tor-guardmgr/src/fallback.rs b/crates/tor-guardmgr/src/fallback.rs
index 323870d29..8047254c8 100644
--- a/crates/tor-guardmgr/src/fallback.rs
+++ b/crates/tor-guardmgr/src/fallback.rs
@@ -6,9 +6,9 @@
use crate::{dirstatus::DirStatus, skew::SkewObservation};
use rand::seq::IteratorRandom;
-use std::time::{Duration, Instant};
use tor_dircommon::fallback::{FallbackDir, FallbackList};
use tor_linkspec::HasRelayIds;
+use web_time_compat::{Duration, Instant};
use crate::{PickGuardError, ids::FallbackId};
use tor_basic_utils::iter::{FilterCount, IteratorExt as _};
@@ -201,6 +201,7 @@ mod test {
use super::*;
use rand::Rng;
use tor_basic_utils::test_rng::testing_rng;
+ use web_time_compat::InstantExt;
/// Construct a `FallbackDir` with random identity keys and addresses.
///
@@ -297,7 +298,7 @@ mod test {
let filter = crate::GuardFilter::unfiltered();
let mut counts = [0_usize; 4];
- let now = Instant::now();
+ let now = Instant::get();
dbg!("A");
fn lookup_idx(set: &FallbackState, id: &impl HasRelayIds) -> Option<usize> {
set.fallbacks
@@ -365,7 +366,7 @@ mod test {
.map(|ent| FallbackId::from_relay_ids(&ent.fallback))
.collect();
- let now = Instant::now();
+ let now = Instant::get();
// There's no "next retry time" when everybody's up.
assert!(set.next_retry().is_none());
diff --git a/crates/tor-guardmgr/src/guard.rs b/crates/tor-guardmgr/src/guard.rs
index 6e876340b..1fa6b2d52 100644
--- a/crates/tor-guardmgr/src/guard.rs
+++ b/crates/tor-guardmgr/src/guard.rs
@@ -6,8 +6,8 @@ use itertools::Itertools;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::net::SocketAddr;
-use std::time::{Duration, Instant, SystemTime};
use tracing::{info, trace, warn};
+use web_time_compat::{Duration, Instant, InstantExt, SystemTime};
use crate::dirstatus::DirStatus;
use crate::sample::Candidate;
@@ -448,7 +448,7 @@ impl Guard {
Some(retry_at) => warn!(
"Could not connect to guard {}. Retrying in {}.",
self,
- humantime::format_duration(retry_at - Instant::now()),
+ humantime::format_duration(retry_at - Instant::get()),
),
None => warn!(
"Could not connect to guard {}. Next retry time unknown.",
@@ -951,6 +951,7 @@ mod test {
use crate::ids::FirstHopId;
use tor_linkspec::{HasRelayIds, RelayId};
use tor_llcrypto::pk::ed25519::Ed25519Identity;
+ use web_time_compat::SystemTimeExt;
#[test]
fn crate_id() {
@@ -965,7 +966,7 @@ mod test {
fn basic_guard() -> Guard {
let id = basic_id();
let ports = vec!["127.0.0.7:7777".parse().unwrap()];
- let added = SystemTime::now();
+ let added = SystemTime::get();
Guard::new(id, ports, None, added)
}
@@ -1055,9 +1056,9 @@ mod test {
#[test]
fn record_attempt() {
- let t1 = Instant::now() - Duration::from_secs(10);
- let t2 = Instant::now() - Duration::from_secs(5);
- let t3 = Instant::now();
+ let t1 = Instant::get() - Duration::from_secs(10);
+ let t2 = Instant::get() - Duration::from_secs(5);
+ let t3 = Instant::get();
let mut g = basic_guard();
@@ -1072,8 +1073,8 @@ mod test {
#[test]
fn record_failure() {
- let t1 = Instant::now() - Duration::from_secs(10);
- let t2 = Instant::now();
+ let t1 = Instant::get() - Duration::from_secs(10);
+ let t2 = Instant::get();
let mut g = basic_guard();
g.record_failure(t1, true);
@@ -1090,11 +1091,11 @@ mod test {
#[test]
fn record_success() {
- let t1 = Instant::now() - Duration::from_secs(10);
+ let t1 = Instant::get() - Duration::from_secs(10);
// has to be in the future, since the guard's "added_at" time is based on now.
- let now = SystemTime::now();
+ let now = SystemTime::get();
let t2 = now + Duration::from_secs(300 * 86400);
- let t3 = Instant::now() + Duration::from_secs(310 * 86400);
+ let t3 = Instant::get() + Duration::from_secs(310 * 86400);
let t4 = now + Duration::from_secs(320 * 86400);
let mut g = basic_guard();
@@ -1121,7 +1122,7 @@ mod test {
#[test]
fn retry() {
- let t1 = Instant::now();
+ let t1 = Instant::get();
let mut g = basic_guard();
g.record_failure(t1, true);
@@ -1148,7 +1149,7 @@ mod test {
fn expiration() {
const DAY: Duration = Duration::from_secs(24 * 60 * 60);
let params = GuardParams::default();
- let now = SystemTime::now();
+ let now = SystemTime::get();
let g = basic_guard();
assert!(!g.is_expired(&params, now));
@@ -1176,7 +1177,7 @@ mod test {
use tor_netdir::testnet;
let netdir = testnet::construct_netdir().unwrap_if_sufficient().unwrap();
let params = GuardParams::default();
- let now = SystemTime::now();
+ let now = SystemTime::get();
// Construct a guard from a relay from the netdir.
let relay22 = netdir.by_id(&Ed25519Identity::from([22; 32])).unwrap();
@@ -1226,7 +1227,7 @@ mod test {
.unwrap();
//let params = GuardParams::default();
- let now = SystemTime::now();
+ let now = SystemTime::get();
// Try a guard that isn't in the netdir at all.
let mut guard255 = Guard::new(
@@ -1283,7 +1284,7 @@ mod test {
#[test]
fn pending() {
let mut g = basic_guard();
- let t1 = Instant::now();
+ let t1 = Instant::get();
let t2 = t1 + Duration::from_secs(100);
let t3 = t1 + Duration::from_secs(200);
@@ -1320,7 +1321,7 @@ mod test {
let mut g = basic_guard();
let params = GuardParams::default();
- let now = SystemTime::now();
+ let now = SystemTime::get();
let _ignore = g.record_success(now, &params);
for _ in 0..13 {
@@ -1374,8 +1375,8 @@ mod test {
use crate::GuardUsageBuilder;
let mut g = basic_guard();
- let inst = Instant::now();
- let st = SystemTime::now();
+ let inst = Instant::get();
+ let st = SystemTime::get();
let sec = Duration::from_secs(1);
let params = GuardParams::default();
let dir_usage = GuardUsageBuilder::new()
diff --git a/crates/tor-guardmgr/src/lib.rs b/crates/tor-guardmgr/src/lib.rs
index 6f54146d4..9e0534eae 100644
--- a/crates/tor-guardmgr/src/lib.rs
+++ b/crates/tor-guardmgr/src/lib.rs
@@ -62,7 +62,6 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex, Weak};
-use std::time::{Duration, Instant, SystemTime};
#[cfg(feature = "bridge-client")]
use tor_error::internal;
use tor_linkspec::{OwnedChanTarget, OwnedCircTarget, RelayId, RelayIdSet};
@@ -71,6 +70,7 @@ use tor_proto::ClockSkew;
use tor_rtcompat::SpawnExt;
use tor_units::BoundedInt32;
use tracing::{debug, info, instrument, trace, warn};
+use web_time_compat::{Duration, Instant, SystemTime};
use tor_config::derive::prelude::*;
use tor_config::{ExplicitOrAuto, impl_standard_builder};
diff --git a/crates/tor-guardmgr/src/pending.rs b/crates/tor-guardmgr/src/pending.rs
index 051291e85..f9bef8536 100644
--- a/crates/tor-guardmgr/src/pending.rs
+++ b/crates/tor-guardmgr/src/pending.rs
@@ -17,8 +17,8 @@ use std::fmt::Debug;
use std::pin::Pin;
use std::sync::atomic::{AtomicU64, Ordering};
use std::task::{Context, Poll};
-use std::time::Instant;
use tor_proto::ClockSkew;
+use web_time_compat::Instant;
use tor_basic_utils::skip_fmt;
diff --git a/crates/tor-guardmgr/src/sample.rs b/crates/tor-guardmgr/src/sample.rs
index b0c2eae80..524f45556 100644
--- a/crates/tor-guardmgr/src/sample.rs
+++ b/crates/tor-guardmgr/src/sample.rs
@@ -18,8 +18,8 @@ use rand::seq::IndexedRandom;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
-use std::time::{Instant, SystemTime};
use tracing::{debug, info};
+use web_time_compat::{Instant, SystemTime};
#[allow(unused_imports)]
pub(crate) use candidate::{Candidate, CandidateStatus, Universe, UniverseRef, WeightThreshold};
@@ -1033,6 +1033,7 @@ mod test {
use tor_netdir::NetDir;
use tor_netdoc::doc::netstatus::RelayWeight;
use tor_netdoc::types::relay_flags::RelayFlag;
+ use web_time_compat::{InstantExt, SystemTimeExt};
use super::*;
use crate::FirstHopId;
@@ -1093,7 +1094,7 @@ mod test {
let mut samples: Vec<HashSet<GuardId>> = Vec::new();
for _ in 0..3 {
let mut guards = GuardSet::default();
- guards.extend_sample_as_needed(SystemTime::now(), &params, &netdir);
+ guards.extend_sample_as_needed(SystemTime::get(), &params, &netdir);
assert_eq!(guards.guards.len(), params.min_filtered_sample_size);
assert_eq!(guards.confirmed.len(), 0);
assert_eq!(guards.primary.len(), 0);
@@ -1107,12 +1108,12 @@ mod test {
assert!(relay.low_level_details().is_dir_cache());
assert!(guards.guards.by_all_ids(&relay).is_some());
{
- assert!(!guard.is_expired(&params, SystemTime::now()));
+ assert!(!guard.is_expired(&params, SystemTime::get()));
}
}
// Make sure that the sample doesn't expand any further.
- guards.extend_sample_as_needed(SystemTime::now(), &params, &netdir);
+ guards.extend_sample_as_needed(SystemTime::get(), &params, &netdir);
assert_eq!(guards.guards.len(), params.min_filtered_sample_size);
guards.assert_consistency();
@@ -1132,7 +1133,7 @@ mod test {
..GuardParams::default()
};
- let t1 = SystemTime::now();
+ let t1 = SystemTime::get();
let t2 = t1 + Duration::from_secs(20);
let mut guards = GuardSet::default();
@@ -1176,7 +1177,7 @@ mod test {
n_primary: 4,
..GuardParams::default()
};
- let t1 = SystemTime::now();
+ let t1 = SystemTime::get();
let t2 = t1 + Duration::from_secs(20);
let t3 = t2 + Duration::from_secs(30);
@@ -1222,7 +1223,7 @@ mod test {
fn expiration() {
let netdir = netdir();
let params = GuardParams::default();
- let t1 = SystemTime::now();
+ let t1 = SystemTime::get();
let mut guards = GuardSet::default();
guards.extend_sample_as_needed(t1, &params, &netdir);
@@ -1256,8 +1257,8 @@ mod test {
n_primary: 2,
..GuardParams::default()
};
- let st1 = SystemTime::now();
- let i1 = Instant::now();
+ let st1 = SystemTime::get();
+ let i1 = Instant::get();
let sec = Duration::from_secs(1);
let mut guards = GuardSet::default();
@@ -1383,8 +1384,8 @@ mod test {
max_sample_bw_fraction: 1.0,
..GuardParams::default()
};
- let mut st = SystemTime::now();
- let mut inst = Instant::now();
+ let mut st = SystemTime::get();
+ let mut inst = Instant::get();
let sec = Duration::from_secs(1);
let usage = crate::GuardUsageBuilder::default().build().unwrap();
@@ -1425,7 +1426,7 @@ mod test {
let mut guards = GuardSet::default();
- guards.extend_sample_as_needed(SystemTime::now(), &params, &netdir);
+ guards.extend_sample_as_needed(SystemTime::get(), &params, &netdir);
guards.select_primary_guards(&params);
assert_eq!(guards.primary.len(), 2);
@@ -1433,25 +1434,25 @@ mod test {
// Let one primary guard fail.
let (kind, p_id1) = guards
- .pick_guard_id(&usage, &params, Instant::now())
+ .pick_guard_id(&usage, &params, Instant::get())
.unwrap();
assert_eq!(kind, ListKind::Primary);
- guards.record_failure(&p_id1, None, Instant::now());
+ guards.record_failure(&p_id1, None, Instant::get());
assert!(!guards.all_primary_guards_are_unreachable());
// Now let the other one fail.
let (kind, p_id2) = guards
- .pick_guard_id(&usage, &params, Instant::now())
+ .pick_guard_id(&usage, &params, Instant::get())
.unwrap();
assert_eq!(kind, ListKind::Primary);
- guards.record_failure(&p_id2, None, Instant::now());
+ guards.record_failure(&p_id2, None, Instant::get());
assert!(guards.all_primary_guards_are_unreachable());
// Now mark the guards retriable.
guards.mark_primary_guards_retriable();
assert!(!guards.all_primary_guards_are_unreachable());
let (kind, p_id3) = guards
- .pick_guard_id(&usage, &params, Instant::now())
+ .pick_guard_id(&usage, &params, Instant::get())
.unwrap();
assert_eq!(kind, ListKind::Primary);
assert_eq!(p_id3, p_id1);
@@ -1468,14 +1469,14 @@ mod test {
};
let usage = crate::GuardUsageBuilder::default().build().unwrap();
let mut guards = GuardSet::default();
- guards.extend_sample_as_needed(SystemTime::now(), &params, &netdir);
+ guards.extend_sample_as_needed(SystemTime::get(), &params, &netdir);
guards.select_primary_guards(&params);
assert_eq!(guards.primary.len(), 2);
let (_kind, p_id1) = guards
- .pick_guard_id(&usage, &params, Instant::now())
+ .pick_guard_id(&usage, &params, Instant::get())
.unwrap();
- guards.record_success(&p_id1, &params, None, SystemTime::now());
+ guards.record_success(&p_id1, &params, None, SystemTime::get());
assert_eq!(guards.n_primary_without_id_info_in(&netdir), 0);
use tor_netdir::testnet;
@@ -1502,17 +1503,17 @@ mod test {
..GuardParams::default()
};
let mut guards1 = GuardSet::default();
- guards1.extend_sample_as_needed(SystemTime::now(), &params, &netdir);
+ guards1.extend_sample_as_needed(SystemTime::get(), &params, &netdir);
guards1.select_primary_guards(&params);
let mut guards2 = guards1.clone();
// Make a persistent change in guards1, and a different persistent change in guards2.
let id1 = guards1.primary[0].clone();
let id2 = guards1.primary[1].clone();
- guards1.record_success(&id1, &params, None, SystemTime::now());
- guards2.record_success(&id2, &params, None, SystemTime::now());
+ guards1.record_success(&id1, &params, None, SystemTime::get());
+ guards2.record_success(&id2, &params, None, SystemTime::get());
// Make a non-persistent change in guards2.
- guards2.record_failure(&id2, None, Instant::now());
+ guards2.record_failure(&id2, None, Instant::get());
// Copy status: make sure non-persistent status changed, and persistent didn't.
guards1.copy_ephemeral_status_into_newly_loaded_state(guards2);
@@ -1537,7 +1538,7 @@ mod test {
for _ in 0..4 {
// There is roughly a 1-in-5000 chance of getting the same set
// twice, so we loop until that doesn't happen.
- guards3.extend_sample_as_needed(SystemTime::now(), &params, &netdir);
+ guards3.extend_sample_as_needed(SystemTime::get(), &params, &netdir);
guards3.select_primary_guards(&params);
g3_set = guards3
.guards
diff --git a/crates/tor-guardmgr/src/skew.rs b/crates/tor-guardmgr/src/skew.rs
index a1ed084ed..99090f07d 100644
--- a/crates/tor-guardmgr/src/skew.rs
+++ b/crates/tor-guardmgr/src/skew.rs
@@ -7,7 +7,7 @@
// of bridges is very small, see if we can still use that to make a
// low-confidence value.
-use std::time::{Duration, Instant};
+use web_time_compat::{Duration, Instant};
use tor_proto::ClockSkew;
@@ -245,6 +245,7 @@ mod test {
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use super::*;
use float_eq::assert_float_eq;
+ use web_time_compat::InstantExt;
/// Tolerance for float comparison.
const TOL: f64 = 0.00001;
@@ -327,7 +328,7 @@ mod test {
#[test]
fn estimate_with_no_data() {
// zero inputs -> output is none.
- let now = Instant::now();
+ let now = Instant::get();
let est = SkewEstimate::estimate_skew([].iter(), now);
assert!(est.is_none());
@@ -365,7 +366,7 @@ mod test {
mins.iter()
.map(|m| SkewObservation {
skew: ClockSkew::from_secs_f64(m * 60.0).unwrap(),
- when: Instant::now(),
+ when: Instant::get(),
})
.collect()
}
@@ -383,7 +384,7 @@ mod test {
// confidence.
let obs = from_minutes(&[-20.0, -10.0, -20.0, -25.0, 0.0, -18.0, -22.0, -22.0]);
- let est = SkewEstimate::estimate_skew(obs.iter(), Instant::now()).unwrap();
+ let est = SkewEstimate::estimate_skew(obs.iter(), Instant::get()).unwrap();
assert_eq!(
est.to_string(),
"slow by around 17m 7s (based on 8 recent observations, with some confidence)"
@@ -401,7 +402,7 @@ mod test {
-100.0, 100.0, -3.0, -2.0, 0.0, 1.0, 0.5, 6.0, 3.0, 0.5, 99.0,
]);
- let est = SkewEstimate::estimate_skew(obs.iter(), Instant::now()).unwrap();
+ let est = SkewEstimate::estimate_skew(obs.iter(), Instant::get()).unwrap();
assert_eq!(
est.to_string(),
"not skewed by more than 15m (based on 8 recent observations, with high confidence)"
diff --git a/crates/tor-guardmgr/src/util.rs b/crates/tor-guardmgr/src/util.rs
index bc27314fd..eea47b091 100644
--- a/crates/tor-guardmgr/src/util.rs
+++ b/crates/tor-guardmgr/src/util.rs
@@ -77,10 +77,11 @@ mod test {
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use super::*;
use tor_basic_utils::test_rng::testing_rng;
+ use web_time_compat::SystemTimeExt;
#[test]
fn test_randomize_time() {
- let now = SystemTime::now();
+ let now = SystemTime::get();
let one_hour = humantime::parse_duration("1hr").unwrap();
let ten_sec = humantime::parse_duration("10s").unwrap();
let mut rng = testing_rng();
diff --git a/crates/tor-hsclient/Cargo.toml b/crates/tor-hsclient/Cargo.toml
index 354e48673..cb6542792 100644
--- a/crates/tor-hsclient/Cargo.toml
+++ b/crates/tor-hsclient/Cargo.toml
@@ -90,6 +90,7 @@ tor-proto = { version = "0.40.0", path = "../tor-proto", features = ["hs-client"
tor-protover = { version = "0.40.0", path = "../tor-protover" }
tor-rtcompat = { version = "0.40.0", path = "../tor-rtcompat" }
tracing = "0.1.36"
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
[dev-dependencies]
humantime = "2"
diff --git a/crates/tor-hsclient/src/connect.rs b/crates/tor-hsclient/src/connect.rs
index 11b4f14e4..c547343d2 100644
--- a/crates/tor-hsclient/src/connect.rs
+++ b/crates/tor-hsclient/src/connect.rs
@@ -1,12 +1,9 @@
//! Main implementation of the connection functionality
-use std::time::Duration;
-
use std::collections::HashMap;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::sync::Arc;
-use std::time::Instant;
use async_trait::async_trait;
use educe::Educe;
@@ -27,6 +24,7 @@ use tor_hscrypto::Subcredential;
use tor_proto::TargetHop;
use tor_proto::client::circuit::handshake::hs_ntor;
use tracing::{debug, instrument, trace};
+use web_time_compat::{Duration, Instant};
use retry_error::RetryError;
use safelog::{DispRedacted, Sensitive};
diff --git a/crates/tor-hsclient/src/pow/v1.rs b/crates/tor-hsclient/src/pow/v1.rs
index 9993442cc..1b8a6b5ba 100644
--- a/crates/tor-hsclient/src/pow/v1.rs
+++ b/crates/tor-hsclient/src/pow/v1.rs
@@ -1,7 +1,6 @@
//! Client support for the `v1` onion service proof of work scheme
use crate::err::ProofOfWorkError;
-use std::time::Instant;
use tor_async_utils::oneshot;
use tor_async_utils::oneshot::Canceled;
use tor_cell::relaycell::hs::pow::v1::ProofOfWorkV1;
@@ -10,6 +9,7 @@ use tor_hscrypto::pk::HsBlindId;
use tor_hscrypto::pow::v1::{Effort, Instance, SolverInput};
use tor_netdoc::doc::hsdesc::pow::v1::PowParamsV1;
use tracing::debug;
+use web_time_compat::{Instant, InstantExt};
/// Double effort at retry until this threshold.
///
@@ -93,7 +93,7 @@ impl HsPowClientV1 {
// TODO: config option
input.runtime(Default::default());
- let start_time = Instant::now();
+ let start_time = Instant::get();
debug!("beginning solve, {:?}", self.effort);
let (result_sender, result_receiver) = oneshot::channel();
diff --git a/crates/tor-hsclient/src/state.rs b/crates/tor-hsclient/src/state.rs
index b3fc983d2..239613287 100644
--- a/crates/tor-hsclient/src/state.rs
+++ b/crates/tor-hsclient/src/state.rs
@@ -5,7 +5,6 @@ use std::fmt::Debug;
use std::mem;
use std::panic::AssertUnwindSafe;
use std::sync::{Arc, Mutex, MutexGuard};
-use std::time::{Duration, Instant};
use futures::FutureExt as _;
use futures::task::SpawnError;
@@ -23,6 +22,7 @@ use tor_error::{Bug, ErrorReport as _, debug_report, error_report, internal};
use tor_hscrypto::pk::HsId;
use tor_netdir::NetDir;
use tor_rtcompat::{Runtime, SpawnExt as _};
+use web_time_compat::{Duration, Instant};
use crate::isol_map;
use crate::{ConnError, HsClientConnector, HsClientSecretKeys};
diff --git a/crates/tor-hscrypto/Cargo.toml b/crates/tor-hscrypto/Cargo.toml
index d2cf0160b..05c2b020b 100644
--- a/crates/tor-hscrypto/Cargo.toml
+++ b/crates/tor-hscrypto/Cargo.toml
@@ -67,6 +67,7 @@ tor-llcrypto = { version = "0.40.0", path = "../tor-llcrypto", features = ["hsv3
tor-memquota = { version = "0.40.0", path = "../tor-memquota", default-features = false, optional = true }
tor-units = { path = "../tor-units", version = "0.40.0" }
void = "1"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
zeroize = { version = "1", optional = true }
[dev-dependencies]
diff --git a/crates/tor-hscrypto/src/pk.rs b/crates/tor-hscrypto/src/pk.rs
index 4a56a004e..ba9e4d39a 100644
--- a/crates/tor-hscrypto/src/pk.rs
+++ b/crates/tor-hscrypto/src/pk.rs
@@ -818,8 +818,8 @@ mod test {
use hex_literal::hex;
use itertools::izip;
- use std::time::{Duration, SystemTime};
use tor_basic_utils::test_rng::testing_rng;
+ use web_time_compat::{Duration, SystemTime, SystemTimeExt};
use super::*;
@@ -872,7 +872,7 @@ mod test {
fn key_blinding_blackbox() {
let mut rng = testing_rng();
let offset = Duration::new(12 * 60 * 60, 0);
- let when = TimePeriod::new(Duration::from_secs(3600), SystemTime::now(), offset).unwrap();
+ let when = TimePeriod::new(Duration::from_secs(3600), SystemTime::get(), offset).unwrap();
let keypair = ed25519::Keypair::generate(&mut rng);
let id_pub = HsIdKey::from(keypair.verifying_key());
let id_keypair = HsIdKeypair::from(ed25519::ExpandedKeypair::from(&keypair));
diff --git a/crates/tor-hscrypto/src/time.rs b/crates/tor-hscrypto/src/time.rs
index a4d7ea831..e70c2f667 100644
--- a/crates/tor-hscrypto/src/time.rs
+++ b/crates/tor-hscrypto/src/time.rs
@@ -1,12 +1,10 @@
//! Manipulate time periods (as used in the onion service system)
-use std::{
- fmt::Display,
- time::{Duration, SystemTime},
-};
+use std::fmt::Display;
use humantime::format_rfc3339_seconds;
use tor_units::IntegerMinutes;
+use web_time_compat::{Duration, SystemTime};
use serde::{Deserialize, Serialize};
diff --git a/crates/tor-hsservice/Cargo.toml b/crates/tor-hsservice/Cargo.toml
index bf200636b..e9a4ff0f5 100644
--- a/crates/tor-hsservice/Cargo.toml
+++ b/crates/tor-hsservice/Cargo.toml
@@ -140,6 +140,7 @@ tor-relay-selection = { path = "../tor-relay-selection", version = "0.40.0" }
tor-rtcompat = { version = "0.40.0", path = "../tor-rtcompat" }
tracing = "0.1.36"
void = "1"
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
[dev-dependencies]
libc = { version = "0.2", default-features = false }
diff --git a/crates/tor-hsservice/src/internal_prelude.rs b/crates/tor-hsservice/src/internal_prelude.rs
index ed17f48bd..f3e3f77c9 100644
--- a/crates/tor-hsservice/src/internal_prelude.rs
+++ b/crates/tor-hsservice/src/internal_prelude.rs
@@ -37,7 +37,6 @@ pub(crate) use {
std::path::{Path, PathBuf},
std::str::FromStr,
std::sync::{Arc, Mutex, MutexGuard},
- std::time::{Duration, Instant, SystemTime},
};
//---------- upstreams ----------
@@ -110,6 +109,7 @@ pub(crate) use {
tor_proto::client::stream::DataStream,
tor_rtcompat::SleepProvider,
tor_rtcompat::{Runtime, SleepProviderExt as _},
+ web_time_compat::{Duration, Instant, SystemTime},
};
//---------- names from this crate ----------
diff --git a/crates/tor-hsservice/src/pow/v1.rs b/crates/tor-hsservice/src/pow/v1.rs
index e791f0bb5..b92972491 100644
--- a/crates/tor-hsservice/src/pow/v1.rs
+++ b/crates/tor-hsservice/src/pow/v1.rs
@@ -8,7 +8,6 @@ use std::{
collections::{BTreeSet, HashMap, VecDeque},
sync::{Arc, Mutex, RwLock},
task::Waker,
- time::{Duration, Instant, SystemTime},
};
use arrayvec::ArrayVec;
@@ -39,6 +38,7 @@ use tor_persist::{
};
use tor_rtcompat::Runtime;
use tor_rtcompat::SpawnExt;
+use web_time_compat::{Duration, Instant, InstantExt, SystemTime, SystemTimeExt};
use crate::{
BlindIdPublicKeySpecifier, OnionServiceConfig, RendRequest, ReplayError, StartupError,
@@ -426,7 +426,7 @@ impl<R: Runtime, Q: MockableRendRequest + Send + 'static> PowManagerGeneric<R, Q
.checked_sub(SEED_EARLY_ROTATION_TIME)
.expect("SEED_EARLY_ROTATION_TIME too high, or EXPIRATION_TIME_MINS_MIN too low.");
let delay = next_update_time
- .map(|x| x.duration_since(SystemTime::now()).unwrap_or(MAX_DELAY))
+ .map(|x| x.duration_since(SystemTime::get()).unwrap_or(MAX_DELAY))
.unwrap_or(MAX_DELAY)
.min(MAX_DELAY)
.min(suggested_effort_update_delay);
@@ -439,7 +439,7 @@ impl<R: Runtime, Q: MockableRendRequest + Send + 'static> PowManagerGeneric<R, Q
/// Make a randomized seed expiration time.
fn make_next_expiration_time<Rng: RngCore + CryptoRng>(rng: &mut Rng) -> SystemTime {
- SystemTime::now()
+ SystemTime::get()
+ Duration::from_secs(
60 * rng
.gen_range_checked(EXPIRATION_TIME_MINS_MIN..=EXPIRATION_TIME_MINS_MAX)
@@ -519,7 +519,7 @@ impl<R: Runtime, Q: MockableRendRequest + Send + 'static> PowManagerGeneric<R, Q
let rotation_time = Self::calculate_early_rotation_time(info.next_expiration_time);
update_times.push(rotation_time);
- if rotation_time <= SystemTime::now() {
+ if rotation_time <= SystemTime::get() {
// This does not allow for easy testing, but because we're in a async function, it's
// non-trivial to pass in a Rng from the outside world. If we end up writing tests that
// require that, we can take a function to generate a Rng, but for now, just using the
@@ -774,7 +774,7 @@ impl<Q: MockableRendRequest> RendRequestOrdByEffort<Q> {
request,
pow,
max_effort,
- recv_time: Instant::now(),
+ recv_time: Instant::get(),
request_num,
})
}
diff --git a/crates/tor-hsservice/src/publish.rs b/crates/tor-hsservice/src/publish.rs
index bb0040316..2ee1b9a56 100644
--- a/crates/tor-hsservice/src/publish.rs
+++ b/crates/tor-hsservice/src/publish.rs
@@ -169,7 +169,6 @@ mod test {
use std::sync::Mutex;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::{Context, Poll};
- use std::time::Duration;
use async_trait::async_trait;
use fs_mistrust::Mistrust;
diff --git a/crates/tor-hsservice/src/publish/reupload_timer.rs b/crates/tor-hsservice/src/publish/reupload_timer.rs
index 565895d9f..60c2a7e79 100644
--- a/crates/tor-hsservice/src/publish/reupload_timer.rs
+++ b/crates/tor-hsservice/src/publish/reupload_timer.rs
@@ -53,15 +53,15 @@ mod test {
#![allow(clippy::needless_pass_by_value)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use std::collections::BinaryHeap;
- use std::time::Duration;
use super::*;
+ use web_time_compat::InstantExt;
#[test]
fn reupload_for_time_period_ordering() {
const ONE_SEC: Duration = Duration::from_secs(1);
- let now = Instant::now();
+ let now = Instant::get();
let later = now + ONE_SEC;
let later_still = now + ONE_SEC * 2;
let timer1 = ReuploadTimer {
diff --git a/crates/tor-hsservice/src/rend_handshake.rs b/crates/tor-hsservice/src/rend_handshake.rs
index ea1599b6c..c4e6f9141 100644
--- a/crates/tor-hsservice/src/rend_handshake.rs
+++ b/crates/tor-hsservice/src/rend_handshake.rs
@@ -176,10 +176,10 @@ pub(crate) trait RendCircConnector: Send + Sync {
/// Return the current time instant from the runtime.
///
/// This provides mockable time for use in error tracking.
- fn now(&self) -> std::time::Instant;
+ fn now(&self) -> Instant;
/// Return the current wall-clock time from the runtime.
- fn wallclock(&self) -> std::time::SystemTime;
+ fn wallclock(&self) -> SystemTime;
}
#[async_trait]
@@ -192,11 +192,11 @@ impl<R: Runtime> RendCircConnector for HsCircPool<R> {
HsCircPool::get_or_launch_svc_rend(self, netdir, target).await
}
- fn now(&self) -> std::time::Instant {
+ fn now(&self) -> Instant {
HsCircPool::now(self)
}
- fn wallclock(&self) -> std::time::SystemTime {
+ fn wallclock(&self) -> SystemTime {
HsCircPool::wallclock(self)
}
}
diff --git a/crates/tor-hsservice/src/time_store.rs b/crates/tor-hsservice/src/time_store.rs
index 54be02664..cf3e247bf 100644
--- a/crates/tor-hsservice/src/time_store.rs
+++ b/crates/tor-hsservice/src/time_store.rs
@@ -26,8 +26,8 @@
//!
//! ```
//! use serde::{Serialize, Deserialize};
-//! use std::time::{Duration, Instant};
//! use tor_rtcompat::{PreferredRuntime, SleepProvider as _};
+//! use web_time_compat::{Duration, Instant};
//!
//! # use tor_hsservice::time_store_for_doctests_unstable_no_semver_guarantees as time_store;
//! # #[cfg(all)] // works like #[cfg(FALSE)]. Instead, we have this workaround ^.
@@ -80,7 +80,7 @@
use std::fmt::{self, Display};
use std::str::FromStr;
-use std::time::{Duration, Instant, SystemTime};
+use web_time_compat::{Duration, Instant, SystemTime};
use derive_deftly::{Deftly, define_derive_deftly};
use serde::{Deserialize, Serialize};
@@ -492,6 +492,7 @@ mod test {
use humantime::parse_rfc3339;
use itertools::{Itertools, chain};
use tor_rtmock::{MockRuntime, simple_time::SimpleMockTimeProvider};
+ use web_time_compat::InstantExt;
fn secs(s: u64) -> Duration {
Duration::from_secs(s)
@@ -561,7 +562,7 @@ mod test {
s2: FutureTimestamp,
}
- let real_instant = Instant::now();
+ let real_instant = Instant::get();
let test_systime = parse_rfc3339("2008-08-02T00:00:00Z").unwrap();
let mk_runtime = |instant, systime| {
diff --git a/crates/tor-hsservice/src/timeout_track.rs b/crates/tor-hsservice/src/timeout_track.rs
index f6fd2ab2f..65a747dd7 100644
--- a/crates/tor-hsservice/src/timeout_track.rs
+++ b/crates/tor-hsservice/src/timeout_track.rs
@@ -147,7 +147,7 @@
use std::cell::Cell;
use std::cmp::Ordering;
-use std::time::{Duration, Instant, SystemTime};
+use web_time_compat::{Duration, Instant, SystemTime};
use derive_deftly::{Deftly, define_derive_deftly};
use futures::{FutureExt as _, future, select_biased};
@@ -634,6 +634,7 @@ mod test {
use std::task::Poll;
use tor_rtcompat::ToplevelBlockOn;
use tor_rtmock::MockRuntime;
+ use web_time_compat::InstantExt;
fn parse_rfc3339(s: &str) -> SystemTime {
humantime::parse_rfc3339(s).unwrap()
@@ -715,7 +716,7 @@ mod test {
#[test]
fn arith_instant_combined() {
// Adding 1Ms gives us some headroom, since we don't want to underflow
- let earliest = Instant::now() + secs(1000000);
+ let earliest = Instant::get() + secs(1000000);
let middle_d = secs(200);
let middle = earliest + middle_d;
let later_d = secs(300);
diff --git a/crates/tor-keymgr/Cargo.toml b/crates/tor-keymgr/Cargo.toml
index 3afa474ac..909dd51b5 100644
--- a/crates/tor-keymgr/Cargo.toml
+++ b/crates/tor-keymgr/Cargo.toml
@@ -83,6 +83,7 @@ tor-persist = { path = "../tor-persist", version = "0.40.0" }
tracing = "0.1.36"
visibility = { version = "0.1.0" }
walkdir = { version = "2" }
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
zeroize = "1"
[dev-dependencies]
diff --git a/crates/tor-keymgr/src/keystore/arti.rs b/crates/tor-keymgr/src/keystore/arti.rs
index 354561545..8afbc739f 100644
--- a/crates/tor-keymgr/src/keystore/arti.rs
+++ b/crates/tor-keymgr/src/keystore/arti.rs
@@ -421,12 +421,12 @@ mod tests {
use std::cmp::Ordering;
use std::fs;
use std::path::PathBuf;
- use std::time::{Duration, SystemTime};
use tempfile::{TempDir, tempdir};
use tor_cert::{CertifiedKey, Ed25519Cert};
use tor_checkable::{SelfSigned, Timebound};
use tor_key_forge::{CertType, KeyType, ParsedEd25519Cert};
use tor_llcrypto::pk::ed25519::{self, Ed25519PublicKey as _};
+ use web_time_compat::{Duration, SystemTime};
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
diff --git a/crates/tor-keymgr/src/mgr.rs b/crates/tor-keymgr/src/mgr.rs
index 66933e4bb..26473dc06 100644
--- a/crates/tor-keymgr/src/mgr.rs
+++ b/crates/tor-keymgr/src/mgr.rs
@@ -859,7 +859,6 @@ mod tests {
use std::result::Result as StdResult;
use std::str::FromStr;
use std::sync::{Arc, RwLock};
- use std::time::{Duration, SystemTime};
use tor_basic_utils::test_rng::testing_rng;
use tor_cert::CertifiedKey;
use tor_cert::Ed25519Cert;
@@ -871,6 +870,7 @@ mod tests {
};
use tor_llcrypto::pk::ed25519::{self, Ed25519PublicKey as _};
use tor_llcrypto::rng::FakeEntropicRng;
+ use web_time_compat::{Duration, SystemTime, SystemTimeExt};
#[cfg(feature = "experimental-api")]
use {
@@ -2079,7 +2079,7 @@ mod tests {
let keypair = ed25519::Keypair::generate(&mut rng);
let encoded_cert = Ed25519Cert::constructor()
.cert_type(tor_cert::CertType::IDENTITY_V_SIGNING)
- .expiration(SystemTime::now() + Duration::from_secs(180))
+ .expiration(SystemTime::get() + Duration::from_secs(180))
.signing_key(keypair.public_key().into())
.cert_key(CertifiedKey::Ed25519(keypair.public_key().into()))
.encode_and_sign(&keypair)
diff --git a/crates/tor-log-ratelim/Cargo.toml b/crates/tor-log-ratelim/Cargo.toml
index 95e41e6f3..539190d3c 100644
--- a/crates/tor-log-ratelim/Cargo.toml
+++ b/crates/tor-log-ratelim/Cargo.toml
@@ -25,6 +25,7 @@ tor-error = { path = "../tor-error", version = "0.40.0" }
tor-rtcompat = { path = "../tor-rtcompat", version = "0.40.0" }
tracing = "0.1.36"
weak-table = "0.3.0"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
diff --git a/crates/tor-log-ratelim/src/ratelim.rs b/crates/tor-log-ratelim/src/ratelim.rs
index 5a05db325..525a88575 100644
--- a/crates/tor-log-ratelim/src/ratelim.rs
+++ b/crates/tor-log-ratelim/src/ratelim.rs
@@ -14,7 +14,7 @@ use tor_rtcompat::SpawnExt as _;
pub(crate) mod rt {
use futures::{future::BoxFuture, task::Spawn};
use std::sync::OnceLock;
- use std::time::{Duration, Instant};
+ use web_time_compat::{Duration, Instant};
/// A dyn-safe view of the parts of an async runtime that we need for rate-limiting.
pub trait RuntimeSupport: Spawn + 'static + Sync + Send {
diff --git a/crates/tor-netdir/Cargo.toml b/crates/tor-netdir/Cargo.toml
index 4d41c2e5f..5d0817ed1 100644
--- a/crates/tor-netdir/Cargo.toml
+++ b/crates/tor-netdir/Cargo.toml
@@ -82,6 +82,7 @@ tor-units = { path = "../tor-units", version = "0.40.0" }
tracing = "0.1.36"
typed-index-collections = "3.2.3"
visibility = { version = "0.1.0", optional = true }
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
float_eq = "1.0.0"
diff --git a/crates/tor-netdir/src/testnet.rs b/crates/tor-netdir/src/testnet.rs
index fdea84985..d928e702d 100644
--- a/crates/tor-netdir/src/testnet.rs
+++ b/crates/tor-netdir/src/testnet.rs
@@ -15,7 +15,6 @@
use crate::{MdReceiver, PartialNetDir};
use std::iter;
use std::net::SocketAddr;
-use std::time::{Duration, SystemTime};
#[cfg(feature = "geoip")]
use tor_geoip::GeoipDb;
use tor_netdoc::doc::microdesc::{Microdesc, MicrodescBuilder};
@@ -23,6 +22,7 @@ use tor_netdoc::doc::netstatus::{Lifetime, MdRouterStatusBuilder, RelayWeight};
use tor_netdoc::doc::netstatus::{MdConsensus, MdConsensusBuilder};
use tor_netdoc::types::relay_flags::RelayFlag;
pub use tor_netdoc::{BuildError, BuildResult};
+use web_time_compat::{Duration, SystemTime, SystemTimeExt};
/// A set of builder objects for a single node.
#[derive(Debug, Clone)]
@@ -201,7 +201,7 @@ where
];
let lifetime = lifetime.map(Ok).unwrap_or_else(|| {
- let now = SystemTime::now();
+ let now = SystemTime::get();
let one_day = Duration::new(86400, 0);
Lifetime::new(now, now + one_day / 2, now + one_day)
diff --git a/crates/tor-netdir/src/weight.rs b/crates/tor-netdir/src/weight.rs
index 8acceb8fa..d47e34fd2 100644
--- a/crates/tor-netdir/src/weight.rs
+++ b/crates/tor-netdir/src/weight.rs
@@ -427,6 +427,7 @@ mod test {
use tor_basic_utils::test_rng::testing_rng;
use tor_netdoc::doc::netstatus::{Lifetime, MdRouterStatusBuilder};
use tor_netdoc::types::relay_flags::{RelayFlag, RelayFlags};
+ use web_time_compat::SystemTimeExt;
#[test]
fn t_clamp() {
@@ -642,7 +643,7 @@ mod test {
#[test]
fn weightset_from_consensus() {
use rand::Rng;
- let now = SystemTime::now();
+ let now = SystemTime::get();
let one_hour = Duration::new(3600, 0);
let mut rng = testing_rng();
let mut bld = MdConsensus::builder();
diff --git a/crates/tor-netdoc/Cargo.toml b/crates/tor-netdoc/Cargo.toml
index 0430e50b6..1a31c5a4e 100644
--- a/crates/tor-netdoc/Cargo.toml
+++ b/crates/tor-netdoc/Cargo.toml
@@ -137,6 +137,7 @@ tor-units = { version = "0.40.0", path = "../tor-units", optional = true }
visibility = { version = "0.1.0", optional = true }
visible = { version = "0.0.1", optional = true }
void = "1"
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
zeroize = "1"
[dev-dependencies]
diff --git a/crates/tor-netdoc/src/doc/authcert/build.rs b/crates/tor-netdoc/src/doc/authcert/build.rs
index 234bf350a..8383e72ef 100644
--- a/crates/tor-netdoc/src/doc/authcert/build.rs
+++ b/crates/tor-netdoc/src/doc/authcert/build.rs
@@ -152,6 +152,7 @@ mod test {
use super::*;
use hex_literal::hex;
use std::time::Duration;
+ use web_time_compat::SystemTimeExt;
fn rsa1() -> rsa::PublicKey {
let der = hex!(
@@ -169,7 +170,7 @@ mod test {
#[test]
fn simple_cert() {
- let now = SystemTime::now();
+ let now = SystemTime::get();
let one_hour = Duration::new(3600, 0);
let later = now + one_hour * 2;
let addr = "192.0.0.1:9090".parse().unwrap();
@@ -189,7 +190,7 @@ mod test {
#[test]
fn failing_cert() {
- let now = SystemTime::now();
+ let now = SystemTime::get();
let one_hour = Duration::new(3600, 0);
let later = now + one_hour * 2;
diff --git a/crates/tor-netdoc/src/doc/hsdesc/build.rs b/crates/tor-netdoc/src/doc/hsdesc/build.rs
index 86304f55c..431ce2fb7 100644
--- a/crates/tor-netdoc/src/doc/hsdesc/build.rs
+++ b/crates/tor-netdoc/src/doc/hsdesc/build.rs
@@ -320,6 +320,7 @@ mod test {
use tor_hscrypto::time::TimePeriod;
use tor_linkspec::LinkSpec;
use tor_llcrypto::pk::{curve25519, ed25519::ExpandedKeypair};
+ use web_time_compat::SystemTimeExt;
// TODO: move the test helpers to a separate module and make them more broadly available if
// necessary.
@@ -410,7 +411,7 @@ mod test {
.compute_blinded_key(period)
.unwrap();
- let expiry = SystemTime::now() + Duration::from_secs(CERT_EXPIRY_SECS);
+ let expiry = SystemTime::get() + Duration::from_secs(CERT_EXPIRY_SECS);
let mut rng = Config::Deterministic.into_rng();
let intro_points = vec![IntroPointDesc {
link_specifiers: vec![
diff --git a/crates/tor-netdoc/src/doc/netstatus/build/each_flavor.rs b/crates/tor-netdoc/src/doc/netstatus/build/each_flavor.rs
index a628b331d..2523d4ac2 100644
--- a/crates/tor-netdoc/src/doc/netstatus/build/each_flavor.rs
+++ b/crates/tor-netdoc/src/doc/netstatus/build/each_flavor.rs
@@ -416,11 +416,11 @@ mod test {
use crate::types::relay_flags::RelayFlag;
use std::net::SocketAddr;
- use std::time::{Duration, SystemTime};
+ use web_time_compat::{Duration, SystemTime, SystemTimeExt};
#[test]
fn consensus() {
- let now = SystemTime::now();
+ let now = SystemTime::get();
let one_hour = Duration::new(3600, 0);
let mut builder = crate::doc::netstatus::MdConsensus::builder();
diff --git a/crates/tor-persist/Cargo.toml b/crates/tor-persist/Cargo.toml
index fbdffa151..733fcbcb0 100644
--- a/crates/tor-persist/Cargo.toml
+++ b/crates/tor-persist/Cargo.toml
@@ -51,6 +51,7 @@ tor-basic-utils = { path = "../tor-basic-utils", version = "0.40.0" }
tor-error = { path = "../tor-error", version = "0.40.0", features = ["tracing"] }
tracing = "0.1.36"
void = "1"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
anyhow = { version = "1.0.23" }
diff --git a/crates/tor-persist/src/fs.rs b/crates/tor-persist/src/fs.rs
index 1e46abda2..c70cff429 100644
--- a/crates/tor-persist/src/fs.rs
+++ b/crates/tor-persist/src/fs.rs
@@ -14,9 +14,9 @@ use oneshot_fused_workaround as oneshot;
use serde::{Serialize, de::DeserializeOwned};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
-use std::time::SystemTime;
use tor_error::warn_report;
use tracing::info;
+use web_time_compat::{SystemTime, SystemTimeExt};
/// Implementation of StateMgr that stores state as JSON files on disk.
///
@@ -223,7 +223,7 @@ impl StateMgr for FsStateMgr {
.try_lock()
.map_err(|e| Error::new(e, Action::Locking, self.err_resource_lock()))?
{
- self.clean(SystemTime::now());
+ self.clean(SystemTime::get());
Ok(LockStatus::NewlyAcquired)
} else {
Ok(LockStatus::NoLock)
@@ -341,7 +341,7 @@ mod test {
assert_eq!(count, 3); // two files, one lock.
// Now we can make sure that "clean" actually removes the right file.
- store.clean(SystemTime::now() + Duration::from_secs(365 * 86400));
+ store.clean(SystemTime::get() + Duration::from_secs(365 * 86400));
let lst: Vec<_> = statedir.read_dir().unwrap().collect();
assert_eq!(lst.len(), 2); // one file, one lock.
assert!(
@@ -374,7 +374,7 @@ mod test {
// Make the store directory read-only and make sure that we can't delete from it.
std::fs::set_permissions(&statedir, ro_dir).unwrap();
- store.clean(SystemTime::now() + Duration::from_secs(365 * 86400));
+ store.clean(SystemTime::get() + Duration::from_secs(365 * 86400));
let lst: Vec<_> = statedir.read_dir().unwrap().collect();
if lst.len() == 2 {
// We must be root. Don't do any more tests here.
diff --git a/crates/tor-persist/src/fs/clean.rs b/crates/tor-persist/src/fs/clean.rs
index 887cb1dc3..103a07261 100644
--- a/crates/tor-persist/src/fs/clean.rs
+++ b/crates/tor-persist/src/fs/clean.rs
@@ -1,14 +1,12 @@
//! Code to remove obsolete and extraneous files from a filesystem-based state
//! directory.
-use std::{
- path::{Path, PathBuf},
- time::{Duration, SystemTime},
-};
+use std::path::{Path, PathBuf};
use tor_basic_utils::PathExt as _;
use tor_error::warn_report;
use tracing::warn;
+use web_time_compat::{Duration, SystemTime};
/// Return true if `path` looks like a filename we'd like to remove from our
/// state directory.
@@ -114,6 +112,7 @@ mod test {
#![allow(clippy::needless_pass_by_value)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use super::*;
+ use web_time_compat::SystemTimeExt;
#[test]
fn fnames() {
@@ -135,7 +134,7 @@ mod test {
let dir = tempfile::TempDir::new().unwrap();
let fname1 = dir.path().join("quokka");
- let now = SystemTime::now();
+ let now = SystemTime::get();
std::fs::write(fname1, "hello world").unwrap();
let mut r = std::fs::read_dir(dir.path()).unwrap();
@@ -147,7 +146,7 @@ mod test {
#[test]
fn list() {
let dir = tempfile::TempDir::new().unwrap();
- let now = SystemTime::now();
+ let now = SystemTime::get();
let fname1 = dir.path().join("quokka.toml");
std::fs::write(fname1, "hello world").unwrap();
@@ -171,7 +170,7 @@ mod test {
fn absent() {
let dir = tempfile::TempDir::new().unwrap();
let dir2 = dir.path().join("subdir_that_doesnt_exist");
- let r = files_to_delete(&dir2, SystemTime::now());
+ let r = files_to_delete(&dir2, SystemTime::get());
assert!(r.is_empty());
}
}
diff --git a/crates/tor-persist/src/slug/timestamp.rs b/crates/tor-persist/src/slug/timestamp.rs
index 502efade0..079d3e79f 100644
--- a/crates/tor-persist/src/slug/timestamp.rs
+++ b/crates/tor-persist/src/slug/timestamp.rs
@@ -4,7 +4,6 @@ use crate::slug::{BadSlug, Slug};
use std::fmt;
use std::str::FromStr;
-use std::time::SystemTime;
use derive_more::{From, Into};
use thiserror::Error;
@@ -12,6 +11,7 @@ use time::format_description::FormatItem;
use time::macros::format_description;
use time::{OffsetDateTime, PrimitiveDateTime};
use tor_error::{Bug, into_internal};
+use web_time_compat::SystemTime;
/// A UTC timestamp that can be encoded in ISO 8601 format,
/// and that can be used as a `Slug`.
diff --git a/crates/tor-persist/src/state_dir.rs b/crates/tor-persist/src/state_dir.rs
index 5fa099655..61069fb4c 100644
--- a/crates/tor-persist/src/state_dir.rs
+++ b/crates/tor-persist/src/state_dir.rs
@@ -70,6 +70,7 @@
//! use tor_persist::state_dir;
//! use state_dir::{InstanceIdentity, InstancePurgeHandler};
//! use state_dir::{InstancePurgeInfo, InstanceStateHandle, StateDirectory, StorageHandle};
+//! use web_time_compat::SystemTimeExt;
//! #
//! # // fake up some things; we do this rather than using real ones
//! # // since this example will move, with the module, to a lower level crate.
@@ -134,7 +135,7 @@
//! retain_for: Duration,
//! ) -> Result<(), Error> {
//! state_dir.purge_instances(
-//! SystemTime::now(),
+//! SystemTime::get(),
//! &mut PurgeHandler(currently_configured_nicks, retain_for),
//! )?;
//! Ok(())
@@ -174,7 +175,7 @@ use std::io;
use std::marker::PhantomData;
use std::path::Path;
use std::sync::Arc;
-use std::time::{Duration, SystemTime};
+use web_time_compat::{Duration, SystemTime, SystemTimeExt};
use derive_deftly::{Deftly, define_derive_deftly};
use derive_more::{AsRef, Deref};
@@ -1013,7 +1014,8 @@ fn touch_instance_dir(dir: &CheckedDir) -> Result<()> {
let dir = dir.as_path();
let resource = || Resource::Directory { dir: dir.into() };
- filetime::set_file_mtime(dir, filetime::FileTime::now())
+ let mtime = filetime::FileTime::from_system_time(SystemTime::get());
+ filetime::set_file_mtime(dir, mtime)
.map_err(|source| Error::new(source, Action::Initializing, resource()))
}
@@ -1137,6 +1139,7 @@ mod test {
use tor_basic_utils::PathExt as _;
use tor_error::HasKind as _;
use tracing_test::traced_test;
+ use web_time_compat::SystemTimeExt;
use tor_error::ErrorKind as TEK;
@@ -1147,7 +1150,7 @@ mod test {
}
fn now() -> SystemTime {
- SystemTime::now()
+ SystemTime::get()
}
struct Garlic(Slug);
diff --git a/crates/tor-proto/Cargo.toml b/crates/tor-proto/Cargo.toml
index 28f528de2..e44d6ae93 100644
--- a/crates/tor-proto/Cargo.toml
+++ b/crates/tor-proto/Cargo.toml
@@ -143,6 +143,7 @@ tracing = "0.1.36"
typenum = "1.12"
visibility = { version = "0.1.0" }
void = "1"
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
zeroize = "1"
[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dev-dependencies]
diff --git a/crates/tor-proto/src/channel/handshake.rs b/crates/tor-proto/src/channel/handshake.rs
index 3c95cb036..f805ac346 100644
--- a/crates/tor-proto/src/channel/handshake.rs
+++ b/crates/tor-proto/src/channel/handshake.rs
@@ -5,7 +5,6 @@ use futures::sink::SinkExt;
use futures::stream::{Stream, StreamExt};
use std::net::IpAddr;
use std::sync::Arc;
-use std::time::SystemTime;
use tor_llcrypto::pk::ValidatableSignature;
use crate::channel::{Canonicity, ChannelFrame, UniqId};
@@ -26,6 +25,7 @@ use tor_linkspec::{
use tor_llcrypto as ll;
use tor_llcrypto::pk::ed25519::Ed25519Identity;
use tor_rtcompat::{CoarseTimeProvider, SleepProvider, StreamOps};
+use web_time_compat::{SystemTime, SystemTimeExt};
use digest::Digest;
@@ -656,7 +656,7 @@ impl<
use tor_cert::CertType;
// Replace 'now' with the real time to use.
- let now = now.unwrap_or_else(SystemTime::now);
+ let now = now.unwrap_or_else(SystemTime::get);
// We are a client initiating a channel to a relay or a bridge. We have received a CERTS
// cell and we need to verify these certs:
@@ -732,7 +732,7 @@ pub(crate) fn verify_link_auth_cert(
use tor_cert::CertType;
// Replace 'now' with the real time to use.
- let now = now.unwrap_or_else(SystemTime::now);
+ let now = now.unwrap_or_else(SystemTime::get);
// Now look at the signing->TLS cert and check it against the
// peer certificate.
@@ -956,7 +956,7 @@ pub(super) mod test {
{
let mb = MsgBuf::new(input);
let handshake = ClientInitiatorHandshake::new(mb, None, sleep_prov, fake_mq());
- handshake.connect(SystemTime::now).await.err().unwrap()
+ handshake.connect(SystemTime::get).await.err().unwrap()
}
#[test]
diff --git a/crates/tor-proto/src/channel/padding.rs b/crates/tor-proto/src/channel/padding.rs
index 7d2af56ce..dc3d40b17 100644
--- a/crates/tor-proto/src/channel/padding.rs
+++ b/crates/tor-proto/src/channel/padding.rs
@@ -29,7 +29,7 @@
use std::pin::Pin;
// TODO, coarsetime maybe? But see arti#496 and also we want to use the mockable SleepProvider
-use std::time::{Duration, Instant};
+use web_time_compat::{Duration, Instant};
use derive_builder::Builder;
use educe::Educe;
@@ -400,7 +400,7 @@ impl<R: SleepProvider> Timer<R> {
self.as_mut().select_fresh_timeout();
// Bet that we will be going to sleep again, and set up the new trigger time
- // and waker now. This will save us a future call to Instant::now.
+ // and waker now. This will save us a future call to Instant::get.
self.as_mut().prepare_to_sleep(Some(now));
Padding::new()
diff --git a/crates/tor-proto/src/circuit/circhop.rs b/crates/tor-proto/src/circuit/circhop.rs
index 13680c0ad..98e87c748 100644
--- a/crates/tor-proto/src/circuit/circhop.rs
+++ b/crates/tor-proto/src/circuit/circhop.rs
@@ -39,7 +39,7 @@ use std::num::NonZeroU32;
use std::pin::Pin;
use std::result::Result as StdResult;
use std::sync::{Arc, Mutex};
-use std::time::Instant;
+use web_time_compat::Instant;
#[cfg(test)]
use tor_cell::relaycell::msg::SendmeTag;
diff --git a/crates/tor-proto/src/client.rs b/crates/tor-proto/src/client.rs
index 89ab120ef..da3b30dc8 100644
--- a/crates/tor-proto/src/client.rs
+++ b/crates/tor-proto/src/client.rs
@@ -198,7 +198,7 @@ impl ClientTunnel {
/// NOTE that the Instant returned by this method is not affected by
/// any runtime mocking; it is the output of an ordinary call to
/// `Instant::now()`.
- pub async fn disused_since(&self) -> Result<Option<std::time::Instant>> {
+ pub async fn disused_since(&self) -> Result<Option<web_time_compat::Instant>> {
self.circ.disused_since().await
}
diff --git a/crates/tor-proto/src/client/channel/handshake.rs b/crates/tor-proto/src/client/channel/handshake.rs
index 48a594c45..a0130458e 100644
--- a/crates/tor-proto/src/client/channel/handshake.rs
+++ b/crates/tor-proto/src/client/channel/handshake.rs
@@ -93,7 +93,7 @@ impl<
/// the relay's handshake information.
///
/// Takes a function that reports the current time. In theory, this can just be
- /// `SystemTime::now()`.
+ /// `SystemTime::get()`.
#[instrument(skip_all, level = "trace")]
pub async fn connect<F>(mut self, now_fn: F) -> Result<UnverifiedClientChannel<T, S>>
where
diff --git a/crates/tor-proto/src/client/circuit.rs b/crates/tor-proto/src/client/circuit.rs
index bbd333b17..8ae369d2f 100644
--- a/crates/tor-proto/src/client/circuit.rs
+++ b/crates/tor-proto/src/client/circuit.rs
@@ -69,6 +69,7 @@ use tor_error::{bad_api_usage, internal, into_internal};
use tor_linkspec::{CircTarget, LinkSpecType, OwnedChanTarget, RelayIdType};
use tor_protover::named;
use tor_rtcompat::DynTimeProvider;
+use web_time_compat::Instant;
use crate::circuit::UniqId;
@@ -488,8 +489,8 @@ impl ClientCirc {
///
/// NOTE that the Instant returned by this method is not affected by
/// any runtime mocking; it is the output of an ordinary call to
- /// `Instant::now()`.
- pub async fn disused_since(&self) -> Result<Option<std::time::Instant>> {
+ /// `Instant::get()`.
+ pub async fn disused_since(&self) -> Result<Option<Instant>> {
let (tx, rx) = oneshot::channel();
self.command
.unbounded_send(CtrlCmd::GetTunnelActivity { sender: tx })
diff --git a/crates/tor-proto/src/client/circuit/padding/maybenot_padding.rs b/crates/tor-proto/src/client/circuit/padding/maybenot_padding.rs
index 449ae8caf..c24a79154 100644
--- a/crates/tor-proto/src/client/circuit/padding/maybenot_padding.rs
+++ b/crates/tor-proto/src/client/circuit/padding/maybenot_padding.rs
@@ -31,7 +31,7 @@ use backend::PaddingBackend;
/// The type of Instant that we'll use for our padding machines.
///
/// We use a separate type alias here in case we want to move to coarsetime.
-type Instant = std::time::Instant;
+type Instant = web_time_compat::Instant;
/// The type of Duration that we'll use for our padding machines.
///
diff --git a/crates/tor-proto/src/client/circuit/padding/maybenot_padding/backend.rs b/crates/tor-proto/src/client/circuit/padding/maybenot_padding/backend.rs
index 903db79ad..66b52793a 100644
--- a/crates/tor-proto/src/client/circuit/padding/maybenot_padding/backend.rs
+++ b/crates/tor-proto/src/client/circuit/padding/maybenot_padding/backend.rs
@@ -24,6 +24,7 @@ use std::{sync::Arc, task::Waker};
use maybenot::{MachineId, TriggerEvent};
use smallvec::SmallVec;
+use web_time_compat::InstantExt;
use super::{Bypass, Duration, Instant, PerHopPaddingEvent, PerHopPaddingEventVec, Replace};
@@ -341,7 +342,8 @@ impl<const N: usize> MaybenotPadder<N> {
rules.machines.clone(),
rules.max_outbound_padding_frac,
rules.max_outbound_blocking_frac,
- Instant::now(),
+ // TODO #2428 PADDING: We should be taking this from a SleepProvider!
+ Instant::get(),
ThisThreadRng,
)?;
Ok(Self::from_framework(framework))
diff --git a/crates/tor-proto/src/client/reactor/circuit.rs b/crates/tor-proto/src/client/reactor/circuit.rs
index 9bd4a7083..331e8ca02 100644
--- a/crates/tor-proto/src/client/reactor/circuit.rs
+++ b/crates/tor-proto/src/client/reactor/circuit.rs
@@ -52,6 +52,7 @@ use tor_error::{Bug, internal};
use tor_linkspec::RelayIds;
use tor_llcrypto::pk;
use tor_memquota::mq_queue::{ChannelSpec as _, MpscSpec};
+use web_time_compat::{Duration, Instant, SystemTime};
use futures::SinkExt as _;
use oneshot_fused_workaround as oneshot;
@@ -69,7 +70,6 @@ use std::borrow::Borrow;
use std::pin::Pin;
use std::result::Result as StdResult;
use std::sync::Arc;
-use std::time::{Duration, Instant, SystemTime};
use extender::HandshakeAuxDataHandler;
diff --git a/crates/tor-proto/src/client/reactor/circuit/circhop.rs b/crates/tor-proto/src/client/reactor/circuit/circhop.rs
index fc6b90404..d2b72a38d 100644
--- a/crates/tor-proto/src/client/reactor/circuit/circhop.rs
+++ b/crates/tor-proto/src/client/reactor/circuit/circhop.rs
@@ -27,6 +27,7 @@ use tor_cell::relaycell::{
AnyRelayMsgOuter, RelayCellDecoder, RelayCellDecoderResult, RelayCellFormat, StreamId,
UnparsedRelayMsg,
};
+use web_time_compat::Instant;
use safelog::sensitive as sv;
use tor_error::Bug;
@@ -35,7 +36,6 @@ use tracing::instrument;
use std::result::Result as StdResult;
use std::sync::{Arc, Mutex, MutexGuard};
use std::task::Poll;
-use std::time::Instant;
#[cfg(test)]
use tor_cell::relaycell::msg::SendmeTag;
diff --git a/crates/tor-proto/src/congestion/rtt.rs b/crates/tor-proto/src/congestion/rtt.rs
index 14b939f5b..ac04112f3 100644
--- a/crates/tor-proto/src/congestion/rtt.rs
+++ b/crates/tor-proto/src/congestion/rtt.rs
@@ -3,7 +3,7 @@
use std::cmp::{max, min};
use std::collections::VecDeque;
use std::sync::atomic::{AtomicBool, Ordering};
-use std::time::{Duration, Instant};
+use web_time_compat::{Duration, Instant};
use super::params::RoundTripEstimatorParams;
use super::{CongestionWindow, State};
@@ -269,7 +269,7 @@ mod test {
#![allow(clippy::needless_pass_by_value)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
- use std::time::{Duration, Instant};
+ use web_time_compat::{Duration, Instant, InstantExt};
use crate::congestion::test_utils::{new_cwnd, new_rtt_estimator};
@@ -333,7 +333,7 @@ mod test {
#[test]
fn test_vectors() {
let mut rtt = new_rtt_estimator();
- let now = Instant::now();
+ let now = Instant::get();
// from C-tor src/test/test_congestion_control.c
let vectors = [
[100000, 200000, 124, 1, 100000, 100000, 100000],
diff --git a/crates/tor-proto/src/congestion/vegas.rs b/crates/tor-proto/src/congestion/vegas.rs
index 0ad46deef..e0f2af68a 100644
--- a/crates/tor-proto/src/congestion/vegas.rs
+++ b/crates/tor-proto/src/congestion/vegas.rs
@@ -343,11 +343,9 @@ pub(crate) mod test {
#![allow(clippy::needless_pass_by_value)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
- use std::{
- collections::VecDeque,
- time::{Duration, Instant},
- };
+ use std::collections::VecDeque;
use tor_units::Percentage;
+ use web_time_compat::{Duration, Instant, InstantExt};
use super::*;
use crate::congestion::{
@@ -433,7 +431,7 @@ pub(crate) mod test {
self.vegas.set_inflight(p.inflight_in);
self.vegas.set_is_blocked_on_chan(p.or_conn_blocked_in);
- let now = Instant::now();
+ let now = Instant::get();
self.rtt
.expect_sendme(now + Duration::from_micros(p.sent_usec_in));
let ret = self.rtt.update(
diff --git a/crates/tor-proto/src/relay/channel/handshake.rs b/crates/tor-proto/src/relay/channel/handshake.rs
index dda1d2602..748d4a177 100644
--- a/crates/tor-proto/src/relay/channel/handshake.rs
+++ b/crates/tor-proto/src/relay/channel/handshake.rs
@@ -108,7 +108,7 @@ impl<
/// Connect to another relay as the relay Initiator.
///
/// Takes a function that reports the current time. In theory, this can just be
- /// `SystemTime::now()`.
+ /// `SystemTime::get()`.
pub async fn connect<F>(mut self, now_fn: F) -> Result<UnverifiedInitiatorRelayChannel<T, S>>
where
F: FnOnce() -> SystemTime,
@@ -237,7 +237,7 @@ impl<
/// Begin the handshake process.
///
/// Takes a function that reports the current time. In theory, this can just be
- /// `SystemTime::now()`.
+ /// `SystemTime::get()`.
pub async fn handshake<F>(
mut self,
now_fn: F,
diff --git a/crates/tor-proto/src/relay/channel/responder.rs b/crates/tor-proto/src/relay/channel/responder.rs
index 4633e641b..09e55def7 100644
--- a/crates/tor-proto/src/relay/channel/responder.rs
+++ b/crates/tor-proto/src/relay/channel/responder.rs
@@ -8,7 +8,7 @@
use digest::Digest;
use futures::{AsyncRead, AsyncWrite};
use safelog::{MaybeSensitive, Sensitive};
-use std::{net::IpAddr, ops::Deref, sync::Arc, time::SystemTime};
+use std::{net::IpAddr, ops::Deref, sync::Arc};
use subtle::ConstantTimeEq;
use tracing::instrument;
@@ -16,6 +16,7 @@ use tor_cell::chancell::msg;
use tor_linkspec::{OwnedChanTarget, RelayIds};
use tor_llcrypto as ll;
use tor_rtcompat::{CertifiedConn, CoarseTimeProvider, SleepProvider, StreamOps};
+use web_time_compat::{SystemTime, SystemTimeExt};
use crate::{
ClockSkew, Error, RelayIdentities, Result,
@@ -132,7 +133,7 @@ where
let initiator_auth_cell = self.auth_cell;
let my_addrs = self.my_addrs;
- let now = now.unwrap_or_else(SystemTime::now);
+ let now = now.unwrap_or_else(SystemTime::get);
// We are a client initiating a channel to a relay or a bridge. We have received a CERTS
// cell and we need to verify these certs:
diff --git a/crates/tor-proto/src/streammap.rs b/crates/tor-proto/src/streammap.rs
index 0840e4608..82b6d1b27 100644
--- a/crates/tor-proto/src/streammap.rs
+++ b/crates/tor-proto/src/streammap.rs
@@ -22,8 +22,8 @@ use std::collections::hash_map;
use std::num::NonZeroU16;
use std::pin::Pin;
use std::task::{Poll, Waker};
-use std::time::Instant;
use tor_error::{bad_api_usage, internal};
+use web_time_compat::Instant;
use rand::Rng;
@@ -590,6 +590,7 @@ mod test {
use crate::client::circuit::test::fake_mpsc;
use crate::stream::queue::fake_stream_queue;
use crate::{client::stream::OutboundDataCmdChecker, congestion::sendme::StreamSendWindow};
+ use web_time_compat::InstantExt;
#[test]
fn test_wrapping_next_stream_id() {
@@ -650,7 +651,7 @@ mod test {
// Test terminate
use TerminateReason as TR;
- let expiry = Instant::now(); // dummy value, unused outside of the reactor
+ let expiry = Instant::get(); // dummy value, unused outside of the reactor
assert!(map.terminate(nonesuch_id, TR::ExplicitEnd, expiry).is_err());
assert_eq!(map.n_open_streams(), 127);
assert_eq!(
diff --git a/crates/tor-proto/src/util/skew.rs b/crates/tor-proto/src/util/skew.rs
index a75d51e57..6648cda46 100644
--- a/crates/tor-proto/src/util/skew.rs
+++ b/crates/tor-proto/src/util/skew.rs
@@ -161,10 +161,11 @@ mod test {
use super::*;
use tor_basic_utils::test_rng::testing_rng;
+ use web_time_compat::SystemTimeExt;
#[test]
fn make_skew() {
- let now = SystemTime::now();
+ let now = SystemTime::get();
let later = now + Duration::from_secs(777);
let earlier = now - Duration::from_secs(333);
let window = Duration::from_secs(30);
diff --git a/crates/tor-proto/src/util/token_bucket/bucket.rs b/crates/tor-proto/src/util/token_bucket/bucket.rs
index ff39b1fe6..2e58f5cbe 100644
--- a/crates/tor-proto/src/util/token_bucket/bucket.rs
+++ b/crates/tor-proto/src/util/token_bucket/bucket.rs
@@ -1,7 +1,7 @@
//! A token bucket implementation.
use std::fmt::Debug;
-use std::time::{Duration, Instant};
+use web_time_compat::{Duration, Instant};
/// A token bucket.
///
diff --git a/crates/tor-proto/src/util/token_bucket/writer.rs b/crates/tor-proto/src/util/token_bucket/writer.rs
index 9e5b05ab6..6fd6d3eb5 100644
--- a/crates/tor-proto/src/util/token_bucket/writer.rs
+++ b/crates/tor-proto/src/util/token_bucket/writer.rs
@@ -4,7 +4,7 @@ use std::future::Future;
use std::num::NonZero;
use std::pin::Pin;
use std::task::{Context, Poll};
-use std::time::{Duration, Instant};
+use web_time_compat::{Duration, Instant};
use futures::AsyncWrite;
use futures::io::Error;
@@ -26,7 +26,9 @@ pub(crate) struct RateLimitedWriter<W: AsyncWrite, P: SleepProvider> {
///
/// While we use [`Instant`] for the time, we should always get the time from this
/// [`SleepProvider`].
- /// For example, use [`SleepProvider::now()`], not [`Instant::now()`].
+ /// For example, use [`SleepProvider::now()`],
+ /// not [`Instant::now()`](std::time::Instant::now) or
+ /// [`InstantExt::get`](web_time_compat::InstantExt::get).
#[educe(Debug(ignore))]
sleep_provider: P,
/// See [`RateLimitedWriterConfig::wake_when_bytes_available`].
diff --git a/crates/tor-proto/src/util/tunnel_activity.rs b/crates/tor-proto/src/util/tunnel_activity.rs
index 62307fd0c..a51bb71e4 100644
--- a/crates/tor-proto/src/util/tunnel_activity.rs
+++ b/crates/tor-proto/src/util/tunnel_activity.rs
@@ -1,7 +1,8 @@
//! Helpers for tracking whether a tunnel or circuit is still active.
use derive_deftly::Deftly;
-use std::{num::NonZeroUsize, time::Instant};
+use std::num::NonZeroUsize;
+use web_time_compat::{Instant, InstantExt};
/// An object to track whether a tunnel or circuit should still be considered active.
///
@@ -132,7 +133,7 @@ impl TunnelActivity {
*n_open_streams = new_value;
} else {
self.inner = Inner::Disused {
- since: Instant::now(),
+ since: Instant::get(),
};
}
}
@@ -154,7 +155,7 @@ impl TunnelActivity {
///
/// # A note about time
///
- /// The returned Instant value is a direct result of an earlier call to `Instant::now()`.
+ /// The returned Instant value is a direct result of an earlier call to `Instant::get()`.
/// It is not affected by any runtime mocking.
pub(crate) fn disused_since(&self) -> Option<Instant> {
match self.inner {
@@ -189,7 +190,7 @@ mod test {
#[test]
fn ordering() {
use Inner::*;
- let t1 = Instant::now();
+ let t1 = Instant::get();
let t2 = t1 + Duration::new(60, 0);
let t3 = t2 + Duration::new(120, 0);
let sorted = vec![
diff --git a/crates/tor-ptmgr/Cargo.toml b/crates/tor-ptmgr/Cargo.toml
index 1c76a0b37..dbfda0855 100644
--- a/crates/tor-ptmgr/Cargo.toml
+++ b/crates/tor-ptmgr/Cargo.toml
@@ -59,6 +59,7 @@ tor-rtcompat = { version = "0.40.0", path = "../tor-rtcompat" }
tor-socksproto = { version = "0.40.0", path = "../tor-socksproto" }
tracing = "0.1.36"
visibility = { version = "0.1.0", optional = true }
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
[dev-dependencies]
anyhow = "1.0.23"
diff --git a/crates/tor-ptmgr/src/ipc.rs b/crates/tor-ptmgr/src/ipc.rs
index 62fb5d1e6..08f553145 100644
--- a/crates/tor-ptmgr/src/ipc.rs
+++ b/crates/tor-ptmgr/src/ipc.rs
@@ -19,7 +19,6 @@ use std::path::PathBuf;
use std::process::{Child, Command, Stdio};
use std::str::FromStr;
use std::sync::Arc;
-use std::time::{Duration, Instant};
use std::{io, thread};
use tor_basic_utils::PathExt as _;
use tor_error::{internal, warn_report};
@@ -27,6 +26,7 @@ use tor_linkspec::PtTransportName;
use tor_rtcompat::{Runtime, SleepProviderExt};
use tor_socksproto::SocksVersion;
use tracing::{debug, error, info, trace, warn};
+use web_time_compat::{Duration, Instant, InstantExt};
/// Amount of time we give a pluggable transport child process to exit gracefully.
const GRACEFUL_EXIT_TIME: Duration = Duration::from_secs(5);
@@ -601,7 +601,7 @@ pub(crate) mod sealed {
match rt
.timeout(
// FIXME(eta): It'd be nice if SleepProviderExt took an `Instant` natively.
- deadline.saturating_duration_since(Instant::now()),
+ deadline.saturating_duration_since(Instant::get()),
async_child.recv(),
)
.await
@@ -916,7 +916,7 @@ impl PluggableClientTransport {
all_env_vars,
)?;
- let deadline = Instant::now() + self.common_params.timeout.unwrap_or(PT_START_TIMEOUT);
+ let deadline = Instant::get() + self.common_params.timeout.unwrap_or(PT_START_TIMEOUT);
let mut cmethods = HashMap::new();
let mut proxy_done = self.client_params.proxy_uri.is_none();
@@ -1070,7 +1070,7 @@ impl PluggableServerTransport {
all_env_vars,
)?;
- let deadline = Instant::now() + self.common_params.timeout.unwrap_or(PT_START_TIMEOUT);
+ let deadline = Instant::get() + self.common_params.timeout.unwrap_or(PT_START_TIMEOUT);
let mut smethods = HashMap::new();
loop {
diff --git a/crates/tor-relay-crypto/Cargo.toml b/crates/tor-relay-crypto/Cargo.toml
index 282fe0bdb..ad35fcfde 100644
--- a/crates/tor-relay-crypto/Cargo.toml
+++ b/crates/tor-relay-crypto/Cargo.toml
@@ -34,6 +34,7 @@ tor-key-forge = { path = "../tor-key-forge", version = "0.40.0" }
tor-keymgr = { path = "../tor-keymgr", version = "0.40.0", features = ["experimental-api"] }
tor-llcrypto = { path = "../tor-llcrypto", version = "0.40.0" }
tor-persist = { path = "../tor-persist", version = "0.40.0" }
+web-time-compat = { path = "../web-time-compat", version = "0.1.0" }
[dev-dependencies]
tor-keymgr = { version = "0.40.0", path = "../tor-keymgr", features = ["testing"] }
diff --git a/crates/tor-relay-crypto/src/certs.rs b/crates/tor-relay-crypto/src/certs.rs
index 7dc80e220..69f2d0299 100644
--- a/crates/tor-relay-crypto/src/certs.rs
+++ b/crates/tor-relay-crypto/src/certs.rs
@@ -1,11 +1,10 @@
//! Certificate related types and functions for an arti relay.
-use std::time::SystemTime;
-
use tor_cert::{CertEncodeError, CertType, CertifiedKey, Ed25519Cert, EncodedEd25519Cert};
use tor_checkable::{SelfSigned, Timebound};
use tor_key_forge::{InvalidCertError, ParsedEd25519Cert, ToEncodableCert};
use tor_llcrypto::pk::ed25519::{self, Ed25519Identity};
+use web_time_compat::{SystemTime, SystemTimeExt};
use crate::pk::{RelayIdentityKeypair, RelayLinkSigningKeypair, RelaySigningKeypair};
@@ -113,7 +112,7 @@ impl ToEncodableCert<RelaySigningKeypair> for RelaySigningKeyCert {
signed_with: &Self::SigningKey,
) -> Result<Self, InvalidCertError> {
// TODO: take the time/time provider as an arg?
- let now = SystemTime::now();
+ let now = SystemTime::get();
validate_ed25519_cert(
cert,
&subject.public().into(),
@@ -140,7 +139,7 @@ impl ToEncodableCert<RelayLinkSigningKeypair> for RelayLinkSigningKeyCert {
signed_with: &Self::SigningKey,
) -> Result<Self, InvalidCertError> {
// TODO: take the time/time provider as an arg?
- let now = SystemTime::now();
+ let now = SystemTime::get();
validate_ed25519_cert(
cert,
&subject.public().into(),
diff --git a/crates/tor-relay-crypto/src/pk.rs b/crates/tor-relay-crypto/src/pk.rs
index 5302b8813..d2980cd5f 100644
--- a/crates/tor-relay-crypto/src/pk.rs
+++ b/crates/tor-relay-crypto/src/pk.rs
@@ -2,7 +2,6 @@
//! KeyMgr so some of them can be stored on disk.
use std::fmt;
-use std::time::SystemTime;
use derive_deftly::Deftly;
use derive_more::Constructor;
@@ -15,6 +14,7 @@ use tor_keymgr::{
derive_deftly_template_CertSpecifier, derive_deftly_template_KeySpecifier,
};
use tor_persist::slug::{Slug, timestamp::Iso8601TimeSlug};
+use web_time_compat::SystemTime;
define_ed25519_keypair!(
/// [KP_relayid_ed] Long-term identity keypair. Never rotates.
diff --git a/crates/tor-rtcompat/Cargo.toml b/crates/tor-rtcompat/Cargo.toml
index e8b980209..2682ccfc0 100644
--- a/crates/tor-rtcompat/Cargo.toml
+++ b/crates/tor-rtcompat/Cargo.toml
@@ -107,6 +107,7 @@ tor-error = { version = "0.40.0", path = "../tor-error", features = ["tracing"]
tor-general-addr = { version = "0.40.0", path = "../tor-general-addr" }
tracing = "0.1.36"
void = "1"
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
zeroize = "1"
[target.'cfg(not(all(target_arch="wasm32", target_os="unknown")))'.dependencies]
diff --git a/crates/tor-rtcompat/src/compound.rs b/crates/tor-rtcompat/src/compound.rs
index 715d40a65..041eccf49 100644
--- a/crates/tor-rtcompat/src/compound.rs
+++ b/crates/tor-rtcompat/src/compound.rs
@@ -10,9 +10,9 @@ use educe::Educe;
use futures::{future::FutureObj, task::Spawn};
use std::future::Future;
use std::io::Result as IoResult;
-use std::time::{Instant, SystemTime};
use tor_general_addr::unix;
use tracing::instrument;
+use web_time_compat::{Instant, SystemTime};
/// A runtime made of several parts, each of which implements one trait-group.
///
diff --git a/crates/tor-rtcompat/src/dyn_time.rs b/crates/tor-rtcompat/src/dyn_time.rs
index f6d04c91e..80d46a19f 100644
--- a/crates/tor-rtcompat/src/dyn_time.rs
+++ b/crates/tor-rtcompat/src/dyn_time.rs
@@ -3,7 +3,7 @@
use std::future::Future;
use std::mem::{self, MaybeUninit};
use std::pin::Pin;
-use std::time::{Duration, Instant, SystemTime};
+use web_time_compat::{Duration, Instant, SystemTime};
use dyn_clone::DynClone;
use educe::Educe;
diff --git a/crates/tor-rtcompat/src/lib.rs b/crates/tor-rtcompat/src/lib.rs
index 534275fdb..9d2e2b808 100644
--- a/crates/tor-rtcompat/src/lib.rs
+++ b/crates/tor-rtcompat/src/lib.rs
@@ -438,17 +438,17 @@ mod test {
use std::io::Result as IoResult;
use std::net::SocketAddr;
use std::net::{Ipv4Addr, SocketAddrV4};
- use std::time::{Duration, Instant};
+ use web_time_compat::{Duration, Instant, InstantExt, SystemTimeExt};
// Test "sleep" with a tiny delay, and make sure that at least that
// much delay happens.
fn small_delay<R: ToplevelRuntime>(runtime: &R) -> IoResult<()> {
let rt = runtime.clone();
runtime.block_on(async {
- let i1 = Instant::now();
+ let i1 = Instant::get();
let one_msec = Duration::from_millis(1);
rt.sleep(one_msec).await;
- let i2 = Instant::now();
+ let i2 = Instant::get();
assert!(i2 >= i1 + one_msec);
});
Ok(())
@@ -488,14 +488,14 @@ mod test {
fn tiny_wallclock<R: ToplevelRuntime>(runtime: &R) -> IoResult<()> {
let rt = runtime.clone();
runtime.block_on(async {
- let i1 = Instant::now();
+ let i1 = Instant::get();
let now = runtime.wallclock();
let one_millis = Duration::from_millis(1);
let one_millis_later = now + one_millis;
rt.sleep_until_wallclock(one_millis_later).await;
- let i2 = Instant::now();
+ let i2 = Instant::get();
let newtime = runtime.wallclock();
assert!(newtime >= one_millis_later);
assert!(i2 - i1 >= one_millis);
@@ -687,7 +687,7 @@ mod test {
let mut rng = tor_basic_utils::test_rng::testing_rng();
let tls_cert = tor_cert_x509::TlsKeyAndCert::create(
&mut rng,
- std::time::SystemTime::now(),
+ std::time::SystemTime::get(),
"prospit.example.org",
"derse.example.org",
)
diff --git a/crates/tor-rtcompat/src/scheduler.rs b/crates/tor-rtcompat/src/scheduler.rs
index ef41ea33e..a290e9ff6 100644
--- a/crates/tor-rtcompat/src/scheduler.rs
+++ b/crates/tor-rtcompat/src/scheduler.rs
@@ -7,7 +7,7 @@ use futures::{Stream, StreamExt};
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
-use std::time::{Duration, Instant, SystemTime};
+use web_time_compat::{Duration, Instant, SystemTime};
use pin_project::pin_project;
@@ -267,7 +267,7 @@ mod test {
use crate::{SleepProvider, test_with_all_runtimes};
use futures::FutureExt;
use futures::StreamExt;
- use std::time::{Duration, Instant};
+ use web_time_compat::{Duration, Instant, InstantExt};
#[test]
fn it_fires_immediately() {
@@ -335,7 +335,7 @@ mod test {
let (mut sch, hdl) = TaskSchedule::new(rt);
assert!(sch.next().now_or_never().is_some());
- hdl.fire_at(Instant::now() + Duration::from_millis(100));
+ hdl.fire_at(Instant::get() + Duration::from_millis(100));
assert!(sch.next().now_or_never().is_none());
assert!(sch.next().await.is_some());
@@ -354,7 +354,7 @@ mod test {
let (mut sch, hdl) = TaskSchedule::new(rt.clone());
assert!(sch.next().now_or_never().is_some());
- hdl.fire_at(Instant::now() + Duration::from_millis(100));
+ hdl.fire_at(Instant::get() + Duration::from_millis(100));
assert!(sch.next().now_or_never().is_none());
@@ -378,7 +378,7 @@ mod test {
let (mut sch, hdl) = TaskSchedule::new(rt.clone());
assert!(sch.next().now_or_never().is_some());
- hdl.fire_at(Instant::now() + Duration::from_millis(100));
+ hdl.fire_at(Instant::get() + Duration::from_millis(100));
hdl.fire();
assert!(sch.next().now_or_never().is_some());
diff --git a/crates/tor-rtcompat/src/timer.rs b/crates/tor-rtcompat/src/timer.rs
index 26236d6a8..abb055af2 100644
--- a/crates/tor-rtcompat/src/timer.rs
+++ b/crates/tor-rtcompat/src/timer.rs
@@ -6,8 +6,8 @@ use pin_project::pin_project;
use std::{
pin::Pin,
task::{Context, Poll},
- time::{Duration, SystemTime},
};
+use web_time_compat::{Duration, SystemTime};
/// An error value given when a function times out.
///
@@ -207,6 +207,7 @@ mod test {
#![allow(clippy::needless_pass_by_value)]
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
#![allow(clippy::erasing_op)]
+ use web_time_compat::SystemTimeExt;
#[cfg(not(miri))]
use super::*;
@@ -219,7 +220,7 @@ mod test {
}
let minute = Duration::from_secs(60);
let second = Duration::from_secs(1);
- let start = SystemTime::now();
+ let start = SystemTime::get();
let target = start + 30 * minute;
diff --git a/crates/tor-rtcompat/src/traits.rs b/crates/tor-rtcompat/src/traits.rs
index 3ff7b9d05..4ef6b5c71 100644
--- a/crates/tor-rtcompat/src/traits.rs
+++ b/crates/tor-rtcompat/src/traits.rs
@@ -9,8 +9,8 @@ use std::borrow::Cow;
use std::fmt::Debug;
use std::io::{self, Result as IoResult};
use std::net;
-use std::time::{Duration, Instant, SystemTime};
use tor_general_addr::unix;
+use web_time_compat::{Duration, Instant, InstantExt, SystemTime, SystemTimeExt};
#[cfg(feature = "tls-server")]
use tor_cert_x509::TlsKeyAndCert;
@@ -121,14 +121,14 @@ pub trait SleepProvider: Clone + Send + Sync + 'static {
///
/// (This is the same as `Instant::now`, if not running in test mode.)
fn now(&self) -> Instant {
- Instant::now()
+ Instant::get()
}
/// Return the SleepProvider's view of the current wall-clock time.
///
/// (This is the same as `SystemTime::now`, if not running in test mode.)
fn wallclock(&self) -> SystemTime {
- SystemTime::now()
+ SystemTime::get()
}
/// Signify that a test running under mock time shouldn't advance time yet, with a given
diff --git a/crates/tor-rtmock/Cargo.toml b/crates/tor-rtmock/Cargo.toml
index c18abd0bd..58a564f34 100644
--- a/crates/tor-rtmock/Cargo.toml
+++ b/crates/tor-rtmock/Cargo.toml
@@ -33,6 +33,7 @@ tor-rtcompat = { version = "0.40.0", path = "../tor-rtcompat" }
tracing = "0.1.36"
tracing-test = "0.2.4"
void = "1"
+web-time-compat = { version = "0.1.0", path = "../web-time-compat" }
[dev-dependencies]
futures-await-test = "0.3.0"
diff --git a/crates/tor-rtmock/src/simple_time.rs b/crates/tor-rtmock/src/simple_time.rs
index 084716581..2e2da094a 100644
--- a/crates/tor-rtmock/src/simple_time.rs
+++ b/crates/tor-rtmock/src/simple_time.rs
@@ -7,7 +7,7 @@ use std::future::Future;
use std::pin::Pin;
use std::sync::{Arc, Mutex, MutexGuard};
use std::task::{Context, Poll, Waker};
-use std::time::{Duration, Instant, SystemTime};
+use web_time_compat::{Duration, Instant, InstantExt, SystemTime, SystemTimeExt};
use derive_more::AsMut;
use priority_queue::priority_queue::PriorityQueue;
@@ -121,7 +121,7 @@ impl Provider {
/// Like any [`SimpleMockTimeProvider`], the time is frozen and only changes
/// due to calls to `advance`.
pub fn from_real() -> Self {
- Provider::from_wallclock(SystemTime::now())
+ Provider::from_wallclock(SystemTime::get())
}
/// Return a new mock time provider starting at a specified wallclock time
///
@@ -131,7 +131,7 @@ impl Provider {
/// nor can a fixed `Instant` be constructed,
/// so this is usually sufficient for a reproducible test.)
pub fn from_wallclock(wallclock: SystemTime) -> Self {
- Provider::new(Instant::now(), wallclock)
+ Provider::new(Instant::get(), wallclock)
}
/// Advance the simulated time by `d`
@@ -320,7 +320,7 @@ mod test {
FUT: Future<Output = ()>,
{
let sp = Provider::new(
- Instant::now(), // it would have been nice to make this fixed for the test
+ Instant::get(), // it would have been nice to make this fixed for the test
parse_rfc3339("2000-01-01T00:00:00Z").unwrap(),
);
let exec = MockExecutor::new();
diff --git a/crates/tor-rtmock/src/sleep_runtime.rs b/crates/tor-rtmock/src/sleep_runtime.rs
index a9ba811a7..04a5cb74b 100644
--- a/crates/tor-rtmock/src/sleep_runtime.rs
+++ b/crates/tor-rtmock/src/sleep_runtime.rs
@@ -33,7 +33,7 @@ impl<R: Runtime> MockSleepRuntime<R> {
/// Create a new runtime that wraps `runtime`, but overrides
/// its view of time with a [`MockSleepProvider`].
pub fn new(runtime: R) -> Self {
- let sleep = MockSleepProvider::new(SystemTime::now());
+ let sleep = MockSleepProvider::new(SystemTime::get());
MockSleepRuntime { runtime, sleep }
}
diff --git a/crates/tor-rtmock/src/time.rs b/crates/tor-rtmock/src/time.rs
index 56be8c117..e5608ffaa 100644
--- a/crates/tor-rtmock/src/time.rs
+++ b/crates/tor-rtmock/src/time.rs
@@ -20,8 +20,8 @@ use std::{
pin::Pin,
sync::{Arc, Mutex, Weak},
task::{Context, Poll, Waker},
- time::{Duration, Instant, SystemTime},
};
+use web_time_compat::{Duration, Instant, InstantExt, SystemTime};
use futures::Future;
use tracing::trace;
@@ -211,7 +211,7 @@ impl Default for MockSleepProvider {
impl MockSleepProvider {
/// Create a new MockSleepProvider, starting at a given wall-clock time.
pub fn new(wallclock: SystemTime) -> Self {
- let instant = Instant::now();
+ let instant = Instant::get();
let sleepers = BinaryHeap::new();
let core = MockTimeCore::new(instant, wallclock);
let state = SleepSchedule {
@@ -590,10 +590,11 @@ mod test {
//! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
use super::*;
use tor_rtcompat::test_with_all_runtimes;
+ use web_time_compat::SystemTimeExt;
#[test]
fn basics_of_time_travel() {
- let w1 = SystemTime::now();
+ let w1 = SystemTime::get();
let sp = MockSleepProvider::new(w1);
let i1 = sp.now();
assert_eq!(sp.wallclock(), w1);
@@ -615,7 +616,7 @@ mod test {
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
- let sp = MockSleepProvider::new(SystemTime::now());
+ let sp = MockSleepProvider::new(SystemTime::get());
let one_hour = Duration::new(3600, 0);
let (s1, r1) = oneshot::channel();
@@ -626,7 +627,7 @@ mod test {
let b2 = AtomicBool::new(false);
let b3 = AtomicBool::new(false);
- let real_start = Instant::now();
+ let real_start = Instant::get();
futures::join!(
async {
@@ -662,7 +663,7 @@ mod test {
assert!(b1.load(Ordering::SeqCst));
assert!(b2.load(Ordering::SeqCst));
assert!(b3.load(Ordering::SeqCst));
- let real_end = Instant::now();
+ let real_end = Instant::get();
assert!(real_end - real_start < one_hour);
}
diff --git a/crates/tor-rtmock/src/time_core.rs b/crates/tor-rtmock/src/time_core.rs
index 98ac5b9eb..35fdb60ef 100644
--- a/crates/tor-rtmock/src/time_core.rs
+++ b/crates/tor-rtmock/src/time_core.rs
@@ -1,9 +1,9 @@
//! [`MockTimeCore`] and [`MockCoarseTimeProvider`]
use derive_deftly::{Deftly, define_derive_deftly};
-use std::time::{Duration, Instant, SystemTime};
use tor_rtcompat::{CoarseDuration, CoarseInstant};
use tor_rtcompat::{CoarseTimeProvider, RealCoarseTimeProvider};
+use web_time_compat::{Duration, Instant, SystemTime};
define_derive_deftly! {
/// Derive getters for struct fields.
diff --git a/crates/tor-rtmock/src/util.rs b/crates/tor-rtmock/src/util.rs
index 0245cb5ce..6c5b77cd0 100644
--- a/crates/tor-rtmock/src/util.rs
+++ b/crates/tor-rtmock/src/util.rs
@@ -190,11 +190,11 @@ pub(crate) mod impl_runtime_prelude {
pub(crate) use futures::task::{FutureObj, Spawn, SpawnError};
pub(crate) use std::io::Result as IoResult;
pub(crate) use std::net::SocketAddr;
- pub(crate) use std::time::{Duration, Instant, SystemTime};
pub(crate) use tor_rtcompat::{
Blocking, CoarseInstant, CoarseTimeProvider, NetStreamProvider, Runtime, SleepProvider,
TlsProvider, ToplevelBlockOn, UdpProvider, unimpl::FakeListener, unimpl::FakeStream,
};
+ pub(crate) use web_time_compat::{Duration, Instant, SystemTime, SystemTimeExt};
}
/// Wrapper for `futures::channel::mpsc::channel` that embodies the `#[allow]`
diff --git a/crates/tor-rtmock/tests/rtcompat_timing.rs b/crates/tor-rtmock/tests/rtcompat_timing.rs
index 6d74f3b1c..f88cb65f5 100644
--- a/crates/tor-rtmock/tests/rtcompat_timing.rs
+++ b/crates/tor-rtmock/tests/rtcompat_timing.rs
@@ -22,7 +22,7 @@ use tor_rtmock::time::MockSleepProvider;
use futures::FutureExt;
use oneshot_fused_workaround as oneshot;
use std::sync::atomic::{AtomicBool, Ordering};
-use std::time::{Duration, SystemTime};
+use web_time_compat::{Duration, SystemTime, SystemTimeExt};
#[test]
fn timeouts() {
@@ -31,7 +31,7 @@ fn timeouts() {
oneshot::Sender<()>,
Timeout<oneshot::Receiver<()>, tor_rtmock::time::Sleeping>,
) {
- let start = SystemTime::now();
+ let start = SystemTime::get();
let (send, recv) = oneshot::channel::<()>();
let mock_sp = MockSleepProvider::new(start);
let ten_min = Duration::new(10 * 60, 0);
diff --git a/crates/web-time-compat/Cargo.toml b/crates/web-time-compat/Cargo.toml
new file mode 100644
index 000000000..3b4f4118a
--- /dev/null
+++ b/crates/web-time-compat/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+name = "web-time-compat"
+version = "0.1.0"
+authors = ["The Tor Project, Inc.", "Nick Mathewson <[email protected]>"]
+edition = "2024"
+rust-version = "1.89"
+license = "MIT OR Apache-2.0"
+homepage = "https://gitlab.torproject.org/tpo/core/arti/-/wikis/home"
+description = "Compatibility layer for web-time"
+keywords = ["js", "wasm", "time"]
+# We must put *something* here and this will do
+categories = ["rust-patterns"]
+repository = "https://gitlab.torproject.org/tpo/core/arti.git/"
+[package.metadata.docs.rs]
+all-features = true
+
+[features]
+default = []
+full = []
+
+[dependencies]
+
+[dev-dependencies]
+
+[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
+web-time = "1.1.0"
diff --git a/crates/web-time-compat/README.md b/crates/web-time-compat/README.md
new file mode 100644
index 000000000..9acc3de82
--- /dev/null
+++ b/crates/web-time-compat/README.md
@@ -0,0 +1,37 @@
+# web-time-compat
+
+Small compatibility layer for [`web-time`].
+
+Unlike [`web-time`], this crate does not require you to stop using
+[`std::time::SystemTime`].
+Instead, it provides an extension trait to replace the `now`
+method of `SystemTime` types with a `get` method that works on
+wasm32-unknown-unknown.
+
+With `Instant`, it isn't possible to continue using `std::time::Instant`,
+since that type is not interconvertible with `web_time::Instant`. Instead,
+we provide an extension trait to make it easier for you to make sure that you
+are only using the version of Instant you want.
+
+## How to use this crate
+
+(This isn't the only way, but it's what we recommend.)
+
+- Replace all references to `std::time::Instant` with `web_time_compat::Instant`.
+- You may, if you like, also use `web_time_compat::{Duration, SystemTime}`.
+ They are just aliases for the standard Duration and SystemTimetypes.
+- Instead of `SystemTime::now()`, use `SystemTimeExt::get()`.
+- Instead of `Instant::now()`, use `Instant::get()`.
+- Add `std::time::SystemTime::now` and `std::time::Instant::now` to your
+ [`disallowed-methods`] list in your `clippy.toml` file,
+ to prevent them from being used accidentally.
+- If you use any other time libraries (such as `time` or `chrono`), you may
+ want to add their "now" methods to `disallowed-methods`, depending
+ on whether you have configured them for wasm compatibility.
+
+[`web-time`]: https://docs.rs/web-time/latest/web_time/
+[`disallowed-methods`]: https://doc.rust-lang.org/stable/clippy/lint_configuration.html#disallowed-methods
+
+----
+
+License: MIT OR Apache-2.0
diff --git a/crates/web-time-compat/src/lib.rs b/crates/web-time-compat/src/lib.rs
new file mode 100644
index 000000000..31abd17f5
--- /dev/null
+++ b/crates/web-time-compat/src/lib.rs
@@ -0,0 +1,112 @@
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![doc = include_str!("../README.md")]
+// @@ begin lint list maintained by maint/add_warning @@
+#![allow(renamed_and_removed_lints)] // @@REMOVE_WHEN(ci_arti_stable)
+#![allow(unknown_lints)] // @@REMOVE_WHEN(ci_arti_nightly)
+#![warn(missing_docs)]
+#![warn(noop_method_call)]
+#![warn(unreachable_pub)]
+#![warn(clippy::all)]
+#![deny(clippy::await_holding_lock)]
+#![deny(clippy::cargo_common_metadata)]
+#![deny(clippy::cast_lossless)]
+#![deny(clippy::checked_conversions)]
+#![warn(clippy::cognitive_complexity)]
+#![deny(clippy::debug_assert_with_mut_call)]
+#![deny(clippy::exhaustive_enums)]
+#![deny(clippy::exhaustive_structs)]
+#![deny(clippy::expl_impl_clone_on_copy)]
+#![deny(clippy::fallible_impl_from)]
+#![deny(clippy::implicit_clone)]
+#![deny(clippy::large_stack_arrays)]
+#![warn(clippy::manual_ok_or)]
+#![deny(clippy::missing_docs_in_private_items)]
+#![warn(clippy::needless_borrow)]
+#![warn(clippy::needless_pass_by_value)]
+#![warn(clippy::option_option)]
+#![deny(clippy::print_stderr)]
+#![deny(clippy::print_stdout)]
+#![warn(clippy::rc_buffer)]
+#![deny(clippy::ref_option_ref)]
+#![warn(clippy::semicolon_if_nothing_returned)]
+#![warn(clippy::trait_duplication_in_bounds)]
+#![deny(clippy::unchecked_time_subtraction)]
+#![deny(clippy::unnecessary_wraps)]
+#![warn(clippy::unseparated_literal_suffix)]
+#![deny(clippy::unwrap_used)]
+#![deny(clippy::mod_module_files)]
+#![allow(clippy::let_unit_value)] // This can reasonably be done for explicitness
+#![allow(clippy::uninlined_format_args)]
+#![allow(clippy::significant_drop_in_scrutinee)] // arti/-/merge_requests/588/#note_2812945
+#![allow(clippy::result_large_err)] // temporary workaround for arti#587
+#![allow(clippy::needless_raw_string_hashes)] // complained-about code is fine, often best
+#![allow(clippy::needless_lifetimes)] // See arti#1765
+#![allow(mismatched_lifetime_syntaxes)] // temporary workaround for arti#2060
+#![allow(clippy::collapsible_if)] // See arti#2342
+#![deny(clippy::unused_async)]
+//! <!-- @@ end lint list maintained by maint/add_warning @@ -->
+
+// We always use `SystemTime` for our data representation outside of this crate.
+//
+// The only time that we touch `SystemTime` is when we are constructing it with
+// `SystemTimeExt::get`.
+pub use std::time::SystemTime;
+
+// "Duration" is the same type in web_time as it is in stdlib.
+pub use std::time::Duration;
+
+#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
+mod stdlib;
+
+#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
+pub use stdlib::*;
+
+#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
+mod wasm;
+
+#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
+pub use wasm::*;
+
+/// Module to hide "Sealed"
+mod seal {
+ /// Trait used to prevent implementing InstantExt or SystemTimeExt outside of this crate.
+ #[allow(unreachable_pub)]
+ pub trait Sealed {}
+}
+
+/// Extension trait for [`std::time::SystemTime`]
+///
+/// This trait adds a `get` method which works like `now`,
+/// but also supports `wasm32-unknown-unknown` environments.
+pub trait SystemTimeExt: seal::Sealed {
+ /// Return the current time.
+ fn get() -> std::time::SystemTime;
+}
+
+/// Extension trait for [`Instant`].
+///
+/// This trait adds a `get` method which works like `now`,
+/// so we can make sure we aren't calling [`std::time::Instant::now`]
+/// on`wasm32-unknown-unknown` environments.
+///
+/// ## Design note
+///
+/// Since we already replace the `std::time::Instant` type with
+/// `web_time::Instant` in this crate, why do we also provide
+/// an extension trait to rename its "now" method?
+///
+/// We do so for two reasons:
+///
+/// 1. Consistency. With this approach, you don't have to remember
+/// which type uses `get` and which uses `now`.
+/// 2. Enforcement. This approach makes it possible to use Clippy
+/// to disallow `std::time::Instant::now()` unconditionally,
+/// to make sure that you don't forget to use
+/// the appropriate `web_time_compat::Instant` type instead.
+pub trait InstantExt: seal::Sealed {
+ /// Return the current time.
+ fn get() -> crate::Instant;
+}
+
+impl seal::Sealed for std::time::SystemTime {}
+impl seal::Sealed for crate::Instant {}
diff --git a/crates/web-time-compat/src/stdlib.rs b/crates/web-time-compat/src/stdlib.rs
new file mode 100644
index 000000000..891a0e0f7
--- /dev/null
+++ b/crates/web-time-compat/src/stdlib.rs
@@ -0,0 +1,21 @@
+//! Standard-library time functionality..
+
+// If we've forbidden `now` elsewhere in our project, we enable it here.
+// (And only here!)
+#![allow(clippy::disallowed_methods)]
+
+pub use std::time::Instant;
+
+use std::time::SystemTime;
+
+impl crate::SystemTimeExt for SystemTime {
+ fn get() -> SystemTime {
+ SystemTime::now()
+ }
+}
+
+impl crate::InstantExt for Instant {
+ fn get() -> crate::Instant {
+ Instant::now()
+ }
+}
diff --git a/crates/web-time-compat/src/wasm.rs b/crates/web-time-compat/src/wasm.rs
new file mode 100644
index 000000000..37d2198ce
--- /dev/null
+++ b/crates/web-time-compat/src/wasm.rs
@@ -0,0 +1,20 @@
+//! Wasm-specific time functionality.
+
+// If we've forbidden `now` elsewhere in our project, we enable it here.
+#![allow(clippy::disallowed_methods)]
+
+pub use web_time::Instant;
+
+impl crate::SystemTimeExt for std::time::SystemTime {
+ fn get() -> std::time::SystemTime {
+ use web_time::web::SystemTimeExt as _;
+ let now = web_time::SystemTime::now();
+ now.to_std()
+ }
+}
+
+impl crate::InstantExt for Instant {
+ fn get() -> crate::Instant {
+ Instant::now()
+ }
+}