From 3c1a5d3aa16d1c515eb0de511576ad15ec5064a4 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Wed, 4 Sep 2024 10:53:37 +0200 Subject: [PATCH 1/3] Re-add optional `std` feature dependencies to fix RGS and BP builds We previously removed these, leading to failure to build under default features including `std`. --- lightning-background-processor/Cargo.toml | 4 +++- lightning-rapid-gossip-sync/Cargo.toml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lightning-background-processor/Cargo.toml b/lightning-background-processor/Cargo.toml index 70c19c5c76d..0afc18fdfbb 100644 --- a/lightning-background-processor/Cargo.toml +++ b/lightning-background-processor/Cargo.toml @@ -15,12 +15,14 @@ rustdoc-args = ["--cfg", "docsrs"] [features] futures = [ ] -std = [] +std = ["lightning/std", "bitcoin-io/std", "bitcoin_hashes/std"] default = ["std"] [dependencies] bitcoin = { version = "0.32.2", default-features = false } +bitcoin_hashes = { version = "0.14.0", default-features = false } +bitcoin-io = { version = "0.1.2", default-features = false } lightning = { version = "0.0.124", path = "../lightning", default-features = false } lightning-rapid-gossip-sync = { version = "0.0.124", path = "../lightning-rapid-gossip-sync", default-features = false } diff --git a/lightning-rapid-gossip-sync/Cargo.toml b/lightning-rapid-gossip-sync/Cargo.toml index ef28f294378..03efbde3daa 100644 --- a/lightning-rapid-gossip-sync/Cargo.toml +++ b/lightning-rapid-gossip-sync/Cargo.toml @@ -11,11 +11,13 @@ Utility to process gossip routing data from Rapid Gossip Sync Server. [features] default = ["std"] -std = [] +std = ["bitcoin-io/std", "bitcoin_hashes/std"] [dependencies] lightning = { version = "0.0.124", path = "../lightning", default-features = false } bitcoin = { version = "0.32.2", default-features = false } +bitcoin_hashes = { version = "0.14.0", default-features = false } +bitcoin-io = { version = "0.1.2", default-features = false } [target.'cfg(ldk_bench)'.dependencies] criterion = { version = "0.4", optional = true, default-features = false } From a06e7b9133e0731766eba495ac049f27859d56a3 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Wed, 4 Sep 2024 11:10:13 +0200 Subject: [PATCH 2/3] Check workspace members with default features individually in CI Previously, we would only check the workspace as a whole. This however would mean that we would check/test crates with `lightning`'s default features enabled, allowing failures-to-build under the crates own default features to slip through, if they didn't explicitly enable `lightning/std`, for example. Here, we extend the CI to check the workspace as a whole but then run checks, tests, and doc generation on the workspace members individually, asserting that all of them build even when not built as part of the same workspace as `lightning`. --- ci/ci-tests.sh | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/ci/ci-tests.sh b/ci/ci-tests.sh index 01771122017..92068f7cc33 100755 --- a/ci/ci-tests.sh +++ b/ci/ci-tests.sh @@ -30,11 +30,31 @@ PIN_RELEASE_DEPS # pin the release dependencies in our main workspace export RUST_BACKTRACE=1 -echo -e "\n\nBuilding and testing all workspace crates..." -cargo test --verbose --color always +echo -e "\n\nChecking the full workspace." cargo check --verbose --color always -echo -e "\n\nBuilding and testing Block Sync Clients with features" +WORKSPACE_MEMBERS=( + lightning + lightning-types + lightning-block-sync + lightning-invoice + lightning-net-tokio + lightning-persister + lightning-background-processor + lightning-rapid-gossip-sync + lightning-custom-message + lightning-transaction-sync + possiblyrandom +) + +echo -e "\n\nChecking, testing, and building docs for all workspace members individually..." +for DIR in "${WORKSPACE_MEMBERS[@]}"; do + cargo test -p "$DIR" --verbose --color always + cargo check -p "$DIR" --verbose --color always + cargo doc -p "$DIR" --document-private-items +done + +echo -e "\n\nChecking and testing Block Sync Clients with features" cargo test -p lightning-block-sync --verbose --color always --features rest-client cargo check -p lightning-block-sync --verbose --color always --features rest-client From 545b037827ca18d475a82320e32ae00b83f01755 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Fri, 13 Sep 2024 13:14:40 +0200 Subject: [PATCH 3/3] 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 | 9 +-- Cargo.toml | 2 + README.md | 2 +- bench/Cargo.toml | 3 - bench/README.md | 3 - ci/check-compiles.sh | 2 +- ci/ci-tests.sh | 16 +++--- fuzz/Cargo.toml | 2 +- lightning-background-processor/src/lib.rs | 5 +- lightning-rapid-gossip-sync/src/lib.rs | 26 +++++++-- lightning/Cargo.toml | 7 +-- lightning/src/events/mod.rs | 11 ++-- lightning/src/lib.rs | 4 -- lightning/src/ln/channelmanager.rs | 4 +- lightning/src/ln/invoice_utils.rs | 28 +++++---- lightning/src/ln/msgs.rs | 2 +- lightning/src/ln/outbound_payment.rs | 5 +- lightning/src/offers/invoice_macros.rs | 2 +- lightning/src/offers/invoice_request.rs | 13 ++--- lightning/src/offers/offer.rs | 4 +- lightning/src/offers/parse.rs | 2 +- lightning/src/offers/refund.rs | 8 +-- lightning/src/routing/gossip.rs | 22 +++---- lightning/src/routing/scoring.rs | 2 +- lightning/src/util/hash_tables.rs | 70 ++--------------------- lightning/src/util/ser.rs | 6 +- lightning/src/util/ser_macros.rs | 1 + lightning/src/util/test_utils.rs | 2 +- lightning/src/util/wakers.rs | 9 ++- no-std-check/Cargo.toml | 2 +- 30 files changed, 110 insertions(+), 164 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58b2e299539..90275f8192b 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,15 +194,15 @@ 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 --release cargo check --no-default-features --features=futures,std --release cargo doc --release + cargo doc --no-default-features --release env: RUSTFLAGS: '--cfg=taproot' RUSTDOCFLAGS: '--cfg=taproot' diff --git a/Cargo.toml b/Cargo.toml index ae5d1bc8f0c..add69f35afa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,8 @@ [workspace] resolver = "2" +# When the workspace members change, make sure to update the list here as well +# as in `ci/ci-tests.sh`. members = [ "lightning", "lightning-types", 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/check-compiles.sh b/ci/check-compiles.sh index 7ad9f4df196..a067861fb56 100755 --- a/ci/check-compiles.sh +++ b/ci/check-compiles.sh @@ -6,5 +6,5 @@ cargo check cargo doc cargo doc --document-private-items cd fuzz && RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" cargo check --features=stdin_fuzz -cd ../lightning && cargo check --no-default-features --features=no-std +cd ../lightning && cargo check --no-default-features cd .. && RUSTC_BOOTSTRAP=1 RUSTFLAGS="--cfg=c_bindings" cargo check -Z avoid-dev-deps diff --git a/ci/ci-tests.sh b/ci/ci-tests.sh index 92068f7cc33..47f0621683c 100755 --- a/ci/ci-tests.sh +++ b/ci/ci-tests.sh @@ -33,6 +33,8 @@ export RUST_BACKTRACE=1 echo -e "\n\nChecking the full workspace." cargo check --verbose --color always +# When the workspace members change, make sure to update the list here as well +# as in `Cargo.toml`. WORKSPACE_MEMBERS=( lightning lightning-types @@ -100,14 +102,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 +115,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-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index d9dc6518cef..59b68dbfb33 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -1,7 +1,6 @@ //! Utilities that take care of tasks that (1) need to happen periodically to keep Rust-Lightning -//! running properly, and (2) either can or should be run in the background. See docs for -//! [`BackgroundProcessor`] for more details on the nitty-gritty. - +//! running properly, and (2) either can or should be run in the background. +#![cfg_attr(feature = "std", doc = "See docs for [`BackgroundProcessor`] for more details.")] #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] #![deny(missing_docs)] diff --git a/lightning-rapid-gossip-sync/src/lib.rs b/lightning-rapid-gossip-sync/src/lib.rs index 2bae65cb8e8..429a3560be0 100644 --- a/lightning-rapid-gossip-sync/src/lib.rs +++ b/lightning-rapid-gossip-sync/src/lib.rs @@ -35,8 +35,15 @@ //! Note that the first ever rapid sync should use `0` for `last_sync_timestamp`. //! //! After the gossip data snapshot has been downloaded, one of the client's graph processing -//! functions needs to be called. In this example, we process the update by reading its contents -//! from disk, which we do by calling [`RapidGossipSync::update_network_graph`]: +//! functions needs to be called. +#![cfg_attr( + feature = "std", + doc = "In this example, we process the update by reading its contents from disk, which we do by calling [`RapidGossipSync::update_network_graph`]:" +)] +#![cfg_attr( + not(feature = "std"), + doc = "In this example, we process the update by reading its contents from disk, which we do by calling [`RapidGossipSync::update_network_graph_no_std`]:" +)] //! //! ``` //! use bitcoin::constants::genesis_block; @@ -54,10 +61,17 @@ //! 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 -//! let current_time_unix = 0; -//! let new_last_sync_timestamp_result = rapid_sync.update_network_graph_no_std(snapshot_contents, Some(current_time_unix)); +//! // In non-`std` environments you need to provide the current time in unix epoch seconds +//! // otherwise you can use `update_network_graph`: +#![cfg_attr( + feature = "std", + doc = "let new_last_sync_timestamp_result = rapid_sync.update_network_graph(snapshot_contents);" +)] +#![cfg_attr(not(feature = "std"), doc = "let current_time_unix = 0;")] +#![cfg_attr( + not(feature = "std"), + doc = "let new_last_sync_timestamp_result = rapid_sync.update_network_graph_no_std(snapshot_contents, Some(current_time_unix));" +)] //! ``` #![cfg_attr(all(not(feature = "std"), not(test)), no_std)] 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/events/mod.rs b/lightning/src/events/mod.rs index a7cf68dcc1c..fe52d08c9e1 100644 --- a/lightning/src/events/mod.rs +++ b/lightning/src/events/mod.rs @@ -543,12 +543,13 @@ pub enum PaymentFailureReason { /// /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment UserAbandoned, - /// We exhausted all of our retry attempts while trying to send the payment, or we - /// exhausted the [`Retry::Timeout`] if the user set one. If at any point a retry - /// attempt failed while being forwarded along the path, an [`Event::PaymentPathFailed`] will + #[cfg_attr(feature = "std", doc = "We exhausted all of our retry attempts while trying to send the payment, or we")] + #[cfg_attr(feature = "std", doc = "exhausted the [`Retry::Timeout`] if the user set one.")] + #[cfg_attr(not(feature = "std"), doc = "We exhausted all of our retry attempts while trying to send the payment.")] + /// If at any point a retry attempt failed while being forwarded along the path, an [`Event::PaymentPathFailed`] will /// have come before this. - /// - /// [`Retry::Timeout`]: crate::ln::channelmanager::Retry::Timeout + #[cfg_attr(feature = "std", doc = "")] + #[cfg_attr(feature = "std", doc = "[`Retry::Timeout`]: crate::ln::channelmanager::Retry::Timeout")] RetriesExhausted, /// The payment expired while retrying, based on the provided /// [`PaymentParameters::expiry_time`]. 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 03164e04fb5..a7c5ae2da22 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -6042,7 +6042,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. @@ -9064,7 +9064,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/ln/invoice_utils.rs b/lightning/src/ln/invoice_utils.rs index aedac5cb489..287f11df7ec 100644 --- a/lightning/src/ln/invoice_utils.rs +++ b/lightning/src/ln/invoice_utils.rs @@ -61,9 +61,8 @@ use core::iter::Iterator; /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash /// [`PhantomRouteHints::channels`]: crate::ln::channelmanager::PhantomRouteHints::channels /// [`MIN_FINAL_CLTV_EXPIRY_DETLA`]: crate::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA -/// -/// This can be used in a `no_std` environment, where [`std::time::SystemTime`] is not -/// available and the current time is supplied by the caller. +#[cfg_attr(feature = "std", doc = "")] +#[cfg_attr(feature = "std", doc = "This can be used in a `no_std` environment, where [`std::time::SystemTime`] is not available and the current time is supplied by the caller.")] pub fn create_phantom_invoice( amt_msat: Option, payment_hash: Option, description: String, invoice_expiry_delta_secs: u32, phantom_route_hints: Vec, entropy_source: ES, @@ -117,9 +116,8 @@ where /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash /// [`PhantomRouteHints::channels`]: crate::ln::channelmanager::PhantomRouteHints::channels -/// -/// This can be used in a `no_std` environment, where [`std::time::SystemTime`] is not -/// available and the current time is supplied by the caller. +#[cfg_attr(feature = "std", doc = "")] +#[cfg_attr(feature = "std", doc = "This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not available and the current time is supplied by the caller.")] pub fn create_phantom_invoice_with_description_hash( amt_msat: Option, payment_hash: Option, invoice_expiry_delta_secs: u32, description_hash: Sha256, phantom_route_hints: Vec, entropy_source: ES, @@ -399,9 +397,12 @@ where ) } -/// See [`create_invoice_from_channelmanager_with_description_hash`] -/// This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not -/// available and the current time is supplied by the caller. +/// Utility to construct an invoice. Generally, unless you want to do something like a custom +/// `cltv_expiry`, this is what you should be using to create an invoice. +#[cfg_attr(feature = "std", doc = "")] +#[cfg_attr(feature = "std", doc = "See [`create_invoice_from_channelmanager_with_description_hash`] for more information.")] +#[cfg_attr(feature = "std", doc = "")] +#[cfg_attr(feature = "std", doc = "This can be used in a `no_std` environment, where [`std::time::SystemTime`] is not available and the current time is supplied by the caller.")] pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch( channelmanager: &ChannelManager, node_signer: NS, logger: L, network: Currency, amt_msat: Option, description_hash: Sha256, @@ -424,9 +425,12 @@ pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_sin ) } -/// See [`create_invoice_from_channelmanager`] -/// This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not -/// available and the current time is supplied by the caller. +/// Utility to construct an invoice. Generally, unless you want to do something like a custom +/// `cltv_expiry`, this is what you should be using to create an invoice. +#[cfg_attr(feature = "std", doc = "")] +#[cfg_attr(feature = "std", doc = "See [`create_invoice_from_channelmanager`] for more information.")] +#[cfg_attr(feature = "std", doc = "")] +#[cfg_attr(feature = "std", doc = "This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not available and the current time is supplied by the caller.")] pub fn create_invoice_from_channelmanager_and_duration_since_epoch( channelmanager: &ChannelManager, node_signer: NS, logger: L, network: Currency, amt_msat: Option, description: String, duration_since_epoch: Duration, diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 5c536a09dc4..c89274f47d8 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -87,7 +87,7 @@ pub enum DecodeError { ShortRead, /// A length descriptor in the packet didn't describe the later data correctly. BadLengthDescriptor, - /// Error from [`std::io`]. + /// Error from [`crate::io`]. Io(io::ErrorKind), /// The message included zlib-compressed values, which we don't support. UnsupportedCompression, diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index 7a850889d4c..80e7c7ad5c5 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -438,8 +438,9 @@ impl_writeable_tlv_based_enum_legacy!(StaleExpiration, /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed #[derive(Clone, Debug, PartialEq, Eq)] pub enum RetryableSendFailure { - /// The provided [`PaymentParameters::expiry_time`] indicated that the payment has expired. Note - /// that this error is *not* caused by [`Retry::Timeout`]. + /// The provided [`PaymentParameters::expiry_time`] indicated that the payment has expired. + #[cfg_attr(feature = "std", doc = "")] + #[cfg_attr(feature = "std", doc = "Note that this error is *not* caused by [`Retry::Timeout`].")] /// /// [`PaymentParameters::expiry_time`]: crate::routing::router::PaymentParameters::expiry_time PaymentExpired, diff --git a/lightning/src/offers/invoice_macros.rs b/lightning/src/offers/invoice_macros.rs index 3037ccfa803..a24cff3642f 100644 --- a/lightning/src/offers/invoice_macros.rs +++ b/lightning/src/offers/invoice_macros.rs @@ -16,7 +16,7 @@ macro_rules! invoice_builder_methods_common { ( #[doc = concat!("Sets the [`", stringify!($invoice_type), "::relative_expiry`]")] #[doc = concat!("as seconds since [`", stringify!($invoice_type), "::created_at`].")] #[doc = "Any expiry that has already passed is valid and can be checked for using"] - #[doc = concat!("[`", stringify!($invoice_type), "::is_expired`].")] + #[cfg_attr(feature = "std", doc = concat!("[`", stringify!($invoice_type), "::is_expired`]."))] /// /// Successive calls to this method will override the previous setting. pub fn relative_expiry($($self_mut)* $self: $self_type, relative_expiry_secs: u32) -> $return_type { diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index dc2fd4bf1df..838a45db24f 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -615,12 +615,11 @@ pub struct VerifiedInvoiceRequest { /// Keys used for signing a [`Bolt12Invoice`] if they can be derived. /// - /// If `Some`, must call [`respond_using_derived_keys`] when responding. Otherwise, call - /// [`respond_with`]. - /// + #[cfg_attr(feature = "std", doc = "If `Some`, must call [`respond_using_derived_keys`] when responding. Otherwise, call [`respond_with`].")] + #[cfg_attr(feature = "std", doc = "")] /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice - /// [`respond_using_derived_keys`]: Self::respond_using_derived_keys - /// [`respond_with`]: Self::respond_with + #[cfg_attr(feature = "std", doc = "[`respond_using_derived_keys`]: Self::respond_using_derived_keys")] + #[cfg_attr(feature = "std", doc = "[`respond_with`]: Self::respond_with")] pub keys: Option, } @@ -719,8 +718,8 @@ 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 - /// where [`std::time::SystemTime`] is not available. + /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. + #[cfg_attr(feature = "std", doc = "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 /// for the invoice. diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 27a79166bc3..912b2359d90 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -316,8 +316,8 @@ macro_rules! offer_builder_methods { ( $return_value } - /// Sets the [`Offer::absolute_expiry`] as seconds since the Unix epoch. Any expiry that has - /// already passed is valid and can be checked for using [`Offer::is_expired`]. + /// Sets the [`Offer::absolute_expiry`] as seconds since the Unix epoch. + #[cfg_attr(feature = "std", doc = "Any expiry that has already passed is valid and can be checked for using [`Offer::is_expired`].")] /// /// Successive calls to this method will override the previous setting. pub fn absolute_expiry($($self_mut)* $self: $self_type, absolute_expiry: Duration) -> $return_type { diff --git a/lightning/src/offers/parse.rs b/lightning/src/offers/parse.rs index 8b9f64d8b39..3b366e391b6 100644 --- a/lightning/src/offers/parse.rs +++ b/lightning/src/offers/parse.rs @@ -135,7 +135,7 @@ pub enum Bolt12ParseError { /// Error when interpreting a TLV stream as a specific type. #[derive(Clone, Debug, PartialEq)] pub enum Bolt12SemanticError { - /// The current [`std::time::SystemTime`] is past the offer or invoice's expiration. + /// The current system time is past the offer or invoice's expiration. AlreadyExpired, /// The provided chain hash does not correspond to a supported chain. UnsupportedChain, diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index c07055c5c10..36ab9530390 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -231,8 +231,8 @@ macro_rules! refund_builder_methods { ( $return_value } - /// Sets the [`Refund::absolute_expiry`] as seconds since the Unix epoch. Any expiry that has - /// already passed is valid and can be checked for using [`Refund::is_expired`]. + /// Sets the [`Refund::absolute_expiry`] as seconds since the Unix epoch. + #[cfg_attr(feature = "std", doc = "Any expiry that has already passed is valid and can be checked for using [`Refund::is_expired`].")] /// /// Successive calls to this method will override the previous setting. pub fn absolute_expiry($($self_mut)* $self: $self_type, absolute_expiry: Duration) -> $return_type { @@ -545,8 +545,8 @@ 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 - /// where [`std::time::SystemTime`] is not available. + /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. + #[cfg_attr(feature = "std", doc = "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 for the invoice. diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 4bcb8b859c6..afff249f7c5 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); @@ -2121,9 +2121,9 @@ impl NetworkGraph where L::Target: Logger { /// /// This method will also cause us to stop tracking removed nodes and channels if they have been /// in the map for a while so that these can be resynced from gossip in the future. - /// - /// This function takes the current unix time as an argument. For users with the `std` feature - /// enabled, [`NetworkGraph::remove_stale_channels_and_tracking`] may be preferable. + #[cfg_attr(feature = "std", doc = "")] + #[cfg_attr(feature = "std", doc = "This function takes the current unix time as an argument. For users with the `std` feature")] + #[cfg_attr(feature = "std", doc = "enabled, [`NetworkGraph::remove_stale_channels_and_tracking`] may be preferable.")] pub fn remove_stale_channels_and_tracking_with_time(&self, current_time_unix: u64) { let mut channels = self.channels.write().unwrap(); // Time out if we haven't received an update in at least 14 days. @@ -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..3debb42c8f0 100644 --- a/lightning/src/util/hash_tables.rs +++ b/lightning/src/util/hash_tables.rs @@ -1,67 +1,10 @@ -//! 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; +pub(crate) use hashbrown::hash_map; -// 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 { @@ -85,7 +28,7 @@ mod hashbrown_tables { /// target platform. pub fn new() -> RandomState { let (k0, k1); - #[cfg(all(not(fuzzing), feature = "possiblyrandom"))] + #[cfg(not(fuzzing))] { let mut keys = [0; 16]; possiblyrandom::getpossiblyrandom(&mut keys); @@ -97,7 +40,7 @@ mod hashbrown_tables { k0 = u64::from_le_bytes(k0_bytes); k1 = u64::from_le_bytes(k1_bytes); } - #[cfg(any(fuzzing, not(feature = "possiblyrandom")))] + #[cfg(fuzzing)] { k0 = 0; k1 = 0; @@ -120,7 +63,6 @@ mod hashbrown_tables { } } - use super::*; pub use hasher::*; /// The HashMap type used in LDK. @@ -170,5 +112,5 @@ mod hashbrown_tables { res } } -#[cfg(feature = "hashbrown")] + pub use hashbrown_tables::*; diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 1c48463b89f..99d20b927b6 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -50,8 +50,8 @@ use crate::util::string::UntrustedString; /// serialization buffer size pub const MAX_BUF_SIZE: usize = 64 * 1024; -/// A simplified version of [`std::io::Write`] that exists largely for backwards compatibility. -/// An impl is provided for any type that also impls [`std::io::Write`]. +/// A simplified version of `std::io::Write` that exists largely for backwards compatibility. +/// An impl is provided for any type that also impls `std::io::Write`. /// /// This is not exported to bindings users as we only export serialization to/from byte arrays instead pub trait Writer { @@ -173,7 +173,7 @@ impl Writer for LengthCalculatingWriter { } } -/// Essentially [`std::io::Take`] but a bit simpler and with a method to walk the underlying stream +/// Essentially `std::io::Take` but a bit simpler and with a method to walk the underlying stream /// forward to ensure we always consume exactly the fixed length specified. /// /// This is not exported to bindings users as manual TLV building is not currently supported in bindings diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index e56b2d9c68d..178fb947aa1 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -872,6 +872,7 @@ macro_rules! _init_and_read_tlv_stream { /// /// [`Readable`]: crate::util::ser::Readable /// [`Writeable`]: crate::util::ser::Writeable +/// [`Vec`]: crate::prelude::Vec #[macro_export] macro_rules! impl_writeable_tlv_based { ($st: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index a15584c9178..473ad906af6 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -1055,7 +1055,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/lightning/src/util/wakers.rs b/lightning/src/util/wakers.rs index e846ef677b3..a01948f3ea1 100644 --- a/lightning/src/util/wakers.rs +++ b/lightning/src/util/wakers.rs @@ -97,11 +97,10 @@ macro_rules! define_callback { ($($bounds: path),*) => { /// A callback which is called when a [`Future`] completes. /// /// Note that this MUST NOT call back into LDK directly, it must instead schedule actions to be -/// taken later. Rust users should use the [`std::future::Future`] implementation for [`Future`] -/// instead. -/// -/// Note that the [`std::future::Future`] implementation may only work for runtimes which schedule -/// futures when they receive a wake, rather than immediately executing them. +/// taken later. +#[cfg_attr(feature = "std", doc = "Rust users should use the [`std::future::Future`] implementation for [`Future`] instead.")] +#[cfg_attr(feature = "std", doc = "")] +#[cfg_attr(feature = "std", doc = "Note that the [`std::future::Future`] implementation may only work for runtimes which schedule futures when they receive a wake, rather than immediately executing them.")] pub trait FutureCallback : $($bounds +)* { /// The method which is called. fn call(&self); 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 }