Add a crate which wraps `getrandom` but always compiles
authorMatt Corallo <git@bluematt.me>
Mon, 12 Feb 2024 22:37:09 +0000 (22:37 +0000)
committerMatt Corallo <git@bluematt.me>
Fri, 16 Feb 2024 20:34:40 +0000 (20:34 +0000)
In the next commit we'll drop the `ahash` dependency in favor of
directly calling `getrandom` to seed our hash tables. However,
we'd like to depend on `getrandom` only on certain platforms *and*
only when certain features (no-std) are set.

This introduces an indirection crate to do so, allowing us to
depend on it only when `no-std` is set but only depending on
`getrandom` on platforms which it supports.

Cargo.toml
ci/check-cfg-flags.py
no-std-check/Cargo.toml
possiblyrandom/Cargo.toml [new file with mode: 0644]
possiblyrandom/src/lib.rs [new file with mode: 0644]

index ddc82cd5d4564cc4299004c797709587c878e291..ec9edb3ac33076af7833898f9c5347db4f34fda5 100644 (file)
@@ -11,6 +11,7 @@ members = [
     "lightning-rapid-gossip-sync",
     "lightning-custom-message",
     "lightning-transaction-sync",
+    "possiblyrandom",
 ]
 
 exclude = [
@@ -38,3 +39,6 @@ lto = "off"
 opt-level = 3
 lto = true
 panic = "abort"
+
+[patch.crates-io.possiblyrandom]
+path = "possiblyrandom"
index d6e8e0a90feff9862aaaccbe56271673d25b834d..8952b693a60d35c8b34391151d8c7a75051d719e 100755 (executable)
@@ -15,6 +15,8 @@ def check_feature(feature):
         pass
     elif feature == "ahash":
         pass
+    elif feature == "getrandom":
+        pass
     elif feature == "hashbrown":
         pass
     elif feature == "backtrace":
index c9d404c922f86012b87e1b961ca451e60c49e0bb..45a70c2a6d1bc15e457a8f4929a492c206ede102 100644 (file)
@@ -15,3 +15,6 @@ lightning-background-processor = { path = "../lightning-background-processor", f
 # Obviously lightning-transaction-sync doesn't support no-std, but it should build
 # even if lightning is built with no-std.
 lightning-transaction-sync = { path = "../lightning-transaction-sync", optional = true }
+
+[patch.crates-io]
+possiblyrandom = { path = "../possiblyrandom" }
diff --git a/possiblyrandom/Cargo.toml b/possiblyrandom/Cargo.toml
new file mode 100644 (file)
index 0000000..e02b596
--- /dev/null
@@ -0,0 +1,21 @@
+[package]
+name = "possiblyrandom"
+version = "0.1.0"
+authors = ["Matt Corallo"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/lightningdevkit/rust-lightning/"
+description = """
+A crate that wraps getrandom and always compiles, returning 0s when no randomness is available.
+"""
+edition = "2021"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
+
+[dependencies]
+getrandom = { version = "0.2", optional = true, default-features = false }
+
+# Enable getrandom if we are on a platform that (likely) supports it
+[target.'cfg(not(any(target_os = "unknown", target_os = "none")))'.dependencies]
+getrandom = { version = "0.2", default-features = false }
diff --git a/possiblyrandom/src/lib.rs b/possiblyrandom/src/lib.rs
new file mode 100644 (file)
index 0000000..9cbbad7
--- /dev/null
@@ -0,0 +1,35 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+//! [`getrandom`] provides access to OS randomness, but will fail to compile on platforms that do
+//! not support fetching OS randomness. This is exactly what you want when you're doing
+//! cryptographic operations, but when you're just opportunistically randomizing, we're fine with
+//! compiling and simply disabling randomization.
+//!
+//! This crate does that, returning only possibly-random data.
+//!
+//! Note that this crate only enables getrandom on a subset of platforms it supports. As getrandom
+//! evolves this crate is unlikely to carefully track all getrandom-supported platforms, however
+//! will use random data on popular platforms.
+
+#![no_std]
+
+#[cfg(feature = "getrandom")]
+extern crate getrandom;
+
+/// Possibly fills `dest` with random data. May fill it with zeros.
+#[inline]
+pub fn getpossiblyrandom(dest: &mut [u8]) {
+       #[cfg(feature = "getrandom")]
+       if getrandom::getrandom(dest).is_err() {
+               dest.fill(0);
+       }
+       #[cfg(not(feature = "getrandom"))]
+       dest.fill(0);
+}