From e03600f23b901663293aa287fb126f652789b10f Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 31 Dec 2025 19:45:00 +0000 Subject: [PATCH 1/4] Update to latest upstream LDK (which removed some test macros) --- Cargo.toml | 24 ++++++++++++------------ src/io/test_utils.rs | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 59ad2b767..aaee4d615 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,17 +39,17 @@ default = [] #lightning-liquidity = { version = "0.2.0", features = ["std"] } #lightning-macros = { version = "0.2.0" } -lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc", features = ["std"] } -lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc" } -lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc", features = ["std"] } -lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc" } -lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc", features = ["tokio"] } -lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc" } -lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc" } -lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc", features = ["rest-client", "rpc-client", "tokio"] } -lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc", features = ["esplora-async-https", "time", "electrum-rustls-ring"] } -lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc", features = ["std"] } -lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc" } +lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766", features = ["std"] } +lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766" } +lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766", features = ["std"] } +lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766" } +lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766", features = ["tokio"] } +lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766" } +lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766" } +lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766", features = ["rest-client", "rpc-client", "tokio"] } +lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766", features = ["esplora-async-https", "time", "electrum-rustls-ring"] } +lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766", features = ["std"] } +lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766" } bdk_chain = { version = "0.23.0", default-features = false, features = ["std"] } bdk_esplora = { version = "0.22.0", default-features = false, features = ["async-https-rustls", "tokio"]} @@ -82,7 +82,7 @@ prost = { version = "0.11.6", default-features = false} winapi = { version = "0.3", features = ["winbase"] } [dev-dependencies] -lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5bf0d1e2427d759fc1ba4108ddc7e9b32e8bacfc", features = ["std", "_test_utils"] } +lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "62c58495c3cbd47387962f31998899f6bbac8766", features = ["std", "_test_utils"] } proptest = "1.0.0" regex = "1.5.6" criterion = { version = "0.7.0", features = ["async_tokio"] } diff --git a/src/io/test_utils.rs b/src/io/test_utils.rs index 6eb04df3f..3687aa7be 100644 --- a/src/io/test_utils.rs +++ b/src/io/test_utils.rs @@ -13,15 +13,15 @@ use std::sync::Mutex; use lightning::events::ClosureReason; use lightning::ln::functional_test_utils::{ - check_closed_event, connect_block, create_announced_chan_between_nodes, create_chanmon_cfgs, - create_dummy_block, create_network, create_node_cfgs, create_node_chanmgrs, send_payment, - TestChanMonCfg, + check_added_monitors, check_closed_event, connect_block, create_announced_chan_between_nodes, + create_chanmon_cfgs, create_dummy_block, create_network, create_node_cfgs, create_node_chanmgrs, + send_payment, TestChanMonCfg, }; use lightning::util::persist::{ KVStore, KVStoreSync, MonitorUpdatingPersister, KVSTORE_NAMESPACE_KEY_MAX_LEN, }; use lightning::util::test_utils; -use lightning::{check_added_monitors, check_closed_broadcast, io}; +use lightning::{check_closed_broadcast, io}; use rand::distr::Alphanumeric; use rand::{rng, Rng}; @@ -333,7 +333,7 @@ pub(crate) fn do_test_store(store_0: &K, store_1: &K) { 100000, ); check_closed_broadcast!(nodes[0], true); - check_added_monitors!(nodes[0], 1); + check_added_monitors(&nodes[0], 1); let node_txn = nodes[0].tx_broadcaster.txn_broadcast(); assert_eq!(node_txn.len(), 1); @@ -345,7 +345,7 @@ pub(crate) fn do_test_store(store_0: &K, store_1: &K) { let reason = ClosureReason::CommitmentTxConfirmed; let node_id_0 = nodes[0].node.get_our_node_id(); check_closed_event(&nodes[1], 1, reason, &[node_id_0], 100000); - check_added_monitors!(nodes[1], 1); + check_added_monitors(&nodes[1], 1); // Make sure everything is persisted as expected after close. check_persisted_data!(persister_0_max_pending_updates * 2 * EXPECTED_UPDATES_PER_PAYMENT + 1); From 890fcc117bb7c075c8c1c62f893c5dbc7712800a Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 30 Dec 2025 14:09:27 +0000 Subject: [PATCH 2/4] Fix circular `Arc` reference in `LiquiditySource` `LiquiditySource` takes a reference to our `PeerManager` but the `PeerManager` holds an indirect reference to the `LiquiditySource`. As a result, after our `Node` instance is `stop`ped and the `Node` `drop`ped, much of the node's memory will stick around, including the `NetworkGraph`. Here we fix this issue by using `Weak` pointers, though note that there is another issue caused by LDK's gossip validation API. --- src/builder.rs | 2 +- src/liquidity.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index ff84505b4..010263fee 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1594,7 +1594,7 @@ fn build_with_store_internal( Arc::clone(&keys_manager), )); - liquidity_source.as_ref().map(|l| l.set_peer_manager(Arc::clone(&peer_manager))); + liquidity_source.as_ref().map(|l| l.set_peer_manager(Arc::downgrade(&peer_manager))); gossip_source.set_gossip_verifier( Arc::clone(&chain_source), diff --git a/src/liquidity.rs b/src/liquidity.rs index 74e6098dd..2151110b6 100644 --- a/src/liquidity.rs +++ b/src/liquidity.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; use std::ops::Deref; -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::{Arc, Mutex, RwLock, Weak}; use std::time::Duration; use bitcoin::hashes::{sha256, Hash}; @@ -291,7 +291,7 @@ where lsps2_service: Option, wallet: Arc, channel_manager: Arc, - peer_manager: RwLock>>, + peer_manager: RwLock>>, keys_manager: Arc, liquidity_manager: Arc, config: Arc, @@ -302,7 +302,7 @@ impl LiquiditySource where L::Target: LdkLogger, { - pub(crate) fn set_peer_manager(&self, peer_manager: Arc) { + pub(crate) fn set_peer_manager(&self, peer_manager: Weak) { *self.peer_manager.write().unwrap() = Some(peer_manager); } @@ -715,8 +715,8 @@ where return; }; - let init_features = if let Some(peer_manager) = - self.peer_manager.read().unwrap().as_ref() + let init_features = if let Some(Some(peer_manager)) = + self.peer_manager.read().unwrap().as_ref().map(|weak| weak.upgrade()) { // Fail if we're not connected to the prospective channel partner. if let Some(peer) = peer_manager.peer_by_node_id(&their_network_key) { From cd4e6e57d8e4edac35bd4fb8ad78c4c42edaa809 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 31 Dec 2025 19:45:22 +0000 Subject: [PATCH 3/4] Update LDK, fixing a circular `Arc` reference in gossip validation LDK's gossip validation API basically forced us to have a circular `Arc` reference, leading to memory leaks after `drop`ping an instance of `Node`. This is fixed upstream in LDK PR #4294 which we update to here. --- src/builder.rs | 14 ++++++-------- src/gossip.rs | 37 +++++++++++++------------------------ src/types.rs | 2 +- 3 files changed, 20 insertions(+), 33 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 010263fee..fe4ac3507 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1474,8 +1474,12 @@ fn build_with_store_internal( let gossip_source = match gossip_source_config { GossipSourceConfig::P2PNetwork => { - let p2p_source = - Arc::new(GossipSource::new_p2p(Arc::clone(&network_graph), Arc::clone(&logger))); + let p2p_source = Arc::new(GossipSource::new_p2p( + Arc::clone(&network_graph), + Arc::clone(&chain_source), + Arc::clone(&runtime), + Arc::clone(&logger), + )); // Reset the RGS sync timestamp in case we somehow switch gossip sources { @@ -1596,12 +1600,6 @@ fn build_with_store_internal( liquidity_source.as_ref().map(|l| l.set_peer_manager(Arc::downgrade(&peer_manager))); - gossip_source.set_gossip_verifier( - Arc::clone(&chain_source), - Arc::clone(&peer_manager), - Arc::clone(&runtime), - ); - let connection_manager = Arc::new(ConnectionManager::new(Arc::clone(&peer_manager), Arc::clone(&logger))); diff --git a/src/gossip.rs b/src/gossip.rs index 563d9e1ea..cd6c5459c 100644 --- a/src/gossip.rs +++ b/src/gossip.rs @@ -33,11 +33,21 @@ pub(crate) enum GossipSource { } impl GossipSource { - pub fn new_p2p(network_graph: Arc, logger: Arc) -> Self { + pub fn new_p2p( + network_graph: Arc, chain_source: Arc, runtime: Arc, + logger: Arc, + ) -> Self { + let verifier = chain_source.as_utxo_source().map(|utxo_source| { + Arc::new(GossipVerifier::new( + Arc::new(utxo_source), + RuntimeSpawner::new(runtime), + )) + }); + let gossip_sync = Arc::new(P2PGossipSync::new( network_graph, - None::>, - Arc::clone(&logger), + verifier, + logger, )); Self::P2PNetwork { gossip_sync } } @@ -62,27 +72,6 @@ impl GossipSource { } } - pub(crate) fn set_gossip_verifier( - &self, chain_source: Arc, peer_manager: Arc, - runtime: Arc, - ) { - match self { - Self::P2PNetwork { gossip_sync } => { - if let Some(utxo_source) = chain_source.as_utxo_source() { - let spawner = RuntimeSpawner::new(Arc::clone(&runtime)); - let gossip_verifier = Arc::new(GossipVerifier::new( - Arc::new(utxo_source), - spawner, - Arc::clone(gossip_sync), - peer_manager, - )); - gossip_sync.add_utxo_lookup(Some(gossip_verifier)); - } - }, - _ => (), - } - } - pub async fn update_rgs_snapshot(&self) -> Result { match self { Self::P2PNetwork { gossip_sync: _, .. } => Ok(0), diff --git a/src/types.rs b/src/types.rs index 7c0e1227a..39769ec5a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -253,7 +253,7 @@ pub(crate) type Scorer = CombinedScorer, Arc>; pub(crate) type Graph = gossip::NetworkGraph>; -pub(crate) type UtxoLookup = GossipVerifier, Arc>; +pub(crate) type UtxoLookup = GossipVerifier>; pub(crate) type P2PGossipSync = lightning::routing::gossip::P2PGossipSync, Arc, Arc>; From 05d7a7dafe2882ae7c9dc580fcb3ef716a8e7f0e Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 30 Dec 2025 14:09:57 +0000 Subject: [PATCH 4/4] Add test for circular references leading to `NetworkGraph` leaks Due to two circular `Arc` references, after `stop`ping and `drop`ping the `Node` instance the bulk of ldk-node's memory (in the form of the `NetworkGraph`) would hang around. Here we add a test for this in our integration tests, checking if the `NetworkGraph` (as a proxy for other objects held in reference by the `PeerManager`) hangs around after `Node`s are `drop`ped. --- .github/workflows/cln-integration.yml | 2 +- .github/workflows/lnd-integration.yml | 2 +- .github/workflows/rust.yml | 4 +-- .github/workflows/vss-integration.yml | 2 +- Cargo.toml | 1 + src/lib.rs | 6 ++++ src/logger.rs | 10 ++++++ tests/common/mod.rs | 46 +++++++++++++++++++++++++-- tests/integration_tests_rust.rs | 34 +++++++++++++------- 9 files changed, 87 insertions(+), 20 deletions(-) diff --git a/.github/workflows/cln-integration.yml b/.github/workflows/cln-integration.yml index 32e7b74c0..d7624181b 100644 --- a/.github/workflows/cln-integration.yml +++ b/.github/workflows/cln-integration.yml @@ -27,4 +27,4 @@ jobs: socat -d -d UNIX-LISTEN:/tmp/lightning-rpc,reuseaddr,fork TCP:127.0.0.1:9937& - name: Run CLN integration tests - run: RUSTFLAGS="--cfg cln_test" cargo test --test integration_tests_cln + run: RUSTFLAGS="--cfg cln_test --cfg cycle_tests" cargo test --test integration_tests_cln diff --git a/.github/workflows/lnd-integration.yml b/.github/workflows/lnd-integration.yml index f913e92ad..894209c4b 100644 --- a/.github/workflows/lnd-integration.yml +++ b/.github/workflows/lnd-integration.yml @@ -51,6 +51,6 @@ jobs: - name: Run LND integration tests run: LND_CERT_PATH=$LND_DATA_DIR/tls.cert LND_MACAROON_PATH=$LND_DATA_DIR/data/chain/bitcoin/regtest/admin.macaroon - RUSTFLAGS="--cfg lnd_test" cargo test --test integration_tests_lnd -- --exact --show-output + RUSTFLAGS="--cfg lnd_test --cfg cycle_tests" cargo test --test integration_tests_lnd -- --exact --show-output env: LND_DATA_DIR: ${{ env.LND_DATA_DIR }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 661703ded..1ccade444 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -80,11 +80,11 @@ jobs: - name: Test on Rust ${{ matrix.toolchain }} if: "matrix.platform != 'windows-latest'" run: | - RUSTFLAGS="--cfg no_download" cargo test + RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test - name: Test with UniFFI support on Rust ${{ matrix.toolchain }} if: "matrix.platform != 'windows-latest' && matrix.build-uniffi" run: | - RUSTFLAGS="--cfg no_download" cargo test --features uniffi + RUSTFLAGS="--cfg no_download --cfg cycle_tests" cargo test --features uniffi doc: name: Documentation diff --git a/.github/workflows/vss-integration.yml b/.github/workflows/vss-integration.yml index 8473ed413..b5c4e9a0b 100644 --- a/.github/workflows/vss-integration.yml +++ b/.github/workflows/vss-integration.yml @@ -45,4 +45,4 @@ jobs: cd ldk-node export TEST_VSS_BASE_URL="http://localhost:8080/vss" RUSTFLAGS="--cfg vss_test" cargo test io::vss_store - RUSTFLAGS="--cfg vss_test" cargo test --test integration_tests_vss + RUSTFLAGS="--cfg vss_test --cfg cycle_tests" cargo test --test integration_tests_vss diff --git a/Cargo.toml b/Cargo.toml index aaee4d615..f73444795 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -122,6 +122,7 @@ check-cfg = [ "cfg(tokio_unstable)", "cfg(cln_test)", "cfg(lnd_test)", + "cfg(cycle_tests)", ] [[bench]] diff --git a/src/lib.rs b/src/lib.rs index 0031269dd..886628772 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1754,6 +1754,12 @@ impl Node { Error::PersistenceFailed }) } + + #[cfg(cycle_tests)] + /// Fetch a reference to the inner NetworkGraph, for Arc cycle detection + pub fn fetch_ref(&self) -> std::sync::Weak { + Arc::downgrade(&self.network_graph) + } } impl Drop for Node { diff --git a/src/logger.rs b/src/logger.rs index 4eaefad74..6a98b92f2 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -171,6 +171,14 @@ impl LogWriter for Writer { } } +#[cfg(cycle_tests)] +/// Our log writer +pub struct Logger { + /// Specifies the logger's writer. + writer: Writer, +} + +#[cfg(not(cycle_tests))] pub(crate) struct Logger { /// Specifies the logger's writer. writer: Writer, @@ -195,10 +203,12 @@ impl Logger { Ok(Self { writer: Writer::FileWriter { file_path, max_log_level } }) } + /// Creates a new logger writing to the `log` crate pub fn new_log_facade() -> Self { Self { writer: Writer::LogFacadeWriter } } + /// Creates a new logger writing to an underlying [`LogWriter`] pub fn new_custom_writer(log_writer: Arc) -> Self { Self { writer: Writer::CustomWriter(log_writer) } } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 96f58297c..594df12f5 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -13,6 +13,7 @@ pub(crate) mod logging; use std::collections::{HashMap, HashSet}; use std::env; use std::future::Future; +use std::ops::Deref; use std::path::PathBuf; use std::sync::{Arc, RwLock}; use std::time::Duration; @@ -261,10 +262,49 @@ pub(crate) fn random_config(anchor_channels: bool) -> TestConfig { TestConfig { node_config, ..Default::default() } } +pub struct TestNode { + #[cfg(feature = "uniffi")] + inner: Option>, + #[cfg(not(feature = "uniffi"))] + inner: Option, +} + #[cfg(feature = "uniffi")] -type TestNode = Arc; +impl From> for TestNode { + fn from(inner: Arc) -> Self { + Self { inner: Some(inner) } + } +} + #[cfg(not(feature = "uniffi"))] -type TestNode = Node; +impl From for TestNode { + fn from(inner: Node) -> Self { + Self { inner: Some(inner) } + } +} + +impl Deref for TestNode { + type Target = Node; + fn deref(&self) -> &Node { + #[cfg(feature = "uniffi")] + { + self.inner.as_ref().unwrap().deref() + } + #[cfg(not(feature = "uniffi"))] + { + &self.inner.as_ref().unwrap() + } + } +} + +#[cfg(cycle_tests)] +impl Drop for TestNode { + fn drop(&mut self) { + let graph_ref = (**self).fetch_ref(); + self.inner.take(); + assert_eq!(graph_ref.strong_count(), 0); + } +} #[derive(Clone)] pub(crate) enum TestChainSource<'a> { @@ -430,7 +470,7 @@ pub(crate) fn setup_node_for_async_payments( node.start().unwrap(); assert!(node.status().is_running); assert!(node.status().latest_fee_rate_cache_update_timestamp.is_some()); - node + node.into() } pub(crate) async fn generate_blocks_and_wait( diff --git a/tests/integration_tests_rust.rs b/tests/integration_tests_rust.rs index 9b02cd61f..bec3ee9dd 100644 --- a/tests/integration_tests_rust.rs +++ b/tests/integration_tests_rust.rs @@ -23,7 +23,8 @@ use common::{ expect_splice_pending_event, generate_blocks_and_wait, open_channel, open_channel_push_amt, premine_and_distribute_funds, premine_blocks, prepare_rbf, random_config, random_listening_addresses, setup_bitcoind_and_electrsd, setup_builder, setup_node, - setup_node_for_async_payments, setup_two_nodes, wait_for_tx, TestChainSource, TestSyncStore, + setup_node_for_async_payments, setup_two_nodes, wait_for_tx, TestChainSource, TestNode, + TestSyncStore, }; use ldk_node::config::{AsyncPaymentsRole, EsploraSyncConfig}; use ldk_node::liquidity::LSPS2ServiceConfig; @@ -153,7 +154,7 @@ async fn multi_hop_sending() { let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap()); // Setup and fund 5 nodes - let mut nodes = Vec::new(); + let mut nodes: Vec = Vec::new(); for _ in 0..5 { let config = random_config(true); let sync_config = EsploraSyncConfig { background_sync_config: None }; @@ -161,7 +162,7 @@ async fn multi_hop_sending() { builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); let node = builder.build(config.node_entropy.into()).unwrap(); node.start().unwrap(); - nodes.push(node); + nodes.push(node.into()); } let addresses = nodes.iter().map(|n| n.onchain_payment().new_address().unwrap()).collect(); @@ -1728,7 +1729,8 @@ async fn do_lsps2_client_service_integration(client_trusts_lsp: bool) { setup_builder!(service_builder, service_config.node_config); service_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); service_builder.set_liquidity_provider_lsps2(lsps2_service_config); - let service_node = service_builder.build(service_config.node_entropy.into()).unwrap(); + let service_node: TestNode = + service_builder.build(service_config.node_entropy.into()).unwrap().into(); service_node.start().unwrap(); let service_node_id = service_node.node_id(); @@ -1738,13 +1740,15 @@ async fn do_lsps2_client_service_integration(client_trusts_lsp: bool) { setup_builder!(client_builder, client_config.node_config); client_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); client_builder.set_liquidity_source_lsps2(service_node_id, service_addr, None); - let client_node = client_builder.build(client_config.node_entropy.into()).unwrap(); + let client_node: TestNode = + client_builder.build(client_config.node_entropy.into()).unwrap().into(); client_node.start().unwrap(); let payer_config = random_config(true); setup_builder!(payer_builder, payer_config.node_config); payer_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); - let payer_node = payer_builder.build(payer_config.node_entropy.into()).unwrap(); + let payer_node: TestNode = + payer_builder.build(payer_config.node_entropy.into()).unwrap().into(); payer_node.start().unwrap(); let service_addr = service_node.onchain_payment().new_address().unwrap(); @@ -2045,7 +2049,8 @@ async fn lsps2_client_trusts_lsp() { setup_builder!(service_builder, service_config.node_config); service_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); service_builder.set_liquidity_provider_lsps2(lsps2_service_config); - let service_node = service_builder.build(service_config.node_entropy.into()).unwrap(); + let service_node: TestNode = + service_builder.build(service_config.node_entropy.into()).unwrap().into(); service_node.start().unwrap(); let service_node_id = service_node.node_id(); let service_addr = service_node.listening_addresses().unwrap().first().unwrap().clone(); @@ -2054,14 +2059,16 @@ async fn lsps2_client_trusts_lsp() { setup_builder!(client_builder, client_config.node_config); client_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); client_builder.set_liquidity_source_lsps2(service_node_id, service_addr.clone(), None); - let client_node = client_builder.build(client_config.node_entropy.into()).unwrap(); + let client_node: TestNode = + client_builder.build(client_config.node_entropy.into()).unwrap().into(); client_node.start().unwrap(); let client_node_id = client_node.node_id(); let payer_config = random_config(true); setup_builder!(payer_builder, payer_config.node_config); payer_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); - let payer_node = payer_builder.build(payer_config.node_entropy.into()).unwrap(); + let payer_node: TestNode = + payer_builder.build(payer_config.node_entropy.into()).unwrap().into(); payer_node.start().unwrap(); let service_addr_onchain = service_node.onchain_payment().new_address().unwrap(); @@ -2218,7 +2225,8 @@ async fn lsps2_lsp_trusts_client_but_client_does_not_claim() { setup_builder!(service_builder, service_config.node_config); service_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); service_builder.set_liquidity_provider_lsps2(lsps2_service_config); - let service_node = service_builder.build(service_config.node_entropy.into()).unwrap(); + let service_node: TestNode = + service_builder.build(service_config.node_entropy.into()).unwrap().into(); service_node.start().unwrap(); let service_node_id = service_node.node_id(); @@ -2228,7 +2236,8 @@ async fn lsps2_lsp_trusts_client_but_client_does_not_claim() { setup_builder!(client_builder, client_config.node_config); client_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); client_builder.set_liquidity_source_lsps2(service_node_id, service_addr.clone(), None); - let client_node = client_builder.build(client_config.node_entropy.into()).unwrap(); + let client_node: TestNode = + client_builder.build(client_config.node_entropy.into()).unwrap().into(); client_node.start().unwrap(); let client_node_id = client_node.node_id(); @@ -2236,7 +2245,8 @@ async fn lsps2_lsp_trusts_client_but_client_does_not_claim() { let payer_config = random_config(true); setup_builder!(payer_builder, payer_config.node_config); payer_builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); - let payer_node = payer_builder.build(payer_config.node_entropy.into()).unwrap(); + let payer_node: TestNode = + payer_builder.build(payer_config.node_entropy.into()).unwrap().into(); payer_node.start().unwrap(); let service_addr_onchain = service_node.onchain_payment().new_address().unwrap();