From 7ae3a50a324fd7b7e5a3ad637c2dde2b3e891451 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Fri, 13 Sep 2024 13:14:40 +0200 Subject: [PATCH] Drop `no-std` feature We drop the `lightning/no-std` feature and just take `hashbrown`,`possiblyrandom` and `libm` as required dependencies. --- .github/workflows/build.yml | 7 --- README.md | 2 +- bench/Cargo.toml | 3 -- bench/README.md | 3 -- ci/ci-tests.sh | 14 +++--- fuzz/Cargo.toml | 2 +- lightning-rapid-gossip-sync/src/lib.rs | 4 +- lightning/Cargo.toml | 7 ++- lightning/src/lib.rs | 4 -- lightning/src/ln/channelmanager.rs | 4 +- lightning/src/offers/invoice_request.rs | 2 +- lightning/src/offers/refund.rs | 2 +- lightning/src/routing/gossip.rs | 16 +++---- lightning/src/routing/scoring.rs | 2 +- lightning/src/util/hash_tables.rs | 60 ++----------------------- lightning/src/util/test_utils.rs | 2 +- no-std-check/Cargo.toml | 2 +- 17 files changed, 31 insertions(+), 105 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58b2e299539..29c4209a50c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -149,16 +149,11 @@ jobs: run: | cd lightning RUSTFLAGS="--cfg=require_route_graph_test" cargo test - RUSTFLAGS="--cfg=require_route_graph_test" cargo test --features hashbrown cd .. - name: Run benchmarks on Rust ${{ matrix.toolchain }} run: | cd bench RUSTFLAGS="--cfg=ldk_bench --cfg=require_route_graph_test" cargo bench - - name: Run benchmarks with hashbrown on Rust ${{ matrix.toolchain }} - run: | - cd bench - RUSTFLAGS="--cfg=ldk_bench --cfg=require_route_graph_test" cargo bench --features hashbrown check_commits: runs-on: ubuntu-latest @@ -199,13 +194,11 @@ jobs: - name: Run cargo check for release build. run: | cargo check --release - cargo check --no-default-features --features=no-std --release cargo check --no-default-features --features=futures,std --release cargo doc --release - name: Run cargo check for Taproot build. run: | cargo check --release - cargo check --no-default-features --features=no-std --release cargo check --no-default-features --features=futures,std --release cargo doc --release env: diff --git a/README.md b/README.md index f77910b7a51..a0721e41407 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Crates ----------- 1. [lightning](./lightning) The core of the LDK library, implements the Lightning protocol, channel state machine, - and on-chain logic. Supports `no-std` and exposes only relatively low-level interfaces. + and on-chain logic. Supports `no_std` and exposes only relatively low-level interfaces. 2. [lightning-background-processor](./lightning-background-processor) Utilities to perform required background tasks for Rust Lightning. 3. [lightning-block-sync](./lightning-block-sync) diff --git a/bench/Cargo.toml b/bench/Cargo.toml index 05354890c2a..5bf14377917 100644 --- a/bench/Cargo.toml +++ b/bench/Cargo.toml @@ -8,9 +8,6 @@ edition = "2021" name = "bench" harness = false -[features] -hashbrown = ["lightning/hashbrown"] - [dependencies] lightning = { path = "../lightning", features = ["_test_utils", "criterion"] } lightning-persister = { path = "../lightning-persister", features = ["criterion"] } diff --git a/bench/README.md b/bench/README.md index 7d4cacc9e87..03f6cb6ca0b 100644 --- a/bench/README.md +++ b/bench/README.md @@ -1,6 +1,3 @@ This crate uses criterion to benchmark various LDK functions. It can be run as `RUSTFLAGS=--cfg=ldk_bench cargo bench`. - -For routing or other HashMap-bottlenecked functions, the `hashbrown` feature -should also be benchmarked. diff --git a/ci/ci-tests.sh b/ci/ci-tests.sh index 92068f7cc33..e82c1a0cefd 100755 --- a/ci/ci-tests.sh +++ b/ci/ci-tests.sh @@ -100,14 +100,12 @@ grep '^max_level_' lightning/Cargo.toml | awk '{ print $1 }'| while read -r FEAT RUSTFLAGS="$RUSTFLAGS -A unused_variables -A unused_macros -A unused_imports -A dead_code" cargo check -p lightning --verbose --color always --features "$FEATURE" done -echo -e "\n\nTesting no-std builds" +echo -e "\n\nTesting no_std builds" for DIR in lightning-invoice lightning-rapid-gossip-sync; do cargo test -p $DIR --verbose --color always --no-default-features done -cargo test -p lightning --verbose --color always --no-default-features --features no-std -# check if there is a conflict between no-std and the default std feature -cargo test -p lightning --verbose --color always --features no-std +cargo test -p lightning --verbose --color always --no-default-features echo -e "\n\nTesting c_bindings builds" # Note that because `$RUSTFLAGS` is not passed through to doctest builds we cannot selectively @@ -115,23 +113,23 @@ echo -e "\n\nTesting c_bindings builds" RUSTFLAGS="$RUSTFLAGS --cfg=c_bindings" cargo test --verbose --color always --lib --bins --tests for DIR in lightning-invoice lightning-rapid-gossip-sync; do - # check if there is a conflict between no-std and the c_bindings cfg + # check if there is a conflict between no_std and the c_bindings cfg RUSTFLAGS="$RUSTFLAGS --cfg=c_bindings" cargo test -p $DIR --verbose --color always --no-default-features done # Note that because `$RUSTFLAGS` is not passed through to doctest builds we cannot selectively # disable doctests in `c_bindings` so we skip doctests entirely here. RUSTFLAGS="$RUSTFLAGS --cfg=c_bindings" cargo test -p lightning-background-processor --verbose --color always --features futures --no-default-features --lib --bins --tests -RUSTFLAGS="$RUSTFLAGS --cfg=c_bindings" cargo test -p lightning --verbose --color always --no-default-features --features=no-std --lib --bins --tests +RUSTFLAGS="$RUSTFLAGS --cfg=c_bindings" cargo test -p lightning --verbose --color always --no-default-features --lib --bins --tests echo -e "\n\nTesting other crate-specific builds" # Note that outbound_commitment_test only runs in this mode because of hardcoded signature values RUSTFLAGS="$RUSTFLAGS --cfg=ldk_test_vectors" cargo test -p lightning --verbose --color always --no-default-features --features=std # This one only works for lightning-invoice -# check that compile with no-std and serde works in lightning-invoice +# check that compile with no_std and serde works in lightning-invoice cargo test -p lightning-invoice --verbose --color always --no-default-features --features serde -echo -e "\n\nTesting no-std build on a downstream no-std crate" +echo -e "\n\nTesting no_std build on a downstream no-std crate" # check no-std compatibility across dependencies pushd no-std-check cargo check --verbose --color always --features lightning-transaction-sync diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 666474f5366..02b808f2383 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -18,7 +18,7 @@ libfuzzer_fuzz = ["libfuzzer-sys"] stdin_fuzz = [] [dependencies] -lightning = { path = "../lightning", features = ["regex", "hashbrown", "_test_utils"] } +lightning = { path = "../lightning", features = ["regex", "_test_utils"] } lightning-invoice = { path = "../lightning-invoice" } lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" } bech32 = "0.9.1" diff --git a/lightning-rapid-gossip-sync/src/lib.rs b/lightning-rapid-gossip-sync/src/lib.rs index 2bae65cb8e8..30da8caf505 100644 --- a/lightning-rapid-gossip-sync/src/lib.rs +++ b/lightning-rapid-gossip-sync/src/lib.rs @@ -54,8 +54,8 @@ //! let network_graph = NetworkGraph::new(Network::Bitcoin, &logger); //! let rapid_sync = RapidGossipSync::new(&network_graph, &logger); //! let snapshot_contents: &[u8] = &[0; 0]; -//! // In no-std you need to provide the current time in unix epoch seconds -//! // otherwise you can use update_network_graph +//! // In non-`std` environments you need to provide the current time in unix epoch seconds +//! // otherwise you can use `update_network_graph` //! let current_time_unix = 0; //! let new_last_sync_timestamp_result = rapid_sync.update_network_graph_no_std(snapshot_contents, Some(current_time_unix)); //! ``` diff --git a/lightning/Cargo.toml b/lightning/Cargo.toml index 8fa85f7a2fb..3a1939733a6 100644 --- a/lightning/Cargo.toml +++ b/lightning/Cargo.toml @@ -29,7 +29,6 @@ max_level_trace = [] # This is unsafe to use in production because it may result in the counterparty publishing taking our funds. unsafe_revoked_tx_signing = [] -no-std = ["hashbrown", "possiblyrandom", "libm"] std = [] # Generates low-r bitcoin signatures, which saves 1 byte in 50% of the cases @@ -44,12 +43,12 @@ lightning-invoice = { version = "0.32.0", path = "../lightning-invoice", default bech32 = { version = "0.9.1", default-features = false } bitcoin = { version = "0.32.2", default-features = false, features = ["secp-recovery"] } -hashbrown = { version = "0.13", optional = true, default-features = false } -possiblyrandom = { version = "0.2", path = "../possiblyrandom", optional = true, default-features = false } +hashbrown = { version = "0.13", default-features = false } +possiblyrandom = { version = "0.2", path = "../possiblyrandom", default-features = false } regex = { version = "1.5.6", optional = true } backtrace = { version = "0.3", optional = true } -libm = { version = "0.2", optional = true, default-features = false } +libm = { version = "0.2", default-features = false } [dev-dependencies] regex = "1.5.6" diff --git a/lightning/src/lib.rs b/lightning/src/lib.rs index 95953e6a033..106a8fdd677 100644 --- a/lightning/src/lib.rs +++ b/lightning/src/lib.rs @@ -28,7 +28,6 @@ //! //! * `std` //! * `grind_signatures` -//! * `no-std ` - exposes write trait implementations from the `core2` crate (at least one of `no-std` or `std` are required) //! * Skip logging of messages at levels below the given log level: //! * `max_level_off` //! * `max_level_error` @@ -53,9 +52,6 @@ #![cfg_attr(all(not(feature = "std"), not(test)), no_std)] -#[cfg(not(any(feature = "std", feature = "no-std")))] -compile_error!("at least one of the `std` or `no-std` features must be enabled"); - #[cfg(all(fuzzing, test))] compile_error!("Tests will always fail with cfg=fuzzing"); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 6414d8a2836..35069632515 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -5920,7 +5920,7 @@ where /// * Forgetting about stale outbound payments, either those that have already been fulfilled /// or those awaiting an invoice that hasn't been delivered in the necessary amount of time. /// The latter is determined using the system clock in `std` and the highest seen block time - /// minus two hours in `no-std`. + /// minus two hours in non-`std`. /// /// Note that this may cause reentrancy through [`chain::Watch::update_channel`] calls or feerate /// estimate fetches. @@ -8942,7 +8942,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => { /// See [Avoiding Duplicate Payments] for other requirements once the payment has been sent. /// /// The builder will have the provided expiration set. Any changes to the expiration on the - /// returned builder will not be honored by [`ChannelManager`]. For `no-std`, the highest seen + /// returned builder will not be honored by [`ChannelManager`]. For non-`std`, the highest seen /// block time minus two hours is used for the current time when determining if the refund has /// expired. /// diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index fa3d9161b82..a623f1a0c30 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -719,7 +719,7 @@ macro_rules! invoice_request_respond_with_explicit_signing_pubkey_methods { ( /// Creates an [`InvoiceBuilder`] for the request with the given required fields. /// /// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after - /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. Useful for `no-std` builds + /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. Useful for non-`std` builds /// where [`std::time::SystemTime`] is not available. /// /// The caller is expected to remember the preimage of `payment_hash` in order to claim a payment diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index c07055c5c10..211e46015f2 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -545,7 +545,7 @@ macro_rules! respond_with_explicit_signing_pubkey_methods { ($self: ident, $buil /// Creates an [`InvoiceBuilder`] for the refund with the given required fields. /// /// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after - /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. Useful for `no-std` builds + /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. Useful for non-`std` builds /// where [`std::time::SystemTime`] is not available. /// /// The caller is expected to remember the preimage of `payment_hash` in order to diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 4bcb8b859c6..17434e4cba5 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -183,7 +183,7 @@ pub struct NetworkGraph where L::Target: Logger { // // NOTE: In the following `removed_*` maps, we use seconds since UNIX epoch to track time instead // of `std::time::Instant`s for a few reasons: - // * We want it to be possible to do tracking in no-std environments where we can compare + // * We want it to be possible to do tracking in non-`std` environments where we can compare // a provided current UNIX timestamp with the time at which we started tracking. // * In the future, if we decide to persist these maps, they will already be serializable. // * Although we lose out on the platform's monotonic clock, the system clock in a std @@ -612,7 +612,7 @@ where U::Target: UtxoLookup, L::Target: Logger // our peers and never receiving gossip from peers at all, we send all of our peers a // `gossip_timestamp_filter`, with the filter time set either two weeks ago or an hour ago. // - // For no-std builds, we bury our head in the sand and do a full sync on each connection. + // For non-`std` builds, we bury our head in the sand and do a full sync on each connection. #[allow(unused_mut, unused_assignments)] let mut gossip_start_time = 0; #[allow(unused)] @@ -934,7 +934,7 @@ pub struct ChannelInfo { /// Not stored if contains excess data to prevent DoS. pub announcement_message: Option, /// The timestamp when we received the announcement, if we are running with feature = "std" - /// (which we can probably assume we are - no-std environments probably won't have a full + /// (which we can probably assume we are - non-`std` environments probably won't have a full /// network graph in memory!). announcement_received_time: u64, } @@ -2105,7 +2105,7 @@ impl NetworkGraph where L::Target: Logger { /// in the map for a while so that these can be resynced from gossip in the future. /// /// This method is only available with the `std` feature. See - /// [`NetworkGraph::remove_stale_channels_and_tracking_with_time`] for `no-std` use. + /// [`NetworkGraph::remove_stale_channels_and_tracking_with_time`] for non-`std` use. pub fn remove_stale_channels_and_tracking(&self) { let time = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time must be > 1970").as_secs(); self.remove_stale_channels_and_tracking_with_time(time); @@ -2169,7 +2169,7 @@ impl NetworkGraph where L::Target: Logger { if let Some(time) = time { current_time_unix.saturating_sub(*time) < REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS } else { - // NOTE: In the case of no-std, we won't have access to the current UNIX time at the time of removal, + // NOTE: In the case of non-`std`, we won't have access to the current UNIX time at the time of removal, // so we'll just set the removal time here to the current UNIX time on the very next invocation // of this function. #[cfg(not(feature = "std"))] @@ -2193,7 +2193,7 @@ impl NetworkGraph where L::Target: Logger { /// [`RoutingMessageHandler`] implementation to call it indirectly. This may be useful to accept /// routing messages from a source using a protocol other than the lightning P2P protocol. /// - /// If built with `no-std`, any updates with a timestamp more than two weeks in the past or + /// If not built with `std`, any updates with a timestamp more than two weeks in the past or /// materially in the future will be rejected. pub fn update_channel(&self, msg: &msgs::ChannelUpdate) -> Result<(), LightningError> { self.update_channel_internal(&msg.contents, Some(&msg), Some(&msg.signature), false) @@ -2203,7 +2203,7 @@ impl NetworkGraph where L::Target: Logger { /// of the channel without verifying the associated signatures. Because we aren't given the /// associated signatures here we cannot relay the channel update to any of our peers. /// - /// If built with `no-std`, any updates with a timestamp more than two weeks in the past or + /// If not built with `std`, any updates with a timestamp more than two weeks in the past or /// materially in the future will be rejected. pub fn update_channel_unsigned(&self, msg: &msgs::UnsignedChannelUpdate) -> Result<(), LightningError> { self.update_channel_internal(msg, None, None, false) @@ -2213,7 +2213,7 @@ impl NetworkGraph where L::Target: Logger { /// /// This checks whether the update currently is applicable by [`Self::update_channel`]. /// - /// If built with `no-std`, any updates with a timestamp more than two weeks in the past or + /// If not built with `std`, any updates with a timestamp more than two weeks in the past or /// materially in the future will be rejected. pub fn verify_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result<(), LightningError> { self.update_channel_internal(&msg.contents, Some(&msg), Some(&msg.signature), true) diff --git a/lightning/src/routing/scoring.rs b/lightning/src/routing/scoring.rs index d40b1f22c40..b27a9f97b02 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -749,7 +749,7 @@ pub struct ProbabilisticScoringDecayParameters { /// /// # Note /// - /// When built with the `no-std` feature, time will never elapse. Therefore, the channel + /// When not built with the `std` feature, time will never elapse. Therefore, the channel /// liquidity knowledge will never decay except when the bounds cross. pub liquidity_offset_half_life: Duration, } diff --git a/lightning/src/util/hash_tables.rs b/lightning/src/util/hash_tables.rs index 6c3d1ec42cb..2d98cb88b9d 100644 --- a/lightning/src/util/hash_tables.rs +++ b/lightning/src/util/hash_tables.rs @@ -1,67 +1,13 @@ -//! Generally LDK uses `std`'s `HashMap`s, however when building for no-std, LDK uses `hashbrown`'s -//! `HashMap`s with the `std` `SipHasher` and uses `getrandom` to opportunistically randomize it, -//! if randomization is available. +//! Generally LDK uses `hashbrown`'s `HashMap`s with the `std` `SipHasher` and uses `getrandom` to +//! opportunistically randomize it, if randomization is available. //! //! This module simply re-exports the `HashMap` used in LDK for public consumption. -#[cfg(feature = "hashbrown")] extern crate hashbrown; -#[cfg(feature = "possiblyrandom")] extern crate possiblyrandom; -// For no-std builds, we need to use hashbrown, however, by default, it doesn't randomize the -// hashing and is vulnerable to HashDoS attacks. Thus, we use the core SipHasher when not using -// std, but use `getrandom` to randomize it if its available. - -#[cfg(not(feature = "hashbrown"))] -mod std_hashtables { - pub use std::collections::hash_map::RandomState; - pub use std::collections::HashMap; - - pub(crate) use std::collections::{hash_map, HashSet}; - - pub(crate) type OccupiedHashMapEntry<'a, K, V> = - std::collections::hash_map::OccupiedEntry<'a, K, V>; - pub(crate) type VacantHashMapEntry<'a, K, V> = - std::collections::hash_map::VacantEntry<'a, K, V>; - - /// Builds a new [`HashMap`]. - pub fn new_hash_map() -> HashMap { - HashMap::new() - } - /// Builds a new [`HashMap`] with the given capacity. - pub fn hash_map_with_capacity(cap: usize) -> HashMap { - HashMap::with_capacity(cap) - } - pub(crate) fn hash_map_from_iter< - K: core::hash::Hash + Eq, - V, - I: IntoIterator, - >( - iter: I, - ) -> HashMap { - HashMap::from_iter(iter) - } - - pub(crate) fn new_hash_set() -> HashSet { - HashSet::new() - } - pub(crate) fn hash_set_with_capacity(cap: usize) -> HashSet { - HashSet::with_capacity(cap) - } - pub(crate) fn hash_set_from_iter>( - iter: I, - ) -> HashSet { - HashSet::from_iter(iter) - } -} -#[cfg(not(feature = "hashbrown"))] -pub use std_hashtables::*; - -#[cfg(feature = "hashbrown")] pub(crate) use self::hashbrown::hash_map; -#[cfg(feature = "hashbrown")] mod hashbrown_tables { #[cfg(feature = "std")] mod hasher { @@ -170,5 +116,5 @@ mod hashbrown_tables { res } } -#[cfg(feature = "hashbrown")] + pub use hashbrown_tables::*; diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index e41ba359b3b..e5d2b1d9c58 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -1053,7 +1053,7 @@ impl msgs::RoutingMessageHandler for TestRoutingMessageHandler { #[allow(unused_mut, unused_assignments)] let mut gossip_start_time = 0; - #[cfg(not(feature = "no-std"))] + #[cfg(feature = "std")] { use std::time::{SystemTime, UNIX_EPOCH}; gossip_start_time = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time must be > 1970").as_secs(); diff --git a/no-std-check/Cargo.toml b/no-std-check/Cargo.toml index a94939eab48..bc43e63404a 100644 --- a/no-std-check/Cargo.toml +++ b/no-std-check/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [features] -default = ["lightning/no-std"] +default = [] [dependencies] lightning = { path = "../lightning", default-features = false }