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 01771122017..47f0621683c 100755 --- a/ci/ci-tests.sh +++ b/ci/ci-tests.sh @@ -30,11 +30,33 @@ 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" +# When the workspace members change, make sure to update the list here as well +# as in `Cargo.toml`. +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 @@ -80,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 @@ -95,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/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-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/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 } 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 }