From 9e7ab1b9a317debeab643c37b750ddbd8d5bbed2 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Fri, 26 May 2023 12:31:31 +0200 Subject: [PATCH 01/11] Remove commented-out code --- .../ldk-node-android/lib/build.gradle.kts | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/bindings/kotlin/ldk-node-android/lib/build.gradle.kts b/bindings/kotlin/ldk-node-android/lib/build.gradle.kts index 9239d7875..d238482f7 100644 --- a/bindings/kotlin/ldk-node-android/lib/build.gradle.kts +++ b/bindings/kotlin/ldk-node-android/lib/build.gradle.kts @@ -111,23 +111,3 @@ signing { useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) sign(publishing.publications) } - -//tasks.named("test") { -// // Use JUnit Platform for unit tests. -// useJUnitPlatform() -// -// testLogging { -// events(PASSED, SKIPPED, FAILED, STANDARD_OUT, STANDARD_ERROR) -// exceptionFormat = FULL -// showExceptions = true -// showCauses = true -// showStackTraces = true -// showStandardStreams = true -// } -//} - -//// This task dependency ensures that we build the bindings -//// binaries before running the tests -//tasks.withType { -// dependsOn("buildAndroidLib") -//} From adc409b77cb73cb31f1735a1991de4ec5663e7c6 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Fri, 26 May 2023 12:36:44 +0200 Subject: [PATCH 02/11] Update package metadata --- .../ldk-node-android/lib/build.gradle.kts | 9 ++------- .../kotlin/ldk-node-jvm/lib/build.gradle.kts | 17 +++++++---------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/bindings/kotlin/ldk-node-android/lib/build.gradle.kts b/bindings/kotlin/ldk-node-android/lib/build.gradle.kts index d238482f7..922d8e81a 100644 --- a/bindings/kotlin/ldk-node-android/lib/build.gradle.kts +++ b/bindings/kotlin/ldk-node-android/lib/build.gradle.kts @@ -68,7 +68,7 @@ afterEvaluate { pom { name.set("ldk-node-android") description.set( - "LDK Node, a ready-to-go node implementation built using LDK." + "LDK Node, a ready-to-go Lightning node library built using LDK and BDK." ) url.set("https://lightningdevkit.org") licenses { @@ -85,12 +85,7 @@ afterEvaluate { developer { id.set("tnull") name.set("Elias Rohrer") - email.set("tnull@noreply.github.org") - } - developer { - id.set("jurvis") - name.set("Jurvis Tan") - email.set("jurvis@noreply.github.org") + email.set("dev@tnull.de") } } scm { diff --git a/bindings/kotlin/ldk-node-jvm/lib/build.gradle.kts b/bindings/kotlin/ldk-node-jvm/lib/build.gradle.kts index fc272e584..f3724722c 100644 --- a/bindings/kotlin/ldk-node-jvm/lib/build.gradle.kts +++ b/bindings/kotlin/ldk-node-jvm/lib/build.gradle.kts @@ -66,7 +66,7 @@ afterEvaluate { pom { name.set("ldk-node-jvm") description.set( - "LDK Node, a ready-to-go node implementation built using LDK." + "LDK Node, a ready-to-go Lightning node library built using LDK and BDK." ) url.set("https://lightningdevkit.org") licenses { @@ -80,15 +80,12 @@ afterEvaluate { } } developers { - developer { - id.set("tnull") - name.set("Elias Rohrer") - email.set("tnull@noreply.github.org") - } - developer { - id.set("jurvis") - name.set("Jurvis Tan") - email.set("jurvis@noreply.github.org") + developers { + developer { + id.set("tnull") + name.set("Elias Rohrer") + email.set("dev@tnull.de") + } } } scm { From c45c3a3ecb6778e27536a67558a0076295742a2b Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Tue, 30 May 2023 11:11:29 +0200 Subject: [PATCH 03/11] Drop `Node::onchain_balance` from public API We already have `Node::spendable_onchain_balance` and `Node::total_onchain_balance` exposed, so the general `onchain_balance` is kind of redudant. As it is also not exposed (and not easily exposable) in bindings, we can make the bindings and Rust APIs more homogeneous by dropping the call. Plus, we probably should avoid exposing any BDK types in the public API until BDK 1.0 landed and we made the switch, as many breaking changes will be coming with it. --- src/lib.rs | 21 ++++++--------- src/test/functional_tests.rs | 51 ++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 150f6908d..9f4940cd5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -736,9 +736,14 @@ impl Node { Ok(funding_address) } - /// Retrieve the current on-chain balance. - pub fn onchain_balance(&self) -> Result { - self.wallet.get_balance() + /// Retrieve the currently spendable on-chain balance in satoshis. + pub fn spendable_onchain_balance_sats(&self) -> Result { + Ok(self.wallet.get_balance().map(|bal| bal.get_spendable())?) + } + + /// Retrieve the current total on-chain balance in satoshis. + pub fn total_onchain_balance_sats(&self) -> Result { + Ok(self.wallet.get_balance().map(|bal| bal.get_total())?) } /// Send an on-chain payment to the given address. @@ -768,16 +773,6 @@ impl Node { self.wallet.send_to_address(address, None) } - /// Retrieve the currently spendable on-chain balance in satoshis. - pub fn spendable_onchain_balance_sats(&self) -> Result { - Ok(self.wallet.get_balance().map(|bal| bal.get_spendable())?) - } - - /// Retrieve the current total on-chain balance in satoshis. - pub fn total_onchain_balance_sats(&self) -> Result { - Ok(self.wallet.get_balance().map(|bal| bal.get_total())?) - } - /// Retrieve a list of known channels. pub fn list_channels(&self) -> Vec { self.channel_manager.list_channels().into_iter().map(|c| c.into()).collect() diff --git a/src/test/functional_tests.rs b/src/test/functional_tests.rs index 5828d6114..c60a29ddb 100644 --- a/src/test/functional_tests.rs +++ b/src/test/functional_tests.rs @@ -69,8 +69,8 @@ fn do_channel_full_cycle( ); node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); - assert_eq!(node_a.onchain_balance().unwrap().get_spendable(), premine_amount_sat); - assert_eq!(node_b.onchain_balance().unwrap().get_spendable(), premine_amount_sat); + assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), premine_amount_sat); + assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), premine_amount_sat); // Check we haven't got any events yet assert_eq!(node_a.next_event(), None); @@ -116,12 +116,11 @@ fn do_channel_full_cycle( node_b.sync_wallets().unwrap(); let onchain_fee_buffer_sat = 1500; - let node_a_balance = node_a.onchain_balance().unwrap(); let node_a_upper_bound_sat = premine_amount_sat - funding_amount_sat; let node_a_lower_bound_sat = premine_amount_sat - funding_amount_sat - onchain_fee_buffer_sat; - assert!(node_a_balance.get_spendable() < node_a_upper_bound_sat); - assert!(node_a_balance.get_spendable() > node_a_lower_bound_sat); - assert_eq!(node_b.onchain_balance().unwrap().get_spendable(), premine_amount_sat); + assert!(node_a.spendable_onchain_balance_sats().unwrap() < node_a_upper_bound_sat); + assert!(node_a.spendable_onchain_balance_sats().unwrap() > node_a_lower_bound_sat); + assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), premine_amount_sat); expect_event!(node_a, ChannelReady); @@ -254,10 +253,10 @@ fn do_channel_full_cycle( let node_a_upper_bound_sat = (premine_amount_sat - funding_amount_sat) + (funding_amount_sat - sum_of_all_payments_sat); let node_a_lower_bound_sat = node_a_upper_bound_sat - onchain_fee_buffer_sat; - assert!(node_a.onchain_balance().unwrap().get_spendable() > node_a_lower_bound_sat); - assert!(node_a.onchain_balance().unwrap().get_spendable() < node_a_upper_bound_sat); + assert!(node_a.spendable_onchain_balance_sats().unwrap() > node_a_lower_bound_sat); + assert!(node_a.spendable_onchain_balance_sats().unwrap() < node_a_upper_bound_sat); let expected_final_amount_node_b_sat = premine_amount_sat + sum_of_all_payments_sat; - assert_eq!(node_b.onchain_balance().unwrap().get_spendable(), expected_final_amount_node_b_sat); + assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), expected_final_amount_node_b_sat); // Check we handled all events assert_eq!(node_a.next_event(), None); @@ -299,8 +298,8 @@ fn channel_open_fails_when_funds_insufficient() { ); node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); - assert_eq!(node_a.onchain_balance().unwrap().get_spendable(), premine_amount_sat); - assert_eq!(node_b.onchain_balance().unwrap().get_spendable(), premine_amount_sat); + assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), premine_amount_sat); + assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), premine_amount_sat); println!("\nA -- connect_open_channel -> B"); assert_eq!( @@ -342,13 +341,13 @@ fn start_stop_reinit() { let expected_amount = Amount::from_sat(100000); premine_and_distribute_funds(&bitcoind, &electrsd, vec![funding_address], expected_amount); - assert_eq!(node.onchain_balance().unwrap().get_total(), 0); + assert_eq!(node.total_onchain_balance_sats().unwrap(), 0); node.start().unwrap(); assert_eq!(node.start(), Err(Error::AlreadyRunning)); node.sync_wallets().unwrap(); - assert_eq!(node.onchain_balance().unwrap().get_spendable(), expected_amount.to_sat()); + assert_eq!(node.spendable_onchain_balance_sats().unwrap(), expected_amount.to_sat()); let log_file_symlink = format!("{}/logs/ldk_node_latest.log", config.storage_dir_path); assert!(std::path::Path::new(&log_file_symlink).is_symlink()); @@ -371,13 +370,13 @@ fn start_stop_reinit() { reinitialized_node.start().unwrap(); assert_eq!( - reinitialized_node.onchain_balance().unwrap().get_spendable(), + reinitialized_node.spendable_onchain_balance_sats().unwrap(), expected_amount.to_sat() ); reinitialized_node.sync_wallets().unwrap(); assert_eq!( - reinitialized_node.onchain_balance().unwrap().get_spendable(), + reinitialized_node.spendable_onchain_balance_sats().unwrap(), expected_amount.to_sat() ); @@ -398,13 +397,13 @@ fn start_stop_reinit_fs_store() { let expected_amount = Amount::from_sat(100000); premine_and_distribute_funds(&bitcoind, &electrsd, vec![funding_address], expected_amount); - assert_eq!(node.onchain_balance().unwrap().get_total(), 0); + assert_eq!(node.total_onchain_balance_sats().unwrap(), 0); node.start().unwrap(); assert_eq!(node.start(), Err(Error::AlreadyRunning)); node.sync_wallets().unwrap(); - assert_eq!(node.onchain_balance().unwrap().get_spendable(), expected_amount.to_sat()); + assert_eq!(node.spendable_onchain_balance_sats().unwrap(), expected_amount.to_sat()); node.stop().unwrap(); assert_eq!(node.stop(), Err(Error::NotRunning)); @@ -424,13 +423,13 @@ fn start_stop_reinit_fs_store() { reinitialized_node.start().unwrap(); assert_eq!( - reinitialized_node.onchain_balance().unwrap().get_spendable(), + reinitialized_node.spendable_onchain_balance_sats().unwrap(), expected_amount.to_sat() ); reinitialized_node.sync_wallets().unwrap(); assert_eq!( - reinitialized_node.onchain_balance().unwrap().get_spendable(), + reinitialized_node.spendable_onchain_balance_sats().unwrap(), expected_amount.to_sat() ); @@ -465,7 +464,7 @@ fn onchain_spend_receive() { node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); - assert_eq!(node_b.onchain_balance().unwrap().get_spendable(), 100000); + assert_eq!(node_b.spendable_onchain_balance_sats().unwrap(), 100000); assert_eq!(Err(Error::InsufficientFunds), node_a.send_to_onchain_address(&addr_b, 1000)); @@ -476,9 +475,9 @@ fn onchain_spend_receive() { node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); - assert_eq!(node_a.onchain_balance().unwrap().get_spendable(), 1000); - assert!(node_b.onchain_balance().unwrap().get_spendable() > 98000); - assert!(node_b.onchain_balance().unwrap().get_spendable() < 100000); + assert_eq!(node_a.spendable_onchain_balance_sats().unwrap(), 1000); + assert!(node_b.spendable_onchain_balance_sats().unwrap() > 98000); + assert!(node_b.spendable_onchain_balance_sats().unwrap() < 100000); let addr_b = node_b.new_funding_address().unwrap(); let txid = node_a.send_all_to_onchain_address(&addr_b).unwrap(); @@ -488,9 +487,9 @@ fn onchain_spend_receive() { node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); - assert_eq!(node_a.onchain_balance().unwrap().get_total(), 0); - assert!(node_b.onchain_balance().unwrap().get_spendable() > 99000); - assert!(node_b.onchain_balance().unwrap().get_spendable() < 100000); + assert_eq!(node_a.total_onchain_balance_sats().unwrap(), 0); + assert!(node_b.spendable_onchain_balance_sats().unwrap() > 99000); + assert!(node_b.spendable_onchain_balance_sats().unwrap() < 100000); } #[test] From 418872588c5002fabdd2dc8a0ba6d9e71d810d4b Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Tue, 30 May 2023 11:18:16 +0200 Subject: [PATCH 04/11] Rename `new_funding_address` to `new_onchain_address` As we're using the `onchain` keyword everywhere in the API to discern onchain-operations (e.g., `send_to_onchain_address`, `spendable_onchain_balance`, etc.) we also align the funding API call here and rename `new_funding_address` to `new_onchain_address`. --- README.md | 2 +- .../lightningdevkit/ldknode/AndroidLibTest.kt | 11 +++++------ .../org/lightningdevkit/ldknode/LibraryTest.kt | 4 ++-- bindings/ldk_node.udl | 2 +- src/lib.rs | 4 ++-- src/test/functional_tests.rs | 18 +++++++++--------- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 181b70e24..33816c5e9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ fn main() { node.start().unwrap(); - let funding_address = node.new_funding_address(); + let funding_address = node.new_onchain_address(); // .. fund address .. diff --git a/bindings/kotlin/ldk-node-android/lib/src/androidTest/kotlin/org/lightningdevkit/ldknode/AndroidLibTest.kt b/bindings/kotlin/ldk-node-android/lib/src/androidTest/kotlin/org/lightningdevkit/ldknode/AndroidLibTest.kt index 6bef9ded8..7ce380817 100644 --- a/bindings/kotlin/ldk-node-android/lib/src/androidTest/kotlin/org/lightningdevkit/ldknode/AndroidLibTest.kt +++ b/bindings/kotlin/ldk-node-android/lib/src/androidTest/kotlin/org/lightningdevkit/ldknode/AndroidLibTest.kt @@ -16,8 +16,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 @RunWith(AndroidJUnit4::class) class AndroidLibTest { @Test fun node_start_stop() { - val network: Network = "regtest" - assertEquals(network, "regtest") + val network = Network.REGTEST val tmpDir1 = createTempDirectory("ldk_node").toString() println("Random dir 1: $tmpDir1") @@ -27,8 +26,8 @@ class AndroidLibTest { val listenAddress1 = "127.0.0.1:2323" val listenAddress2 = "127.0.0.1:2324" - val config1 = Config(tmpDir1, "http://127.0.0.1:3002", network, listenAddress1, 2048u) - val config2 = Config(tmpDir2, "http://127.0.0.1:3002", network, listenAddress2, 2048u) + val config1 = Config(tmpDir1, network, listenAddress1, 2048u) + val config2 = Config(tmpDir2, network, listenAddress2, 2048u) val builder1 = Builder.fromConfig(config1) val builder2 = Builder.fromConfig(config2) @@ -45,10 +44,10 @@ class AndroidLibTest { val nodeId2 = node2.nodeId() println("Node Id 2: $nodeId2") - val address1 = node1.newFundingAddress() + val address1 = node1.newOnchainAddress() println("Funding address 1: $address1") - val address2 = node2.newFundingAddress() + val address2 = node2.newOnchainAddress() println("Funding address 2: $address2") node1.stop() diff --git a/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt b/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt index a755d5837..03cebbb24 100644 --- a/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt +++ b/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt @@ -91,10 +91,10 @@ class LibraryTest { val nodeId2 = node2.nodeId() println("Node Id 2: $nodeId2") - val address1 = node1.newFundingAddress() + val address1 = node1.newOnchainAddress() println("Funding address 1: $address1") - val address2 = node2.newFundingAddress() + val address2 = node2.newOnchainAddress() println("Funding address 2: $address2") val txid1 = sendToAddress(address1, 100000u) diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index 480a9cccf..3a33717cd 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -41,7 +41,7 @@ interface LDKNode { PublicKey node_id(); NetAddress? listening_address(); [Throws=NodeError] - Address new_funding_address(); + Address new_onchain_address(); [Throws=NodeError] Txid send_to_onchain_address([ByRef]Address address, u64 amount_msat); [Throws=NodeError] diff --git a/src/lib.rs b/src/lib.rs index 9f4940cd5..5186efbce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ //! //! node.start().unwrap(); //! -//! let funding_address = node.new_funding_address(); +//! let funding_address = node.new_onchain_address(); //! //! // .. fund address .. //! @@ -730,7 +730,7 @@ impl Node { } /// Retrieve a new on-chain/funding address. - pub fn new_funding_address(&self) -> Result { + pub fn new_onchain_address(&self) -> Result { let funding_address = self.wallet.get_new_address()?; log_info!(self.logger, "Generated new funding address: {}", funding_address); Ok(funding_address) diff --git a/src/test/functional_tests.rs b/src/test/functional_tests.rs index c60a29ddb..a957b8efd 100644 --- a/src/test/functional_tests.rs +++ b/src/test/functional_tests.rs @@ -56,8 +56,8 @@ fn channel_full_cycle_0conf() { fn do_channel_full_cycle( node_a: Node, node_b: Node, bitcoind: &BitcoinD, electrsd: &ElectrsD, allow_0conf: bool, ) { - let addr_a = node_a.new_funding_address().unwrap(); - let addr_b = node_b.new_funding_address().unwrap(); + let addr_a = node_a.new_onchain_address().unwrap(); + let addr_b = node_b.new_onchain_address().unwrap(); let premine_amount_sat = 100_000; @@ -278,7 +278,7 @@ fn channel_open_fails_when_funds_insufficient() { builder_a.set_esplora_server(esplora_url.clone()); let node_a = builder_a.build(); node_a.start().unwrap(); - let addr_a = node_a.new_funding_address().unwrap(); + let addr_a = node_a.new_onchain_address().unwrap(); println!("\n== Node B =="); let config_b = random_config(); @@ -286,7 +286,7 @@ fn channel_open_fails_when_funds_insufficient() { builder_b.set_esplora_server(esplora_url); let node_b = builder_b.build(); node_b.start().unwrap(); - let addr_b = node_b.new_funding_address().unwrap(); + let addr_b = node_b.new_onchain_address().unwrap(); let premine_amount_sat = 100_000; @@ -337,7 +337,7 @@ fn start_stop_reinit() { let node = builder.build(); let expected_node_id = node.node_id(); - let funding_address = node.new_funding_address().unwrap(); + let funding_address = node.new_onchain_address().unwrap(); let expected_amount = Amount::from_sat(100000); premine_and_distribute_funds(&bitcoind, &electrsd, vec![funding_address], expected_amount); @@ -393,7 +393,7 @@ fn start_stop_reinit_fs_store() { let node = builder.build_with_fs_store(); let expected_node_id = node.node_id(); - let funding_address = node.new_funding_address().unwrap(); + let funding_address = node.new_onchain_address().unwrap(); let expected_amount = Amount::from_sat(100000); premine_and_distribute_funds(&bitcoind, &electrsd, vec![funding_address], expected_amount); @@ -446,14 +446,14 @@ fn onchain_spend_receive() { builder_a.set_esplora_server(esplora_url.clone()); let node_a = builder_a.build(); node_a.start().unwrap(); - let addr_a = node_a.new_funding_address().unwrap(); + let addr_a = node_a.new_onchain_address().unwrap(); let config_b = random_config(); let mut builder_b = NodeBuilder::from_config(config_b); builder_b.set_esplora_server(esplora_url); let node_b = builder_b.build(); node_b.start().unwrap(); - let addr_b = node_b.new_funding_address().unwrap(); + let addr_b = node_b.new_onchain_address().unwrap(); premine_and_distribute_funds( &bitcoind, @@ -479,7 +479,7 @@ fn onchain_spend_receive() { assert!(node_b.spendable_onchain_balance_sats().unwrap() > 98000); assert!(node_b.spendable_onchain_balance_sats().unwrap() < 100000); - let addr_b = node_b.new_funding_address().unwrap(); + let addr_b = node_b.new_onchain_address().unwrap(); let txid = node_a.send_all_to_onchain_address(&addr_b).unwrap(); generate_blocks_and_wait(&bitcoind, &electrsd, 6); wait_for_tx(&electrsd, txid); From 3253ecc26f81aa64035dd71bdd91dc84a4032bca Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Tue, 30 May 2023 12:21:38 +0200 Subject: [PATCH 05/11] Check documentation building in CI Now that we split out UniFFI to its own feature, we can make use of the `missing_docs` lint again and enforce it in CI for release docs as well as private items. --- .github/workflows/build.yml | 4 ++++ src/io/mod.rs | 1 + src/io/utils.rs | 3 ++- src/lib.rs | 7 +------ 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d7a889264..802b1ec35 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,6 +24,10 @@ jobs: run: cargo build --verbose --color always - name: Build with UniFFI support on Rust ${{ matrix.toolchain }} run: cargo build --features uniffi --verbose --color always + - name: Build documentation on Rust ${{ matrix.toolchain }} + run: | + cargo doc --release --verbose --color always + cargo doc --document-private-items --verbose --color always - name: Check release build on Rust ${{ matrix.toolchain }} run: cargo check --release --verbose --color always - name: Check release build with UniFFI support on Rust ${{ matrix.toolchain }} diff --git a/src/io/mod.rs b/src/io/mod.rs index d62c55bc9..994cb0206 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -54,6 +54,7 @@ pub(crate) const LATEST_NODE_ANN_BCAST_TIMESTAMP_KEY: &str = "latest_node_ann_bc /// Keys and namespaces are required to be valid ASCII strings and the empty namespace (`""`) is /// assumed to be valid namespace. pub trait KVStore: KVStorePersister { + /// A reader as returned by [`Self::read`]. type Reader: Read; /// Returns a [`Read`] for the given `namespace` and `key` from which [`Readable`]s may be /// read. diff --git a/src/io/utils.rs b/src/io/utils.rs index f141648c3..0ee1999c2 100644 --- a/src/io/utils.rs +++ b/src/io/utils.rs @@ -31,6 +31,7 @@ use super::KVStore; /// [`Builder::set_entropy_bip39_mnemonic`]. /// /// [BIP 39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki +/// [`Node`]: crate::Node /// [`Builder::set_entropy_bip39_mnemonic`]: crate::Builder::set_entropy_bip39_mnemonic pub fn generate_entropy_mnemonic() -> Mnemonic { // bip39::Mnemonic supports 256 bit entropy max @@ -121,7 +122,7 @@ where }) } -/// Read a previously persisted [`Scorer`] from the store. +/// Read a previously persisted [`ProbabilisticScorer`] from the store. pub(crate) fn read_scorer< K: KVStore + Send + Sync, G: Deref>, diff --git a/src/lib.rs b/src/lib.rs index 5186efbce..2acf69b93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,12 +67,7 @@ //! [`connect_open_channel`]: Node::connect_open_channel //! [`send_payment`]: Node::send_payment //! - -// We currently disable the missing_docs lint due to incompatibility with the generated Uniffi -// scaffolding. -// TODO: Re-enable after https://github.com/mozilla/uniffi-rs/issues/1502 has been -// addressed. -//#![deny(missing_docs)] +#![cfg_attr(not(feature = "uniffi"), deny(missing_docs))] #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] #![allow(bare_trait_objects)] From c8c4448cd23b0aba254cf0f15ffb50180a0f341e Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Mon, 19 Jun 2023 13:54:30 +0200 Subject: [PATCH 06/11] Document and enforce MSRV in CI --- .github/workflows/build.yml | 15 ++++++++++++++- README.md | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 802b1ec35..ee43460dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,10 +6,17 @@ jobs: build: strategy: matrix: - toolchain: [ stable, beta ] + toolchain: [ + stable, + beta, + 1.60.0, # Our MSRV + ] include: - toolchain: stable check-fmt: true + build-uniffi: true + - toolchain: 1.60.0 + msrv: true runs-on: ubuntu-latest steps: - name: Checkout source code @@ -20,9 +27,13 @@ jobs: toolchain: ${{ matrix.toolchain }} override: true profile: minimal + - name: Pin packages to allow for MSRV + if: matrix.msrv + run: cargo update -p hashlink --precise "0.8.1" --verbose # hashlink 0.8.2 requires hashbrown 0.13, requiring 1.61.0 - name: Build on Rust ${{ matrix.toolchain }} run: cargo build --verbose --color always - name: Build with UniFFI support on Rust ${{ matrix.toolchain }} + if: matrix.build-uniffi run: cargo build --features uniffi --verbose --color always - name: Build documentation on Rust ${{ matrix.toolchain }} run: | @@ -31,10 +42,12 @@ jobs: - name: Check release build on Rust ${{ matrix.toolchain }} run: cargo check --release --verbose --color always - name: Check release build with UniFFI support on Rust ${{ matrix.toolchain }} + if: matrix.build-uniffi run: cargo check --release --features uniffi --verbose --color always - name: Test on Rust ${{ matrix.toolchain }} run: cargo test - name: Test with UniFFI support on Rust ${{ matrix.toolchain }} + if: matrix.build-uniffi run: cargo test --features uniffi - name: Check formatting on Rust ${{ matrix.toolchain }} if: matrix.check-fmt diff --git a/README.md b/README.md index 33816c5e9..235611d45 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,9 @@ LDK Node currently comes with a decidedly opinionated set of design choices: ## Language Support LDK Node itself is written in [Rust][rust] and may therefore be natively added as a library dependency to any `std` Rust program. However, beyond its Rust API it also offers language bindings for [Swift][swift], [Kotlin][kotlin], and [Python][python] based on the [UniFFI](https://github.com/mozilla/uniffi-rs/). Moreover, [Flutter bindings][flutter_bindings] are also available. +## MSRV +The Minimum Supported Rust Version (MSRV) is currently 1.60.0. + [api_docs]: https://docs.rs/ldk-node/*/ldk_node/ [api_docs_node]: https://docs.rs/ldk-node/*/ldk_node/struct.Node.html [api_docs_builder]: https://docs.rs/ldk-node/*/ldk_node/struct.Builder.html From d3e909a1c1a712b41f0cf237410ab1f6b7cd387c Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Tue, 30 May 2023 15:11:56 +0200 Subject: [PATCH 07/11] Make Kotlin tests more robust --- .../lightningdevkit/ldknode/LibraryTest.kt | 63 +++++++++++++++---- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt b/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt index 03cebbb24..1d8a0e681 100644 --- a/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt +++ b/bindings/kotlin/ldk-node-jvm/lib/src/test/kotlin/org/lightningdevkit/ldknode/LibraryTest.kt @@ -23,10 +23,19 @@ fun runCommandAndWait(cmd: String): String { return stdout + stderr } -fun mine(blocks: UInt) { +fun mine(blocks: UInt): String { val address = runCommandAndWait("bitcoin-cli -regtest getnewaddress") val output = runCommandAndWait("bitcoin-cli -regtest generatetoaddress $blocks $address") println("Mining output: $output") + val re = Regex("\n.+\n\\]$") + val lastBlock = re.find(output)!!.value.replace("]","").replace("\"", "").replace("\n","").trim() + println("Last block: $lastBlock") + return lastBlock +} + +fun mineAndWait(esploraEndpoint: String, blocks: UInt) { + val lastBlockHash = mine(blocks) + waitForBlock(esploraEndpoint, lastBlockHash) } fun sendToAddress(address: String, amountSats: UInt): String { @@ -39,6 +48,7 @@ fun setup() { runCommandAndWait("bitcoin-cli -regtest createwallet ldk_node_test") runCommandAndWait("bitcoin-cli -regtest loadwallet ldk_node_test true") mine(101u) + Thread.sleep(5_000) } fun waitForTx(esploraEndpoint: String, txid: String) { @@ -53,16 +63,32 @@ fun waitForTx(esploraEndpoint: String, txid: String) { val response = client.send(request, HttpResponse.BodyHandlers.ofString()); esploraPickedUpTx = re.containsMatchIn(response.body()); - Thread.sleep(1_000) + Thread.sleep(500) + } +} + +fun waitForBlock(esploraEndpoint: String, blockHash: String) { + var esploraPickedUpBlock = false + val re = Regex("\"in_best_chain\":true"); + while (!esploraPickedUpBlock) { + val client = HttpClient.newBuilder().build() + val request = HttpRequest.newBuilder() + .uri(URI.create(esploraEndpoint + "/block/" + blockHash + "/status")) + .build(); + + val response = client.send(request, HttpResponse.BodyHandlers.ofString()); + val body = response.body() + + esploraPickedUpBlock = re.containsMatchIn(response.body()); + Thread.sleep(500) } } class LibraryTest { @Test fun fullCycle() { + val esploraEndpoint = "http://127.0.0.1:3002" setup() - val network = Network.REGTEST - val tmpDir1 = createTempDirectory("ldk_node").toString() println("Random dir 1: $tmpDir1") val tmpDir2 = createTempDirectory("ldk_node").toString() @@ -71,13 +97,27 @@ class LibraryTest { val listenAddress1 = "127.0.0.1:2323" val listenAddress2 = "127.0.0.1:2324" - val esploraEndpoint = "http://127.0.0.1:3002" + val logLevel = LogLevel.TRACE; + + val config1 = Config() + config1.storageDirPath = tmpDir1 + config1.listeningAddress = listenAddress1 + config1.network = Network.REGTEST + config1.logLevel = LogLevel.TRACE - val config1 = Config(tmpDir1, esploraEndpoint, network, listenAddress1, 2048u) - val config2 = Config(tmpDir2, esploraEndpoint, network, listenAddress2, 2048u) + println("Config 1: $config1") + + val config2 = Config() + config2.storageDirPath = tmpDir2 + config2.listeningAddress = listenAddress2 + config2.network = Network.REGTEST + config2.logLevel = LogLevel.TRACE + println("Config 2: $config2") val builder1 = Builder.fromConfig(config1) + builder1.setEsploraServer(esploraEndpoint) val builder2 = Builder.fromConfig(config2) + builder2.setEsploraServer(esploraEndpoint) val node1 = builder1.build() val node2 = builder2.build() @@ -99,7 +139,7 @@ class LibraryTest { val txid1 = sendToAddress(address1, 100000u) val txid2 = sendToAddress(address2, 100000u) - mine(6u) + mineAndWait(esploraEndpoint, 6u) waitForTx(esploraEndpoint, txid1) waitForTx(esploraEndpoint, txid2) @@ -139,7 +179,7 @@ class LibraryTest { waitForTx(esploraEndpoint, fundingTxid) - mine(6u) + mineAndWait(esploraEndpoint, 6u) node1.syncWallets() node2.syncWallets() @@ -196,10 +236,7 @@ class LibraryTest { assert(channelClosedEvent2 is Event.ChannelClosed) node2.eventHandled() - mine(1u) - - // Sleep a bit to allow for the block to propagate to esplora - Thread.sleep(5_000) + mineAndWait(esploraEndpoint, 1u) node1.syncWallets() node2.syncWallets() From c99f4bd18237a58cd42c46c4c074881638613eb8 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Mon, 19 Jun 2023 10:47:06 +0200 Subject: [PATCH 08/11] Rename Swift modules to `LDKNode`/`LDKNodeFFI` --- .../Info.plist | 6 ++--- .../Headers/LDKNodeFFI-umbrella.h} | 2 +- .../Modules/module.modulemap | 6 +++++ .../Headers/LDKNodeFFI-umbrella.h} | 2 +- .../Modules/module.modulemap | 6 +++++ .../Headers/LDKNodeFFI-umbrella.h} | 2 +- .../Modules/module.modulemap | 6 +++++ bindings/swift/Package.swift | 14 ++++++------ .../Modules/module.modulemap | 6 ----- .../Modules/module.modulemap | 6 ----- .../Modules/module.modulemap | 6 ----- scripts/uniffi_bindgen_generate_swift.sh | 22 +++++++++---------- uniffi.toml | 3 +++ 13 files changed, 45 insertions(+), 42 deletions(-) rename bindings/swift/{ldk_nodeFFI.xcframework => LDKNodeFFI.xcframework}/Info.plist (90%) rename bindings/swift/{ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h => LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h} (83%) create mode 100644 bindings/swift/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Modules/module.modulemap rename bindings/swift/{ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h => LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h} (83%) create mode 100644 bindings/swift/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Modules/module.modulemap rename bindings/swift/{ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h => LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h} (83%) create mode 100644 bindings/swift/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Modules/module.modulemap delete mode 100644 bindings/swift/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Modules/module.modulemap delete mode 100644 bindings/swift/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Modules/module.modulemap delete mode 100644 bindings/swift/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Modules/module.modulemap diff --git a/bindings/swift/ldk_nodeFFI.xcframework/Info.plist b/bindings/swift/LDKNodeFFI.xcframework/Info.plist similarity index 90% rename from bindings/swift/ldk_nodeFFI.xcframework/Info.plist rename to bindings/swift/LDKNodeFFI.xcframework/Info.plist index d0d1ee6fc..ee11d9a89 100644 --- a/bindings/swift/ldk_nodeFFI.xcframework/Info.plist +++ b/bindings/swift/LDKNodeFFI.xcframework/Info.plist @@ -8,7 +8,7 @@ LibraryIdentifier macos-arm64_x86_64 LibraryPath - ldk_nodeFFI.framework + LDKNodeFFI.framework SupportedArchitectures arm64 @@ -21,7 +21,7 @@ LibraryIdentifier ios-arm64_x86_64-simulator LibraryPath - ldk_nodeFFI.framework + LDKNodeFFI.framework SupportedArchitectures arm64 @@ -36,7 +36,7 @@ LibraryIdentifier ios-arm64 LibraryPath - ldk_nodeFFI.framework + LDKNodeFFI.framework SupportedArchitectures arm64 diff --git a/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h b/bindings/swift/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h similarity index 83% rename from bindings/swift/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h rename to bindings/swift/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h index ecc6775bc..51a02f031 100644 --- a/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h +++ b/bindings/swift/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h @@ -1,4 +1,4 @@ // This is the "umbrella header" for our combined Rust code library. // It needs to import all of the individual headers. -#import "ldk_nodeFFI.h" +#import "LDKNodeFFI.h" diff --git a/bindings/swift/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Modules/module.modulemap b/bindings/swift/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Modules/module.modulemap new file mode 100644 index 000000000..a18e710d3 --- /dev/null +++ b/bindings/swift/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module LDKNodeFFI { + umbrella header "LDKNodeFFI-umbrella.h" + + export * + module * { export * } +} diff --git a/bindings/swift/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h b/bindings/swift/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h similarity index 83% rename from bindings/swift/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h rename to bindings/swift/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h index ecc6775bc..51a02f031 100644 --- a/bindings/swift/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h +++ b/bindings/swift/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h @@ -1,4 +1,4 @@ // This is the "umbrella header" for our combined Rust code library. // It needs to import all of the individual headers. -#import "ldk_nodeFFI.h" +#import "LDKNodeFFI.h" diff --git a/bindings/swift/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Modules/module.modulemap b/bindings/swift/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Modules/module.modulemap new file mode 100644 index 000000000..a18e710d3 --- /dev/null +++ b/bindings/swift/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module LDKNodeFFI { + umbrella header "LDKNodeFFI-umbrella.h" + + export * + module * { export * } +} diff --git a/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h b/bindings/swift/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h similarity index 83% rename from bindings/swift/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h rename to bindings/swift/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h index ecc6775bc..51a02f031 100644 --- a/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Headers/ldk_nodeFFI-umbrella.h +++ b/bindings/swift/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Headers/LDKNodeFFI-umbrella.h @@ -1,4 +1,4 @@ // This is the "umbrella header" for our combined Rust code library. // It needs to import all of the individual headers. -#import "ldk_nodeFFI.h" +#import "LDKNodeFFI.h" diff --git a/bindings/swift/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Modules/module.modulemap b/bindings/swift/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Modules/module.modulemap new file mode 100644 index 000000000..a18e710d3 --- /dev/null +++ b/bindings/swift/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module LDKNodeFFI { + umbrella header "LDKNodeFFI-umbrella.h" + + export * + module * { export * } +} diff --git a/bindings/swift/Package.swift b/bindings/swift/Package.swift index 7ae8aee70..8f5e52a0f 100644 --- a/bindings/swift/Package.swift +++ b/bindings/swift/Package.swift @@ -12,8 +12,8 @@ let package = Package( products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( - name: "LightningDevKitNode", - targets: ["ldk_nodeFFI", "LightningDevKitNode"]), + name: "LDKNode", + targets: ["LDKNodeFFI", "LDKNode"]), ], dependencies: [ // Dependencies declare other packages that this package depends on. @@ -23,13 +23,13 @@ let package = Package( // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. // .binaryTarget( -// name: "ldk_nodeFFI", -// url: "https://github.com/lightningdevkit/ldk-node/releases/download/0.3.0/ldk_nodeFFI.xcframework.zip", +// name: "LDKNodeFFI", +// url: "https://github.com/lightningdevkit/ldk-node/releases/download/0.3.0/LDKNodeFFI.xcframework.zip", // checksum: ""), - .binaryTarget(name: "ldk_nodeFFI", path: "./ldk_nodeFFI.xcframework"), + .binaryTarget(name: "LDKNodeFFI", path: "./LDKNodeFFI.xcframework"), .target( - name: "LightningDevKitNode", - dependencies: ["ldk_nodeFFI"]), + name: "LDKNode", + dependencies: ["LDKNodeFFI"]), // .testTarget( // name: "LightningDevKitNodeTests", // dependencies: ["LightningDevKitNode"]), diff --git a/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Modules/module.modulemap b/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Modules/module.modulemap deleted file mode 100644 index 7a6998828..000000000 --- a/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Modules/module.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module ldk_nodeFFI { - umbrella header "ldk_nodeFFI-umbrella.h" - - export * - module * { export * } -} diff --git a/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Modules/module.modulemap b/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Modules/module.modulemap deleted file mode 100644 index 7a6998828..000000000 --- a/bindings/swift/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Modules/module.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module ldk_nodeFFI { - umbrella header "ldk_nodeFFI-umbrella.h" - - export * - module * { export * } -} diff --git a/bindings/swift/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Modules/module.modulemap b/bindings/swift/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Modules/module.modulemap deleted file mode 100644 index 7a6998828..000000000 --- a/bindings/swift/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Modules/module.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module ldk_nodeFFI { - umbrella header "ldk_nodeFFI-umbrella.h" - - export * - module * { export * } -} diff --git a/scripts/uniffi_bindgen_generate_swift.sh b/scripts/uniffi_bindgen_generate_swift.sh index 042e157be..0ec165bde 100755 --- a/scripts/uniffi_bindgen_generate_swift.sh +++ b/scripts/uniffi_bindgen_generate_swift.sh @@ -30,17 +30,17 @@ lipo target/aarch64-apple-darwin/release-smaller/libldk_node.a target/x86_64-app $UNIFFI_BINDGEN_BIN generate bindings/ldk_node.udl --language swift -o "$BINDINGS_DIR" || exit 1 -swiftc -module-name ldk_node -emit-library -o "$BINDINGS_DIR"/libldk_node.dylib -emit-module -emit-module-path "$BINDINGS_DIR" -parse-as-library -L ./target/release-smaller -lldk_node -Xcc -fmodule-map-file="$BINDINGS_DIR"/ldk_nodeFFI.modulemap "$BINDINGS_DIR"/ldk_node.swift -v || exit 1 +swiftc -module-name LDKNode -emit-library -o "$BINDINGS_DIR"/libldk_node.dylib -emit-module -emit-module-path "$BINDINGS_DIR" -parse-as-library -L ./target/release-smaller -lldk_node -Xcc -fmodule-map-file="$BINDINGS_DIR"/LDKNodeFFI.modulemap "$BINDINGS_DIR"/LDKNode.swift -v || exit 1 # Create xcframework from bindings Swift file and libs -mkdir -p "$BINDINGS_DIR"/Sources/LightningDevKitNode || exit 1 -mv "$BINDINGS_DIR"/ldk_node.swift "$BINDINGS_DIR"/Sources/LightningDevKitNode/LightningDevKitNode.swift || exit 1 -cp "$BINDINGS_DIR"/ldk_nodeFFI.h "$BINDINGS_DIR"/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/Headers || exit 1 -cp "$BINDINGS_DIR"/ldk_nodeFFI.h "$BINDINGS_DIR"/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/Headers || exit 1 -cp "$BINDINGS_DIR"/ldk_nodeFFI.h "$BINDINGS_DIR"/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/Headers || exit 1 -cp target/aarch64-apple-ios/release-smaller/libldk_node.a "$BINDINGS_DIR"/ldk_nodeFFI.xcframework/ios-arm64/ldk_nodeFFI.framework/ldk_nodeFFI || exit 1 -cp target/lipo-ios-sim/release-smaller/libldk_node.a "$BINDINGS_DIR"/ldk_nodeFFI.xcframework/ios-arm64_x86_64-simulator/ldk_nodeFFI.framework/ldk_nodeFFI || exit 1 -cp target/lipo-macos/release-smaller/libldk_node.a "$BINDINGS_DIR"/ldk_nodeFFI.xcframework/macos-arm64_x86_64/ldk_nodeFFI.framework/ldk_nodeFFI || exit 1 -# rm "$BINDINGS_DIR"/ldk_nodeFFI.h || exit 1 -# rm "$BINDINGS_DIR"/ldk_nodeFFI.modulemap || exit 1 +mkdir -p "$BINDINGS_DIR"/Sources/LDKNode || exit 1 +mv "$BINDINGS_DIR"/LDKNode.swift "$BINDINGS_DIR"/Sources/LDKNode/LDKNode.swift || exit 1 +cp "$BINDINGS_DIR"/LDKNodeFFI.h "$BINDINGS_DIR"/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/Headers || exit 1 +cp "$BINDINGS_DIR"/LDKNodeFFI.h "$BINDINGS_DIR"/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/Headers || exit 1 +cp "$BINDINGS_DIR"/LDKNodeFFI.h "$BINDINGS_DIR"/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/Headers || exit 1 +cp target/aarch64-apple-ios/release-smaller/libldk_node.a "$BINDINGS_DIR"/LDKNodeFFI.xcframework/ios-arm64/LDKNodeFFI.framework/LDKNodeFFI || exit 1 +cp target/lipo-ios-sim/release-smaller/libldk_node.a "$BINDINGS_DIR"/LDKNodeFFI.xcframework/ios-arm64_x86_64-simulator/LDKNodeFFI.framework/LDKNodeFFI || exit 1 +cp target/lipo-macos/release-smaller/libldk_node.a "$BINDINGS_DIR"/LDKNodeFFI.xcframework/macos-arm64_x86_64/LDKNodeFFI.framework/LDKNodeFFI || exit 1 +# rm "$BINDINGS_DIR"/LDKNodeFFI.h || exit 1 +# rm "$BINDINGS_DIR"/LDKNodeFFI.modulemap || exit 1 echo finished successfully! diff --git a/uniffi.toml b/uniffi.toml index 57655582d..9e429034f 100644 --- a/uniffi.toml +++ b/uniffi.toml @@ -6,4 +6,7 @@ cdylib_name = "ldk_node" cdylib_name = "ldk_node" [bindings.swift] +module_name = "LDKNode" +ffi_module_name = "LDKNodeFFI" +ffi_module_filename ="LDKNodeFFI" cdylib_name = "ldk_node" From 70c01cc32df93951b247535b0fe6c3fdb95e6a12 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Mon, 19 Jun 2023 13:14:42 +0200 Subject: [PATCH 09/11] Update Package.swift and prepare desc for SwiftPM --- Package.swift | 35 +++++++++++++++++++++++++++++++++++ bindings/swift/Package.swift | 25 ++++++++----------------- 2 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 Package.swift diff --git a/Package.swift b/Package.swift new file mode 100644 index 000000000..efab0d8d5 --- /dev/null +++ b/Package.swift @@ -0,0 +1,35 @@ +// swift-tools-version:5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let tag = "0.1-alpha.1" +let checksum = "d91403566498f01cdaaafc07a9360ef661151e64075c6d83bbce4c9b5bfa7cee" +let url = "https://github.com/lightningdevkit/ldk-node/releases/download/\(tag)/LDKNodeFFI.xcframework.zip" + +let package = Package( + name: "ldk-node", + platforms: [ + .iOS(.v15), + .macOS(.v12), + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "LDKNode", + targets: ["LDKNodeFFI", "LDKNode"]), + ], + targets: [ + .target( + name: "LDKNode", + dependencies: ["LDKNodeFFI"], + path: "./bindings/swift/Sources", + swiftSettings: [.unsafeFlags(["-suppress-warnings"])] + ), + .binaryTarget( + name: "LDKNodeFFI", + url: url, + checksum: checksum + ) + ] +) diff --git a/bindings/swift/Package.swift b/bindings/swift/Package.swift index 8f5e52a0f..fcd346505 100644 --- a/bindings/swift/Package.swift +++ b/bindings/swift/Package.swift @@ -1,13 +1,12 @@ // swift-tools-version:5.5 // The swift-tools-version declares the minimum version of Swift required to build this package. - import PackageDescription let package = Package( name: "ldk-node", platforms: [ + .iOS(.v15), .macOS(.v12), - .iOS(.v15) ], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. @@ -15,23 +14,15 @@ let package = Package( name: "LDKNode", targets: ["LDKNodeFFI", "LDKNode"]), ], - dependencies: [ - // Dependencies declare other packages that this package depends on. - // .package(url: /* package url */, from: "1.0.0"), - ], targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages this package depends on. -// .binaryTarget( -// name: "LDKNodeFFI", -// url: "https://github.com/lightningdevkit/ldk-node/releases/download/0.3.0/LDKNodeFFI.xcframework.zip", -// checksum: ""), - .binaryTarget(name: "LDKNodeFFI", path: "./LDKNodeFFI.xcframework"), .target( name: "LDKNode", - dependencies: ["LDKNodeFFI"]), -// .testTarget( -// name: "LightningDevKitNodeTests", -// dependencies: ["LightningDevKitNode"]), + dependencies: ["LDKNodeFFI"], + swiftSettings: [.unsafeFlags(["-suppress-warnings"])] + ), + .binaryTarget( + name: "LDKNodeFFI", + path: "./LDKNodeFFI.xcframework" + ) ] ) From d95bb5b5b7d8eb93d2adf27e69fe9d84c8bad15c Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Mon, 19 Jun 2023 13:27:25 +0200 Subject: [PATCH 10/11] Add scripts to create Swift xcframework archive and update Package.swift --- scripts/swift_create_xcframework_archive.sh | 4 ++ scripts/swift_update_package_checksum.py | 80 +++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100755 scripts/swift_create_xcframework_archive.sh create mode 100644 scripts/swift_update_package_checksum.py diff --git a/scripts/swift_create_xcframework_archive.sh b/scripts/swift_create_xcframework_archive.sh new file mode 100755 index 000000000..c72f5bd85 --- /dev/null +++ b/scripts/swift_create_xcframework_archive.sh @@ -0,0 +1,4 @@ +ditto -c -k --sequesterRsrc --keepParent ./bindings/swift/LDKNodeFFI.xcframework ./bindings/swift/LDKNodeFFI.xcframework.zip || exit 1 +CHECKSUM=`swift package compute-checksum ./bindings/swift/LDKNodeFFI.xcframework.zip` || exit 1 +echo "New checksum: $CHECKSUM" || exit 1 +python3 ./scripts/swift_update_package_checksum.py --checksum "${CHECKSUM}" || exit 1 diff --git a/scripts/swift_update_package_checksum.py b/scripts/swift_update_package_checksum.py new file mode 100644 index 000000000..ae26a86c9 --- /dev/null +++ b/scripts/swift_update_package_checksum.py @@ -0,0 +1,80 @@ +import argparse +import json +import os +import re +import sys + + +def run(new_checksum: str = None, new_tag: str = None): + if new_checksum is None and new_tag is None: + print('At least one of --checksum or --tag arguments must be provided.', file=sys.stderr) + sys.exit(1) + + if new_checksum is not None: + if not new_checksum.isalnum(): + print('Checksum must be alphanumeric.', file=sys.stderr) + sys.exit(1) + + if not new_checksum.islower(): + print('Checksum must be lowercase.', file=sys.stderr) + sys.exit(1) + + try: + int(new_checksum, 16) + except: + print('Checksum must be hexadecimal.', file=sys.stderr) + sys.exit(1) + + if new_tag is not None: + if new_tag.strip() != new_tag: + print('Tag must not contain any whitespace.', file=sys.stderr) + + tag_regex = re.compile("^\d+[.]\d+[.]\d+$") + tag_match = tag_regex.match(new_tag) + if tag_match is None: + print('Tag must adhere to x.x.x major/minor/patch format.', file=sys.stderr) + + settings = [ + {'variable_name': 'checksum', 'value': new_checksum}, + {'variable_name': 'tag', 'value': new_tag}, + ] + + package_file_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '../Package.swift')) + print(package_file_path) + + + + original_package_file = None + try: + with open(package_file_path, 'r') as package_file_handle: + original_package_file = package_file_handle.read() + except: + print('Failed to read Package.swift file.', file=sys.stderr) + sys.exit(1) + + package_file = original_package_file + for current_setting in settings: + current_variable_name = current_setting['variable_name'] + new_value = current_setting['value'] + if new_value is None: + continue + + print(f'setting {current_variable_name} (JSON-serialization):') + print(json.dumps(new_value)) + + regex = re.compile(f'(let[\s]+{current_variable_name}[\s]*=[\s]*)(.*)') + + previous_value = regex.search(package_file).group(2) + package_file = package_file.replace(previous_value, f'"{new_value}"') + + with open(package_file_path, "w") as f: + f.write(package_file) + + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument('--checksum', type=str, help='new checksum of LDKNode.xcframework.zip', required=False, default=None) + parser.add_argument('--tag', type=str, help='new release tag', required=False, default=None) + args = parser.parse_args() + run(new_checksum=args.checksum, new_tag=args.tag) From 7de04b7cf5967a633a0f96569c12679bd6b6eaec Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Mon, 19 Jun 2023 15:52:33 +0200 Subject: [PATCH 11/11] Avoid nightly for binding generation where possible .. and use a particular nightly rev for where it's not. --- scripts/uniffi_bindgen_generate_kotlin_android.sh | 10 +++++----- scripts/uniffi_bindgen_generate_python.sh | 4 ++-- scripts/uniffi_bindgen_generate_swift.sh | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/uniffi_bindgen_generate_kotlin_android.sh b/scripts/uniffi_bindgen_generate_kotlin_android.sh index 30a867181..fb11074bf 100755 --- a/scripts/uniffi_bindgen_generate_kotlin_android.sh +++ b/scripts/uniffi_bindgen_generate_kotlin_android.sh @@ -3,15 +3,15 @@ BINDINGS_DIR="bindings/kotlin" TARGET_DIR="target" PROJECT_DIR="ldk-node-android" PACKAGE_DIR="org/lightningdevkit/ldknode" -UNIFFI_BINDGEN_BIN="cargo +nightly run --features=uniffi/cli --bin uniffi-bindgen" +UNIFFI_BINDGEN_BIN="cargo run --features=uniffi/cli --bin uniffi-bindgen" ANDROID_NDK_ROOT="/opt/homebrew/share/android-ndk" LLVM_ARCH_PATH="darwin-x86_64" PATH="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$LLVM_ARCH_PATH/bin:$PATH" -rustup +nightly target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi -CFLAGS="-D__ANDROID_MIN_SDK_VERSION__=21" AR=llvm-ar CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="x86_64-linux-android21-clang" CC="x86_64-linux-android21-clang" cargo +nightly build --profile release-smaller --features uniffi --target x86_64-linux-android || exit 1 -CFLAGS="-D__ANDROID_MIN_SDK_VERSION__=21" AR=llvm-ar CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="armv7a-linux-androideabi21-clang" CC="armv7a-linux-androideabi21-clang" cargo +nightly build --profile release-smaller --features uniffi --target armv7-linux-androideabi || exit 1 -CFLAGS="-D__ANDROID_MIN_SDK_VERSION__=21" AR=llvm-ar CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="aarch64-linux-android21-clang" CC="aarch64-linux-android21-clang" cargo +nightly build --profile release-smaller --features uniffi --target aarch64-linux-android || exit 1 +rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabi +CFLAGS="-D__ANDROID_MIN_SDK_VERSION__=21" AR=llvm-ar CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="x86_64-linux-android21-clang" CC="x86_64-linux-android21-clang" cargo build --profile release-smaller --features uniffi --target x86_64-linux-android || exit 1 +CFLAGS="-D__ANDROID_MIN_SDK_VERSION__=21" AR=llvm-ar CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="armv7a-linux-androideabi21-clang" CC="armv7a-linux-androideabi21-clang" cargo build --profile release-smaller --features uniffi --target armv7-linux-androideabi || exit 1 +CFLAGS="-D__ANDROID_MIN_SDK_VERSION__=21" AR=llvm-ar CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="aarch64-linux-android21-clang" CC="aarch64-linux-android21-clang" cargo build --profile release-smaller --features uniffi --target aarch64-linux-android || exit 1 $UNIFFI_BINDGEN_BIN generate bindings/ldk_node.udl --language kotlin -o "$BINDINGS_DIR"/"$PROJECT_DIR"/lib/src/main/kotlin || exit 1 JNI_LIB_DIR="$BINDINGS_DIR"/"$PROJECT_DIR"/lib/src/main/jniLibs/ diff --git a/scripts/uniffi_bindgen_generate_python.sh b/scripts/uniffi_bindgen_generate_python.sh index a517fb329..c8f76a036 100755 --- a/scripts/uniffi_bindgen_generate_python.sh +++ b/scripts/uniffi_bindgen_generate_python.sh @@ -1,7 +1,7 @@ #!/bin/bash BINDINGS_DIR="./bindings/python" -UNIFFI_BINDGEN_BIN="cargo +nightly run --features=uniffi/cli --bin uniffi-bindgen" +UNIFFI_BINDGEN_BIN="cargo run --features=uniffi/cli --bin uniffi-bindgen" -cargo +nightly build --release --features uniffi || exit 1 +cargo build --release --features uniffi || exit 1 $UNIFFI_BINDGEN_BIN generate bindings/ldk_node.udl --language python -o "$BINDINGS_DIR" || exit 1 cp ./target/release/libldk_node.dylib "$BINDINGS_DIR"/libldk_node.dylib || exit 1 diff --git a/scripts/uniffi_bindgen_generate_swift.sh b/scripts/uniffi_bindgen_generate_swift.sh index 0ec165bde..238b07baf 100755 --- a/scripts/uniffi_bindgen_generate_swift.sh +++ b/scripts/uniffi_bindgen_generate_swift.sh @@ -8,10 +8,10 @@ $UNIFFI_BINDGEN_BIN generate bindings/ldk_node.udl --language swift -o "$BINDING mkdir -p $BINDINGS_DIR # Install rust target toolchains -rustup install nightly-x86_64-apple-darwin -rustup component add rust-src --toolchain nightly-x86_64-apple-darwin +rustup install nightly-2023-04-10 +rustup component add rust-src --toolchain nightly-2023-04-10 rustup target add aarch64-apple-ios x86_64-apple-ios -rustup target add aarch64-apple-ios-sim --toolchain nightly +rustup target add aarch64-apple-ios-sim --toolchain nightly-2023-04-10 rustup target add aarch64-apple-darwin x86_64-apple-darwin # Build rust target libs @@ -20,7 +20,7 @@ cargo build --profile release-smaller --features uniffi --target x86_64-apple-da cargo build --profile release-smaller --features uniffi --target aarch64-apple-darwin || exit 1 cargo build --profile release-smaller --features uniffi --target x86_64-apple-ios || exit 1 cargo build --profile release-smaller --features uniffi --target aarch64-apple-ios || exit 1 -cargo +nightly build --release --features uniffi --target aarch64-apple-ios-sim || exit 1 +cargo +nightly-2023-04-10 build --release --features uniffi --target aarch64-apple-ios-sim || exit 1 # Combine ios-sim and apple-darwin (macos) libs for x86_64 and aarch64 (m1) mkdir -p target/lipo-ios-sim/release-smaller || exit 1