diff --git a/README.md b/README.md index 7bcfb6f78..df072999d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ A ready-to-go Lightning node library built using [LDK][ldk] and [BDK][bdk]. LDK Node is a self-custodial Lightning node in library form. Its central goal is to provide a small, simple, and straightforward interface that enables users to easily set up and run a Lightning node with an integrated on-chain wallet. While minimalism is at its core, LDK Node aims to be sufficiently modular and configurable to be useful for a variety of use cases. ## Getting Started -The primary abstraction of the library is the [`Node`][api_docs_node], which can be retrieved by setting up and configuring a [`Builder`][api_docs_builder] to your liking and calling one of the `build` methods. `Node` can then be controlled via commands such as `start`, `stop`, `open_channel`, `open_announced_channel`, `send`, etc. +The primary abstraction of the library is the [`Node`][api_docs_node], which can be retrieved by setting up and configuring a [`Builder`][api_docs_builder] to your liking and calling one of the `build` methods. `Node` can then be controlled via commands such as `start`, `stop`, `open_channel`, `send`, etc. ```rust use ldk_node::Builder; diff --git a/src/builder.rs b/src/builder.rs index d2ceb5f22..9faf97714 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -307,9 +307,10 @@ impl NodeBuilder { Ok(self) } - /// Sets the alias the [`Node`] will use in its announcement. + /// Sets the node alias that will be used when broadcasting announcements to the gossip + /// network. /// - /// The provided alias must be a valid UTF-8 string. + /// The provided alias must be a valid UTF-8 string and no longer than 32 bytes in total. pub fn set_node_alias(&mut self, node_alias: String) -> Result<&mut Self, BuildError> { let node_alias = sanitize_alias(&node_alias)?; @@ -515,7 +516,10 @@ impl ArcedNodeBuilder { self.inner.write().unwrap().set_listening_addresses(listening_addresses).map(|_| ()) } - /// Sets the node alias. + /// Sets the node alias that will be used when broadcasting announcements to the gossip + /// network. + /// + /// The provided alias must be a valid UTF-8 string and no longer than 32 bytes in total. pub fn set_node_alias(&self, node_alias: String) -> Result<(), BuildError> { self.inner.write().unwrap().set_node_alias(node_alias).map(|_| ()) } diff --git a/src/config.rs b/src/config.rs index 574789ac6..2ccfc2db9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -87,7 +87,7 @@ pub(crate) const WALLET_KEYS_SEED_LEN: usize = 64; /// | `log_dir_path` | None | /// | `network` | Bitcoin | /// | `listening_addresses` | None | -/// | `node_alias` | None | +/// | `node_alias` | None | /// | `default_cltv_expiry_delta` | 144 | /// | `onchain_wallet_sync_interval_secs` | 80 | /// | `wallet_sync_interval_secs` | 30 | @@ -113,12 +113,14 @@ pub struct Config { pub network: Network, /// The addresses on which the node will listen for incoming connections. /// - /// **Note**: Node announcements will only be broadcast if the `node_alias` and the + /// **Note**: We will only allow opening and accepting public channels if the `node_alias` and the /// `listening_addresses` are set. pub listening_addresses: Option>, - /// The node alias to be used in announcements. + /// The node alias that will be used when broadcasting announcements to the gossip network. /// - /// **Note**: Node announcements will only be broadcast if the `node_alias` and the + /// The provided alias must be a valid UTF-8 string and no longer than 32 bytes in total. + /// + /// **Note**: We will only allow opening and accepting public channels if the `node_alias` and the /// `listening_addresses` are set. pub node_alias: Option, /// The time in-between background sync attempts of the onchain wallet, in seconds. @@ -276,47 +278,9 @@ pub fn default_config() -> Config { Config::default() } -/// Specifies reasons why a channel cannot be announced. -#[derive(Debug, PartialEq)] -pub(crate) enum ChannelAnnouncementBlocker { - /// The node alias is not set. - MissingNodeAlias, - /// The listening addresses are not set. - MissingListeningAddresses, - // This listening addresses is set but the vector is empty. - EmptyListeningAddresses, -} - -/// Enumeration defining the announcement status of a channel. -#[derive(Debug, PartialEq)] -pub(crate) enum ChannelAnnouncementStatus { - /// The channel is announceable. - Announceable, - /// The channel is not announceable. - Unannounceable(ChannelAnnouncementBlocker), -} - -/// Checks if a node is can announce a channel based on the configured values of both the node's -/// alias and its listening addresses. -/// -/// If either of them is unset, the node cannot announce the channel. This ability to announce/ -/// unannounce a channel is codified with `ChannelAnnouncementStatus` -pub(crate) fn can_announce_channel(config: &Config) -> ChannelAnnouncementStatus { - if config.node_alias.is_none() { - return ChannelAnnouncementStatus::Unannounceable( - ChannelAnnouncementBlocker::MissingNodeAlias, - ); - } - - match &config.listening_addresses { - None => ChannelAnnouncementStatus::Unannounceable( - ChannelAnnouncementBlocker::MissingListeningAddresses, - ), - Some(addresses) if addresses.is_empty() => ChannelAnnouncementStatus::Unannounceable( - ChannelAnnouncementBlocker::EmptyListeningAddresses, - ), - Some(_) => ChannelAnnouncementStatus::Announceable, - } +pub(crate) fn may_announce_channel(config: &Config) -> bool { + config.node_alias.is_some() + && config.listening_addresses.as_ref().map_or(false, |addrs| !addrs.is_empty()) } pub(crate) fn default_user_config(config: &Config) -> UserConfig { @@ -331,13 +295,10 @@ pub(crate) fn default_user_config(config: &Config) -> UserConfig { user_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = config.anchor_channels_config.is_some(); - match can_announce_channel(config) { - ChannelAnnouncementStatus::Announceable => (), - ChannelAnnouncementStatus::Unannounceable(_) => { - user_config.accept_forwards_to_priv_channels = false; - user_config.channel_handshake_config.announced_channel = false; - user_config.channel_handshake_limits.force_announced_channel_preference = true; - }, + if !may_announce_channel(config) { + user_config.accept_forwards_to_priv_channels = false; + user_config.channel_handshake_config.announced_channel = false; + user_config.channel_handshake_limits.force_announced_channel_preference = true; } user_config @@ -347,23 +308,16 @@ pub(crate) fn default_user_config(config: &Config) -> UserConfig { mod tests { use std::str::FromStr; - use crate::config::ChannelAnnouncementStatus; - - use super::can_announce_channel; + use super::may_announce_channel; use super::Config; use super::NodeAlias; use super::SocketAddress; #[test] - fn node_can_announce_channel() { + fn node_announce_channel() { // Default configuration with node alias and listening addresses unset let mut node_config = Config::default(); - assert_eq!( - can_announce_channel(&node_config), - ChannelAnnouncementStatus::Unannounceable( - crate::config::ChannelAnnouncementBlocker::MissingNodeAlias - ) - ); + assert!(!may_announce_channel(&node_config)); // Set node alias with listening addresses unset let alias_frm_str = |alias: &str| { @@ -372,21 +326,11 @@ mod tests { NodeAlias(bytes) }; node_config.node_alias = Some(alias_frm_str("LDK_Node")); - assert_eq!( - can_announce_channel(&node_config), - ChannelAnnouncementStatus::Unannounceable( - crate::config::ChannelAnnouncementBlocker::MissingListeningAddresses - ) - ); + assert!(!may_announce_channel(&node_config)); // Set node alias with an empty list of listening addresses node_config.listening_addresses = Some(vec![]); - assert_eq!( - can_announce_channel(&node_config), - ChannelAnnouncementStatus::Unannounceable( - crate::config::ChannelAnnouncementBlocker::EmptyListeningAddresses - ) - ); + assert!(!may_announce_channel(&node_config)); // Set node alias with a non-empty list of listening addresses let socket_address = @@ -394,6 +338,6 @@ mod tests { if let Some(ref mut addresses) = node_config.listening_addresses { addresses.push(socket_address); } - assert_eq!(can_announce_channel(&node_config), ChannelAnnouncementStatus::Announceable); + assert!(may_announce_channel(&node_config)); } } diff --git a/src/lib.rs b/src/lib.rs index 48750f74e..914dec4b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,8 +20,7 @@ //! //! The primary abstraction of the library is the [`Node`], which can be retrieved by setting up //! and configuring a [`Builder`] to your liking and calling [`build`]. `Node` can then be -//! controlled via commands such as [`start`], [`stop`], [`open_channel`], [`open_announced_channel`] -//! [`send`], etc.: +//! controlled via commands such as [`start`], [`stop`], [`open_channel`], [`send`], etc.: //! //! ```no_run //! use ldk_node::Builder; @@ -64,7 +63,6 @@ //! [`start`]: Node::start //! [`stop`]: Node::stop //! [`open_channel`]: Node::open_channel -//! [`open_announced_channel`]: Node::open_announced_channel //! [`send`]: Bolt11Payment::send //! #![cfg_attr(not(feature = "uniffi"), deny(missing_docs))] @@ -100,7 +98,6 @@ mod wallet; pub use bip39; pub use bitcoin; pub use lightning; -use lightning::routing::gossip::NodeAlias; pub use lightning_invoice; pub use balance::{BalanceDetails, LightningBalance, PendingSweepBalance}; @@ -123,8 +120,8 @@ pub use builder::BuildError; pub use builder::NodeBuilder as Builder; use config::{ - can_announce_channel, default_user_config, ChannelAnnouncementStatus, - LDK_WALLET_SYNC_TIMEOUT_SECS, NODE_ANN_BCAST_INTERVAL, PEER_RECONNECTION_INTERVAL, + default_user_config, may_announce_channel, LDK_WALLET_SYNC_TIMEOUT_SECS, + NODE_ANN_BCAST_INTERVAL, PEER_RECONNECTION_INTERVAL, RESOLVED_CHANNEL_MONITOR_ARCHIVAL_INTERVAL, RGS_SYNC_INTERVAL, WALLET_SYNC_INTERVAL_MINIMUM_SECS, }; @@ -151,6 +148,7 @@ use lightning::chain::{BestBlock, Confirm}; use lightning::events::bump_transaction::Wallet as LdkWallet; use lightning::ln::channelmanager::{ChannelShutdownState, PaymentId}; use lightning::ln::msgs::SocketAddress; +use lightning::routing::gossip::NodeAlias; pub use lightning::util::logger::Level as LogLevel; @@ -605,20 +603,20 @@ impl Node { let bcast_ann_timestamp = Arc::clone(&self.latest_node_announcement_broadcast_timestamp); let mut stop_bcast = self.stop_sender.subscribe(); let node_alias = self.config.node_alias.clone(); - let can_announce_channel = can_announce_channel(&self.config); - runtime.spawn(async move { - // We check every 30 secs whether our last broadcast is NODE_ANN_BCAST_INTERVAL away. - #[cfg(not(test))] - let mut interval = tokio::time::interval(Duration::from_secs(30)); - #[cfg(test)] - let mut interval = tokio::time::interval(Duration::from_secs(5)); - loop { - tokio::select! { + if may_announce_channel(&self.config) { + runtime.spawn(async move { + // We check every 30 secs whether our last broadcast is NODE_ANN_BCAST_INTERVAL away. + #[cfg(not(test))] + let mut interval = tokio::time::interval(Duration::from_secs(30)); + #[cfg(test)] + let mut interval = tokio::time::interval(Duration::from_secs(5)); + loop { + tokio::select! { _ = stop_bcast.changed() => { log_trace!( bcast_logger, "Stopping broadcasting node announcements.", - ); + ); return; } _ = interval.tick() => { @@ -648,37 +646,37 @@ impl Node { continue; } - match can_announce_channel { - ChannelAnnouncementStatus::Unannounceable(_) => { - // Skip if we are not listening on any addresses or if the node alias is not set. - continue; - } - ChannelAnnouncementStatus::Announceable => { - // Broadcast node announcement. - let addresses = bcast_config.listening_addresses.clone().unwrap_or(Vec::new()); - if let Some(node_alias) = node_alias.as_ref() { - bcast_pm.broadcast_node_announcement([0; 3], node_alias.0, addresses); - } else { - continue - } - } - } + let addresses = if let Some(addresses) = bcast_config.listening_addresses.clone() { + addresses + } else { + debug_assert!(false, "We checked whether the node may announce, so listening addresses should always be set"); + continue; + }; - let unix_time_secs_opt = - SystemTime::now().duration_since(UNIX_EPOCH).ok().map(|d| d.as_secs()); - *bcast_ann_timestamp.write().unwrap() = unix_time_secs_opt; + if let Some(node_alias) = node_alias.as_ref() { + bcast_pm.broadcast_node_announcement([0; 3], node_alias.0, addresses); - if let Some(unix_time_secs) = unix_time_secs_opt { - io::utils::write_latest_node_ann_bcast_timestamp(unix_time_secs, Arc::clone(&bcast_store), Arc::clone(&bcast_logger)) - .unwrap_or_else(|e| { - log_error!(bcast_logger, "Persistence failed: {}", e); - panic!("Persistence failed"); - }); + let unix_time_secs_opt = + SystemTime::now().duration_since(UNIX_EPOCH).ok().map(|d| d.as_secs()); + *bcast_ann_timestamp.write().unwrap() = unix_time_secs_opt; + + if let Some(unix_time_secs) = unix_time_secs_opt { + io::utils::write_latest_node_ann_bcast_timestamp(unix_time_secs, Arc::clone(&bcast_store), Arc::clone(&bcast_logger)) + .unwrap_or_else(|e| { + log_error!(bcast_logger, "Persistence failed: {}", e); + panic!("Persistence failed"); + }); + } + } else { + debug_assert!(false, "We checked whether the node may announce, so node alias should always be set"); + continue } + } + } } - } - }); + }); + } let mut stop_tx_bcast = self.stop_sender.subscribe(); let tx_bcaster = Arc::clone(&self.tx_broadcaster); @@ -1187,10 +1185,6 @@ impl Node { Ok(()) } - /// Connect to a node and open a new channel. - /// - /// See [`Node::open_channel`] or [`Node::open_announced_channel`] for more information about - /// parameters. fn open_channel_inner( &self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64, push_to_counterparty_msat: Option, channel_config: Option, @@ -1294,7 +1288,9 @@ impl Node { } } - /// Connect to a node and open a new channel. + /// Connect to a node and open a new unannounced channel. + /// + /// To open an announced channel, see [`Node::open_announced_channel`]. /// /// Disconnects and reconnects are handled automatically. /// @@ -1306,8 +1302,6 @@ impl Node { /// [`AnchorChannelsConfig::per_channel_reserve_sats`] is available and will be retained before /// opening the channel. /// - /// Calls `Node::open_channel_inner` with `announce_channel` set to `false`. - /// /// Returns a [`UserChannelId`] allowing to locally keep track of the channel. pub fn open_channel( &self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64, @@ -1325,6 +1319,12 @@ impl Node { /// Connect to a node and open a new announced channel. /// + /// This will return an error if the node has not been sufficiently configured to operate as a + /// forwarding node that can properly announce its existence to the publip network graph, i.e., + /// [`Config::listening_addresses`] and [`Config::node_alias`] are unset. + /// + /// To open an unannounced channel, see [`Node::open_channel`]. + /// /// Disconnects and reconnects are handled automatically. /// /// If `push_to_counterparty_msat` is set, the given value will be pushed (read: sent) to the @@ -1335,37 +1335,23 @@ impl Node { /// [`AnchorChannelsConfig::per_channel_reserve_sats`] is available and will be retained before /// opening the channel. /// - /// Note that, regardless of the value of `announce_channel` passed, this function - /// checks that a node is configured to announce the channel to be openned and returns - /// an error if the configuration is wrong. Otherwise, calls `Node::open_channel_inner` - /// with `announced_channel` equals to `true`. - /// See `config::can_announce_channel` for more details. - /// /// Returns a [`UserChannelId`] allowing to locally keep track of the channel. pub fn open_announced_channel( &self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64, push_to_counterparty_msat: Option, channel_config: Option, ) -> Result { - match can_announce_channel(&self.config) { - config::ChannelAnnouncementStatus::Announceable => self.open_channel_inner( + if may_announce_channel(&self.config) { + self.open_channel_inner( node_id, address, channel_amount_sats, push_to_counterparty_msat, channel_config, true, - ), - config::ChannelAnnouncementStatus::Unannounceable(reason) => match reason { - config::ChannelAnnouncementBlocker::MissingNodeAlias => { - return Err(Error::InvalidNodeAlias) - }, - config::ChannelAnnouncementBlocker::MissingListeningAddresses => { - return Err(Error::InvalidSocketAddress) - }, - config::ChannelAnnouncementBlocker::EmptyListeningAddresses => { - return Err(Error::InvalidSocketAddress) - }, - }, + ) + } else { + log_error!(self.logger, "Failed to open announced channel as the node hasn't been sufficiently configured to act as a forwarding node. Please make sure to configure listening addreesses and node alias"); + return Err(Error::ChannelCreationFailed); } } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 4dcbfd999..f8a9eae7a 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -203,37 +203,20 @@ pub(crate) fn random_listening_addresses() -> Vec { pub(crate) fn random_node_alias() -> Option { let mut rng = thread_rng(); - let ranged_val = rng.gen_range(0..10); - - let alias = format!("ldk-node-{}", ranged_val); + let rand_val = rng.gen_range(0..1000); + let alias = format!("ldk-node-{}", rand_val); let mut bytes = [0u8; 32]; bytes[..alias.as_bytes().len()].copy_from_slice(alias.as_bytes()); - Some(NodeAlias(bytes)) } -pub(crate) fn random_announce_channel() -> bool { - let mut rng = thread_rng(); - let ranged_val = rng.gen_range(0..=1); - match ranged_val { - 0 => false, - _ => true, - } -} - -pub(crate) fn random_config(anchor_channels: bool, announce_channel: bool) -> Config { +pub(crate) fn random_config(anchor_channels: bool) -> Config { let mut config = Config::default(); if !anchor_channels { config.anchor_channels_config = None; } - if announce_channel { - let alias = random_node_alias(); - println!("Setting random LDK node alias: {:?}", alias); - config.node_alias = alias; - } - config.network = Network::Regtest; config.onchain_wallet_sync_interval_secs = 100000; config.wallet_sync_interval_secs = 100000; @@ -247,6 +230,10 @@ pub(crate) fn random_config(anchor_channels: bool, announce_channel: bool) -> Co println!("Setting random LDK listening addresses: {:?}", rand_listening_addresses); config.listening_addresses = Some(rand_listening_addresses); + let alias = random_node_alias(); + println!("Setting random LDK node alias: {:?}", alias); + config.node_alias = alias; + config.log_level = LogLevel::Gossip; config @@ -269,15 +256,14 @@ macro_rules! setup_builder { pub(crate) use setup_builder; pub(crate) fn setup_two_nodes( - electrsd: &ElectrsD, allow_0conf: bool, anchor_channels: bool, - anchors_trusted_no_reserve: bool, announce_channel: bool, + electrsd: &ElectrsD, allow_0conf: bool, anchor_channels: bool, anchors_trusted_no_reserve: bool, ) -> (TestNode, TestNode) { println!("== Node A =="); - let config_a = random_config(anchor_channels, announce_channel); + let config_a = random_config(anchor_channels); let node_a = setup_node(electrsd, config_a); println!("\n== Node B =="); - let mut config_b = random_config(anchor_channels, announce_channel); + let mut config_b = random_config(anchor_channels); if allow_0conf { config_b.trusted_peers_0conf.push(node_a.node_id()); } @@ -413,9 +399,10 @@ pub(crate) fn premine_and_distribute_funds( } pub fn open_channel( - node_a: &TestNode, node_b: &TestNode, funding_amount_sat: u64, electrsd: &ElectrsD, + node_a: &TestNode, node_b: &TestNode, funding_amount_sat: u64, should_announce: bool, + electrsd: &ElectrsD, ) { - if node_a.config().node_alias.is_some() { + if should_announce { node_a .open_announced_channel( node_b.node_id(), @@ -436,7 +423,6 @@ pub fn open_channel( ) .unwrap(); } - assert!(node_a.list_peers().iter().find(|c| { c.node_id == node_b.node_id() }).is_some()); let funding_txo_a = expect_channel_pending_event!(node_a, node_b.node_id()); @@ -472,28 +458,15 @@ pub(crate) fn do_channel_full_cycle( println!("\nA -- open_channel -> B"); let funding_amount_sat = 2_080_000; let push_msat = (funding_amount_sat / 2) * 1000; // balance the channel - - if node_a.config().node_alias.is_some() { - node_a - .open_announced_channel( - node_b.node_id(), - node_b.listening_addresses().unwrap().first().unwrap().clone(), - funding_amount_sat, - Some(push_msat), - None, - ) - .unwrap(); - } else { - node_a - .open_channel( - node_b.node_id(), - node_b.listening_addresses().unwrap().first().unwrap().clone(), - funding_amount_sat, - Some(push_msat), - None, - ) - .unwrap(); - } + node_a + .open_announced_channel( + node_b.node_id(), + node_b.listening_addresses().unwrap().first().unwrap().clone(), + funding_amount_sat, + Some(push_msat), + None, + ) + .unwrap(); assert_eq!(node_a.list_peers().first().unwrap().node_id, node_b.node_id()); assert!(node_a.list_peers().first().unwrap().is_persisted); diff --git a/tests/integration_tests_cln.rs b/tests/integration_tests_cln.rs index 11065bfe6..13b5c44c6 100644 --- a/tests/integration_tests_cln.rs +++ b/tests/integration_tests_cln.rs @@ -9,7 +9,6 @@ mod common; -use common::random_announce_channel; use ldk_node::bitcoin::secp256k1::PublicKey; use ldk_node::bitcoin::Amount; use ldk_node::lightning::ln::msgs::SocketAddress; @@ -44,7 +43,7 @@ fn test_cln() { common::generate_blocks_and_wait(&bitcoind_client, &electrs_client, 1); // Setup LDK Node - let config = common::random_config(true, random_announce_channel()); + let config = common::random_config(true); let mut builder = Builder::from_config(config); builder.set_esplora_server("http://127.0.0.1:3002".to_string()); @@ -83,19 +82,8 @@ fn test_cln() { // Open the channel let funding_amount_sat = 1_000_000; - if node.config().node_alias.is_none() { - node.open_channel(cln_node_id, cln_address, funding_amount_sat, Some(500_000_000), None) - .unwrap(); - } else { - node.open_announced_channel( - cln_node_id, - cln_address, - funding_amount_sat, - Some(500_000_000), - None, - ) + node.open_channel(cln_node_id, cln_address, funding_amount_sat, Some(500_000_000), None) .unwrap(); - } let funding_txo = common::expect_channel_pending_event!(node, cln_node_id); common::wait_for_tx(&electrs_client, funding_txo.txid); diff --git a/tests/integration_tests_rust.rs b/tests/integration_tests_rust.rs index 9c244e90a..907e89084 100644 --- a/tests/integration_tests_rust.rs +++ b/tests/integration_tests_rust.rs @@ -10,9 +10,8 @@ mod common; use common::{ do_channel_full_cycle, expect_channel_ready_event, expect_event, expect_payment_received_event, expect_payment_successful_event, generate_blocks_and_wait, open_channel, - premine_and_distribute_funds, random_announce_channel, random_config, - setup_bitcoind_and_electrsd, setup_builder, setup_node, setup_two_nodes, wait_for_tx, - TestSyncStore, + premine_and_distribute_funds, random_config, setup_bitcoind_and_electrsd, setup_builder, + setup_node, setup_two_nodes, wait_for_tx, TestSyncStore, }; use ldk_node::payment::{PaymentKind, QrPaymentResult, SendingParameters}; @@ -28,46 +27,42 @@ use std::sync::Arc; #[test] fn channel_full_cycle() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, false); do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, true, false); } #[test] fn channel_full_cycle_force_close() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, false); do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, true, true); } #[test] fn channel_full_cycle_force_close_trusted_no_reserve() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, true, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, true); do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, true, true); } #[test] fn channel_full_cycle_0conf() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = setup_two_nodes(&electrsd, true, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, true, true, false); do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, true, true, false) } #[test] fn channel_full_cycle_legacy_staticremotekey() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, false, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, false, false); do_channel_full_cycle(node_a, node_b, &bitcoind.client, &electrsd.client, false, false, false); } #[test] fn channel_open_fails_when_funds_insufficient() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, false); let addr_a = node_a.onchain_payment().new_address().unwrap(); let addr_b = node_b.onchain_payment().new_address().unwrap(); @@ -88,23 +83,13 @@ fn channel_open_fails_when_funds_insufficient() { println!("\nA -- open_channel -> B"); assert_eq!( Err(NodeError::InsufficientFunds), - if node_a.config().node_alias.is_some() { - node_a.open_announced_channel( - node_b.node_id(), - node_b.listening_addresses().unwrap().first().unwrap().clone(), - 120000, - None, - None, - ) - } else { - node_a.open_channel( - node_b.node_id(), - node_b.listening_addresses().unwrap().first().unwrap().clone(), - 120000, - None, - None, - ) - } + node_a.open_channel( + node_b.node_id(), + node_b.listening_addresses().unwrap().first().unwrap().clone(), + 120000, + None, + None, + ) ); } @@ -115,9 +100,8 @@ fn multi_hop_sending() { // Setup and fund 5 nodes let mut nodes = Vec::new(); - let announce_channel = random_announce_channel(); for _ in 0..5 { - let config = random_config(true, announce_channel); + let config = random_config(true); setup_builder!(builder, config); builder.set_esplora_server(esplora_url.clone()); let node = builder.build().unwrap(); @@ -147,16 +131,16 @@ fn multi_hop_sending() { // \ / // (1M:0)- N3 -(1M:0) - open_channel(&nodes[0], &nodes[1], 100_000, &electrsd); - open_channel(&nodes[1], &nodes[2], 1_000_000, &electrsd); + open_channel(&nodes[0], &nodes[1], 100_000, true, &electrsd); + open_channel(&nodes[1], &nodes[2], 1_000_000, true, &electrsd); // We need to sync wallets in-between back-to-back channel opens from the same node so BDK // wallet picks up on the broadcast funding tx and doesn't double-spend itself. // // TODO: Remove once fixed in BDK. nodes[1].sync_wallets().unwrap(); - open_channel(&nodes[1], &nodes[3], 1_000_000, &electrsd); - open_channel(&nodes[2], &nodes[4], 1_000_000, &electrsd); - open_channel(&nodes[3], &nodes[4], 1_000_000, &electrsd); + open_channel(&nodes[1], &nodes[3], 1_000_000, true, &electrsd); + open_channel(&nodes[2], &nodes[4], 1_000_000, true, &electrsd); + open_channel(&nodes[3], &nodes[4], 1_000_000, true, &electrsd); generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6); @@ -186,22 +170,16 @@ fn multi_hop_sending() { }; let invoice = nodes[4].bolt11_payment().receive(2_500_000, &"asdf", 9217).unwrap(); - let send_res = nodes[0].bolt11_payment().send(&invoice, Some(sending_params)); + nodes[0].bolt11_payment().send(&invoice, Some(sending_params)).unwrap(); - // N0 cannot find a route to N4 if node and channel is unannounced. - if nodes[0].config().node_alias.is_none() { - assert_eq!(send_res, Err(NodeError::PaymentSendingFailed)) - } else { - let payment_id = expect_payment_received_event!(&nodes[4], 2_500_000); - assert_eq!(send_res.unwrap(), payment_id.unwrap()); - let fee_paid_msat = Some(2000); - expect_payment_successful_event!(nodes[0], payment_id, Some(fee_paid_msat)); - } + let payment_id = expect_payment_received_event!(&nodes[4], 2_500_000); + let fee_paid_msat = Some(2000); + expect_payment_successful_event!(nodes[0], payment_id, Some(fee_paid_msat)); } #[test] fn connect_to_public_testnet_esplora() { - let mut config = random_config(true, random_announce_channel()); + let mut config = random_config(true); config.network = Network::Testnet; setup_builder!(builder, config); builder.set_esplora_server("https://blockstream.info/testnet/api".to_string()); @@ -213,7 +191,7 @@ fn connect_to_public_testnet_esplora() { #[test] fn start_stop_reinit() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let config = random_config(true, random_announce_channel()); + let config = random_config(true); let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap()); @@ -281,8 +259,7 @@ fn start_stop_reinit() { #[test] fn onchain_spend_receive() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, false); let addr_a = node_a.onchain_payment().new_address().unwrap(); let addr_b = node_b.onchain_payment().new_address().unwrap(); @@ -330,7 +307,7 @@ fn onchain_spend_receive() { #[test] fn sign_verify_msg() { let (_bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let config = random_config(true, random_announce_channel()); + let config = random_config(true); let node = setup_node(&electrsd, config); // Tests arbitrary message signing and later verification @@ -348,8 +325,7 @@ fn connection_restart_behavior() { fn do_connection_restart_behavior(persist: bool) { let (_bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, false, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, false, false); let node_id_a = node_a.node_id(); let node_id_b = node_b.node_id(); @@ -400,8 +376,7 @@ fn do_connection_restart_behavior(persist: bool) { #[test] fn concurrent_connections_succeed() { let (_bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, false); let node_a = Arc::new(node_a); let node_b = Arc::new(node_b); @@ -431,8 +406,7 @@ fn concurrent_connections_succeed() { #[test] fn simple_bolt12_send_receive() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, false); let address_a = node_a.onchain_payment().new_address().unwrap(); let premine_amount_sat = 5_000_000; @@ -444,7 +418,7 @@ fn simple_bolt12_send_receive() { ); node_a.sync_wallets().unwrap(); - open_channel(&node_a, &node_b, 4_000_000, &electrsd); + open_channel(&node_a, &node_b, 4_000_000, true, &electrsd); generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6); @@ -454,203 +428,191 @@ fn simple_bolt12_send_receive() { expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); - // For announced nodes, we make a trivial check that node_alias is set knowing that - // `random_listening_addresses()` always sets the listening_addresses. This check - // is important to prevent the test from looping endlessly. - if node_a.config().node_alias.is_some() && node_b.config().node_alias.is_some() { - // Sleep until we broadcasted a node announcement. - while node_b.status().latest_node_announcement_broadcast_timestamp.is_none() { - std::thread::sleep(std::time::Duration::from_millis(10)); - } - - // Sleep one more sec to make sure the node announcement propagates. - std::thread::sleep(std::time::Duration::from_secs(1)); + // Sleep until we broadcasted a node announcement. + while node_b.status().latest_node_announcement_broadcast_timestamp.is_none() { + std::thread::sleep(std::time::Duration::from_millis(10)); } + // Sleep one more sec to make sure the node announcement propagates. + std::thread::sleep(std::time::Duration::from_secs(1)); + let expected_amount_msat = 100_000_000; - let offer_res = node_b.bolt12_payment().receive(expected_amount_msat, "asdf", Some(1)); - if node_a.config().node_alias.is_none() && node_b.config().node_alias.is_none() { - // Node must be announced if alternative one-hop `BlindedPath` is to be used. - assert_eq!(offer_res, Err(NodeError::OfferCreationFailed)) - } else { - let offer = offer_res.unwrap(); - let expected_quantity = Some(1); - let expected_payer_note = Some("Test".to_string()); - let payment_id = node_a - .bolt12_payment() - .send(&offer, expected_quantity, expected_payer_note.clone()) - .unwrap(); - - expect_payment_successful_event!(node_a, Some(payment_id), None); - let node_a_payments = node_a.list_payments(); - assert_eq!(node_a_payments.len(), 1); - match node_a_payments.first().unwrap().kind { - PaymentKind::Bolt12Offer { - hash, - preimage, - secret: _, - offer_id, - quantity: ref qty, - payer_note: ref note, - } => { - assert!(hash.is_some()); - assert!(preimage.is_some()); - assert_eq!(offer_id, offer.id()); - assert_eq!(&expected_quantity, qty); - assert_eq!(expected_payer_note.unwrap(), note.clone().unwrap().0); - //TODO: We should eventually set and assert the secret sender-side, too, but the BOLT12 - //API currently doesn't allow to do that. - }, - _ => { - panic!("Unexpected payment kind"); - }, - } - assert_eq!(node_a_payments.first().unwrap().amount_msat, Some(expected_amount_msat)); - - expect_payment_received_event!(node_b, expected_amount_msat); - let node_b_payments = node_b.list_payments(); - assert_eq!(node_b_payments.len(), 1); - match node_b_payments.first().unwrap().kind { - PaymentKind::Bolt12Offer { hash, preimage, secret, offer_id, .. } => { - assert!(hash.is_some()); - assert!(preimage.is_some()); - assert!(secret.is_some()); - assert_eq!(offer_id, offer.id()); - }, - _ => { - panic!("Unexpected payment kind"); - }, - } - assert_eq!(node_b_payments.first().unwrap().amount_msat, Some(expected_amount_msat)); - - // Test send_using_amount - let offer_amount_msat = 100_000_000; - let less_than_offer_amount = offer_amount_msat - 10_000; - let expected_amount_msat = offer_amount_msat + 10_000; - let offer = node_b.bolt12_payment().receive(offer_amount_msat, "asdf", Some(1)).unwrap(); - let expected_quantity = Some(1); - let expected_payer_note = Some("Test".to_string()); - assert!(node_a - .bolt12_payment() - .send_using_amount(&offer, less_than_offer_amount, None, None) - .is_err()); - let payment_id = node_a - .bolt12_payment() - .send_using_amount( - &offer, - expected_amount_msat, - expected_quantity, - expected_payer_note.clone(), - ) - .unwrap(); - - expect_payment_successful_event!(node_a, Some(payment_id), None); - let node_a_payments = node_a.list_payments_with_filter(|p| p.id == payment_id); - assert_eq!(node_a_payments.len(), 1); - let payment_hash = match node_a_payments.first().unwrap().kind { - PaymentKind::Bolt12Offer { - hash, - preimage, - secret: _, - offer_id, - quantity: ref qty, - payer_note: ref note, - } => { - assert!(hash.is_some()); - assert!(preimage.is_some()); - assert_eq!(offer_id, offer.id()); - assert_eq!(&expected_quantity, qty); - assert_eq!(expected_payer_note.unwrap(), note.clone().unwrap().0); - //TODO: We should eventually set and assert the secret sender-side, too, but the BOLT12 - //API currently doesn't allow to do that. - hash.unwrap() - }, - _ => { - panic!("Unexpected payment kind"); - }, - }; - assert_eq!(node_a_payments.first().unwrap().amount_msat, Some(expected_amount_msat)); - - expect_payment_received_event!(node_b, expected_amount_msat); - let node_b_payment_id = PaymentId(payment_hash.0); - let node_b_payments = node_b.list_payments_with_filter(|p| p.id == node_b_payment_id); - assert_eq!(node_b_payments.len(), 1); - match node_b_payments.first().unwrap().kind { - PaymentKind::Bolt12Offer { hash, preimage, secret, offer_id, .. } => { - assert!(hash.is_some()); - assert!(preimage.is_some()); - assert!(secret.is_some()); - assert_eq!(offer_id, offer.id()); - }, - _ => { - panic!("Unexpected payment kind"); - }, - } - assert_eq!(node_b_payments.first().unwrap().amount_msat, Some(expected_amount_msat)); - - // Now node_b refunds the amount node_a just overpaid. - let overpaid_amount = expected_amount_msat - offer_amount_msat; - let expected_quantity = Some(1); - let expected_payer_note = Some("Test".to_string()); - let refund = node_b - .bolt12_payment() - .initiate_refund(overpaid_amount, 3600, expected_quantity, expected_payer_note.clone()) - .unwrap(); - let invoice = node_a.bolt12_payment().request_refund_payment(&refund).unwrap(); - expect_payment_received_event!(node_a, overpaid_amount); - - let node_b_payment_id = node_b - .list_payments_with_filter(|p| p.amount_msat == Some(overpaid_amount)) - .first() - .unwrap() - .id; - expect_payment_successful_event!(node_b, Some(node_b_payment_id), None); - - let node_b_payments = node_b.list_payments_with_filter(|p| p.id == node_b_payment_id); - assert_eq!(node_b_payments.len(), 1); - match node_b_payments.first().unwrap().kind { - PaymentKind::Bolt12Refund { - hash, - preimage, - secret: _, - quantity: ref qty, - payer_note: ref note, - } => { - assert!(hash.is_some()); - assert!(preimage.is_some()); - assert_eq!(&expected_quantity, qty); - assert_eq!(expected_payer_note.unwrap(), note.clone().unwrap().0) - //TODO: We should eventually set and assert the secret sender-side, too, but the BOLT12 - //API currently doesn't allow to do that. - }, - _ => { - panic!("Unexpected payment kind"); - }, - } - assert_eq!(node_b_payments.first().unwrap().amount_msat, Some(overpaid_amount)); - - let node_a_payment_id = PaymentId(invoice.payment_hash().0); - let node_a_payments = node_a.list_payments_with_filter(|p| p.id == node_a_payment_id); - assert_eq!(node_a_payments.len(), 1); - match node_a_payments.first().unwrap().kind { - PaymentKind::Bolt12Refund { hash, preimage, secret, .. } => { - assert!(hash.is_some()); - assert!(preimage.is_some()); - assert!(secret.is_some()); - }, - _ => { - panic!("Unexpected payment kind"); - }, - } - assert_eq!(node_a_payments.first().unwrap().amount_msat, Some(overpaid_amount)); + let offer = node_b.bolt12_payment().receive(expected_amount_msat, "asdf", Some(1)).unwrap(); + let expected_quantity = Some(1); + let expected_payer_note = Some("Test".to_string()); + let payment_id = node_a + .bolt12_payment() + .send(&offer, expected_quantity, expected_payer_note.clone()) + .unwrap(); + + expect_payment_successful_event!(node_a, Some(payment_id), None); + let node_a_payments = node_a.list_payments(); + assert_eq!(node_a_payments.len(), 1); + match node_a_payments.first().unwrap().kind { + PaymentKind::Bolt12Offer { + hash, + preimage, + secret: _, + offer_id, + quantity: ref qty, + payer_note: ref note, + } => { + assert!(hash.is_some()); + assert!(preimage.is_some()); + assert_eq!(offer_id, offer.id()); + assert_eq!(&expected_quantity, qty); + assert_eq!(expected_payer_note.unwrap(), note.clone().unwrap().0); + //TODO: We should eventually set and assert the secret sender-side, too, but the BOLT12 + //API currently doesn't allow to do that. + }, + _ => { + panic!("Unexpected payment kind"); + }, + } + assert_eq!(node_a_payments.first().unwrap().amount_msat, Some(expected_amount_msat)); + + expect_payment_received_event!(node_b, expected_amount_msat); + let node_b_payments = node_b.list_payments(); + assert_eq!(node_b_payments.len(), 1); + match node_b_payments.first().unwrap().kind { + PaymentKind::Bolt12Offer { hash, preimage, secret, offer_id, .. } => { + assert!(hash.is_some()); + assert!(preimage.is_some()); + assert!(secret.is_some()); + assert_eq!(offer_id, offer.id()); + }, + _ => { + panic!("Unexpected payment kind"); + }, + } + assert_eq!(node_b_payments.first().unwrap().amount_msat, Some(expected_amount_msat)); + + // Test send_using_amount + let offer_amount_msat = 100_000_000; + let less_than_offer_amount = offer_amount_msat - 10_000; + let expected_amount_msat = offer_amount_msat + 10_000; + let offer = node_b.bolt12_payment().receive(offer_amount_msat, "asdf", Some(1)).unwrap(); + let expected_quantity = Some(1); + let expected_payer_note = Some("Test".to_string()); + assert!(node_a + .bolt12_payment() + .send_using_amount(&offer, less_than_offer_amount, None, None) + .is_err()); + let payment_id = node_a + .bolt12_payment() + .send_using_amount( + &offer, + expected_amount_msat, + expected_quantity, + expected_payer_note.clone(), + ) + .unwrap(); + + expect_payment_successful_event!(node_a, Some(payment_id), None); + let node_a_payments = node_a.list_payments_with_filter(|p| p.id == payment_id); + assert_eq!(node_a_payments.len(), 1); + let payment_hash = match node_a_payments.first().unwrap().kind { + PaymentKind::Bolt12Offer { + hash, + preimage, + secret: _, + offer_id, + quantity: ref qty, + payer_note: ref note, + } => { + assert!(hash.is_some()); + assert!(preimage.is_some()); + assert_eq!(offer_id, offer.id()); + assert_eq!(&expected_quantity, qty); + assert_eq!(expected_payer_note.unwrap(), note.clone().unwrap().0); + //TODO: We should eventually set and assert the secret sender-side, too, but the BOLT12 + //API currently doesn't allow to do that. + hash.unwrap() + }, + _ => { + panic!("Unexpected payment kind"); + }, + }; + assert_eq!(node_a_payments.first().unwrap().amount_msat, Some(expected_amount_msat)); + + expect_payment_received_event!(node_b, expected_amount_msat); + let node_b_payment_id = PaymentId(payment_hash.0); + let node_b_payments = node_b.list_payments_with_filter(|p| p.id == node_b_payment_id); + assert_eq!(node_b_payments.len(), 1); + match node_b_payments.first().unwrap().kind { + PaymentKind::Bolt12Offer { hash, preimage, secret, offer_id, .. } => { + assert!(hash.is_some()); + assert!(preimage.is_some()); + assert!(secret.is_some()); + assert_eq!(offer_id, offer.id()); + }, + _ => { + panic!("Unexpected payment kind"); + }, + } + assert_eq!(node_b_payments.first().unwrap().amount_msat, Some(expected_amount_msat)); + + // Now node_b refunds the amount node_a just overpaid. + let overpaid_amount = expected_amount_msat - offer_amount_msat; + let expected_quantity = Some(1); + let expected_payer_note = Some("Test".to_string()); + let refund = node_b + .bolt12_payment() + .initiate_refund(overpaid_amount, 3600, expected_quantity, expected_payer_note.clone()) + .unwrap(); + let invoice = node_a.bolt12_payment().request_refund_payment(&refund).unwrap(); + expect_payment_received_event!(node_a, overpaid_amount); + + let node_b_payment_id = node_b + .list_payments_with_filter(|p| p.amount_msat == Some(overpaid_amount)) + .first() + .unwrap() + .id; + expect_payment_successful_event!(node_b, Some(node_b_payment_id), None); + + let node_b_payments = node_b.list_payments_with_filter(|p| p.id == node_b_payment_id); + assert_eq!(node_b_payments.len(), 1); + match node_b_payments.first().unwrap().kind { + PaymentKind::Bolt12Refund { + hash, + preimage, + secret: _, + quantity: ref qty, + payer_note: ref note, + } => { + assert!(hash.is_some()); + assert!(preimage.is_some()); + assert_eq!(&expected_quantity, qty); + assert_eq!(expected_payer_note.unwrap(), note.clone().unwrap().0) + //TODO: We should eventually set and assert the secret sender-side, too, but the BOLT12 + //API currently doesn't allow to do that. + }, + _ => { + panic!("Unexpected payment kind"); + }, + } + assert_eq!(node_b_payments.first().unwrap().amount_msat, Some(overpaid_amount)); + + let node_a_payment_id = PaymentId(invoice.payment_hash().0); + let node_a_payments = node_a.list_payments_with_filter(|p| p.id == node_a_payment_id); + assert_eq!(node_a_payments.len(), 1); + match node_a_payments.first().unwrap().kind { + PaymentKind::Bolt12Refund { hash, preimage, secret, .. } => { + assert!(hash.is_some()); + assert!(preimage.is_some()); + assert!(secret.is_some()); + }, + _ => { + panic!("Unexpected payment kind"); + }, } + assert_eq!(node_a_payments.first().unwrap().amount_msat, Some(overpaid_amount)); } #[test] fn generate_bip21_uri() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, false); let address_a = node_a.onchain_payment().new_address().unwrap(); let premined_sats = 5_000_000; @@ -663,7 +625,7 @@ fn generate_bip21_uri() { ); node_a.sync_wallets().unwrap(); - open_channel(&node_a, &node_b, 4_000_000, &electrsd); + open_channel(&node_a, &node_b, 4_000_000, true, &electrsd); generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6); node_a.sync_wallets().unwrap(); @@ -677,26 +639,21 @@ fn generate_bip21_uri() { let uqr_payment = node_b.unified_qr_payment().receive(expected_amount_sats, "asdf", expiry_sec); - if node_a.config().node_alias.is_none() && node_b.config().node_alias.is_none() { - assert_eq!(uqr_payment, Err(NodeError::OfferCreationFailed)); - } else { - match uqr_payment.clone() { - Ok(ref uri) => { - println!("Generated URI: {}", uri); - assert!(uri.contains("BITCOIN:")); - assert!(uri.contains("lightning=")); - assert!(uri.contains("lno=")); - }, - Err(e) => panic!("Failed to generate URI: {:?}", e), - } + match uqr_payment.clone() { + Ok(ref uri) => { + println!("Generated URI: {}", uri); + assert!(uri.contains("BITCOIN:")); + assert!(uri.contains("lightning=")); + assert!(uri.contains("lno=")); + }, + Err(e) => panic!("Failed to generate URI: {:?}", e), } } #[test] fn unified_qr_send_receive() { let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); - let (node_a, node_b) = - setup_two_nodes(&electrsd, false, true, false, random_announce_channel()); + let (node_a, node_b) = setup_two_nodes(&electrsd, false, true, false); let address_a = node_a.onchain_payment().new_address().unwrap(); let premined_sats = 5_000_000; @@ -709,7 +666,7 @@ fn unified_qr_send_receive() { ); node_a.sync_wallets().unwrap(); - open_channel(&node_a, &node_b, 4_000_000, &electrsd); + open_channel(&node_a, &node_b, 4_000_000, true, &electrsd); generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6); node_a.sync_wallets().unwrap(); @@ -718,98 +675,88 @@ fn unified_qr_send_receive() { expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); - // For announced nodes, we make a trivial check that node_alias is set knowing that - // `random_listening_addresses()` always sets the listening_addresses. This check - // is important to prevent the test from looping endlessly. - if node_a.config().node_alias.is_some() && node_b.config().node_alias.is_some() { - // Sleep until we broadcasted a node announcement. - while node_b.status().latest_node_announcement_broadcast_timestamp.is_none() { - std::thread::sleep(std::time::Duration::from_millis(10)); - } - - // Sleep one more sec to make sure the node announcement propagates. - std::thread::sleep(std::time::Duration::from_secs(1)); + // Sleep until we broadcast a node announcement. + while node_b.status().latest_node_announcement_broadcast_timestamp.is_none() { + std::thread::sleep(std::time::Duration::from_millis(10)); } + // Sleep one more sec to make sure the node announcement propagates. + std::thread::sleep(std::time::Duration::from_secs(1)); + let expected_amount_sats = 100_000; let expiry_sec = 4_000; let uqr_payment = node_b.unified_qr_payment().receive(expected_amount_sats, "asdf", expiry_sec); - if node_a.config().node_alias.is_none() && node_b.config().node_alias.is_none() { - // Node must be announced if alternative one-hop `BlindedPath` is to be used used. - assert_eq!(uqr_payment, Err(NodeError::OfferCreationFailed)) - } else { - let uri_str = uqr_payment.clone().unwrap(); - let offer_payment_id: PaymentId = match node_a.unified_qr_payment().send(&uri_str) { - Ok(QrPaymentResult::Bolt12 { payment_id }) => { - println!("\nBolt12 payment sent successfully with PaymentID: {:?}", payment_id); - payment_id - }, - Ok(QrPaymentResult::Bolt11 { payment_id: _ }) => { - panic!("Expected Bolt12 payment but got Bolt11"); - }, - Ok(QrPaymentResult::Onchain { txid: _ }) => { - panic!("Expected Bolt12 payment but get On-chain transaction"); - }, - Err(e) => { - panic!("Expected Bolt12 payment but got error: {:?}", e); - }, - }; + let uri_str = uqr_payment.clone().unwrap(); + let offer_payment_id: PaymentId = match node_a.unified_qr_payment().send(&uri_str) { + Ok(QrPaymentResult::Bolt12 { payment_id }) => { + println!("\nBolt12 payment sent successfully with PaymentID: {:?}", payment_id); + payment_id + }, + Ok(QrPaymentResult::Bolt11 { payment_id: _ }) => { + panic!("Expected Bolt12 payment but got Bolt11"); + }, + Ok(QrPaymentResult::Onchain { txid: _ }) => { + panic!("Expected Bolt12 payment but get On-chain transaction"); + }, + Err(e) => { + panic!("Expected Bolt12 payment but got error: {:?}", e); + }, + }; - expect_payment_successful_event!(node_a, Some(offer_payment_id), None); - - // Removed one character from the offer to fall back on to invoice. - // Still needs work - let uri_str_with_invalid_offer = &uri_str[..uri_str.len() - 1]; - let invoice_payment_id: PaymentId = - match node_a.unified_qr_payment().send(uri_str_with_invalid_offer) { - Ok(QrPaymentResult::Bolt12 { payment_id: _ }) => { - panic!("Expected Bolt11 payment but got Bolt12"); - }, - Ok(QrPaymentResult::Bolt11 { payment_id }) => { - println!("\nBolt11 payment sent successfully with PaymentID: {:?}", payment_id); - payment_id - }, - Ok(QrPaymentResult::Onchain { txid: _ }) => { - panic!("Expected Bolt11 payment but got on-chain transaction"); - }, - Err(e) => { - panic!("Expected Bolt11 payment but got error: {:?}", e); - }, - }; - expect_payment_successful_event!(node_a, Some(invoice_payment_id), None); - - let expect_onchain_amount_sats = 800_000; - let onchain_uqr_payment = - node_b.unified_qr_payment().receive(expect_onchain_amount_sats, "asdf", 4_000).unwrap(); - - // Removed a character from the offer, so it would move on to the other parameters. - let txid = match node_a - .unified_qr_payment() - .send(&onchain_uqr_payment.as_str()[..onchain_uqr_payment.len() - 1]) - { + expect_payment_successful_event!(node_a, Some(offer_payment_id), None); + + // Removed one character from the offer to fall back on to invoice. + // Still needs work + let uri_str_with_invalid_offer = &uri_str[..uri_str.len() - 1]; + let invoice_payment_id: PaymentId = + match node_a.unified_qr_payment().send(uri_str_with_invalid_offer) { Ok(QrPaymentResult::Bolt12 { payment_id: _ }) => { - panic!("Expected on-chain payment but got Bolt12") + panic!("Expected Bolt11 payment but got Bolt12"); }, - Ok(QrPaymentResult::Bolt11 { payment_id: _ }) => { - panic!("Expected on-chain payment but got Bolt11"); + Ok(QrPaymentResult::Bolt11 { payment_id }) => { + println!("\nBolt11 payment sent successfully with PaymentID: {:?}", payment_id); + payment_id }, - Ok(QrPaymentResult::Onchain { txid }) => { - println!("\nOn-chain transaction successful with Txid: {}", txid); - txid + Ok(QrPaymentResult::Onchain { txid: _ }) => { + panic!("Expected Bolt11 payment but got on-chain transaction"); }, Err(e) => { - panic!("Expected on-chain payment but got error: {:?}", e); + panic!("Expected Bolt11 payment but got error: {:?}", e); }, }; + expect_payment_successful_event!(node_a, Some(invoice_payment_id), None); + + let expect_onchain_amount_sats = 800_000; + let onchain_uqr_payment = + node_b.unified_qr_payment().receive(expect_onchain_amount_sats, "asdf", 4_000).unwrap(); + + // Removed a character from the offer, so it would move on to the other parameters. + let txid = match node_a + .unified_qr_payment() + .send(&onchain_uqr_payment.as_str()[..onchain_uqr_payment.len() - 1]) + { + Ok(QrPaymentResult::Bolt12 { payment_id: _ }) => { + panic!("Expected on-chain payment but got Bolt12") + }, + Ok(QrPaymentResult::Bolt11 { payment_id: _ }) => { + panic!("Expected on-chain payment but got Bolt11"); + }, + Ok(QrPaymentResult::Onchain { txid }) => { + println!("\nOn-chain transaction successful with Txid: {}", txid); + txid + }, + Err(e) => { + panic!("Expected on-chain payment but got error: {:?}", e); + }, + }; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6); - wait_for_tx(&electrsd.client, txid); + generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6); + wait_for_tx(&electrsd.client, txid); - node_a.sync_wallets().unwrap(); - node_b.sync_wallets().unwrap(); + node_a.sync_wallets().unwrap(); + node_b.sync_wallets().unwrap(); - assert_eq!(node_b.list_balances().total_onchain_balance_sats, 800_000); - assert_eq!(node_b.list_balances().total_lightning_balance_sats, 200_000); - } + assert_eq!(node_b.list_balances().total_onchain_balance_sats, 800_000); + assert_eq!(node_b.list_balances().total_lightning_balance_sats, 200_000); } diff --git a/tests/integration_tests_vss.rs b/tests/integration_tests_vss.rs index b7fc8ba42..c572fbcd8 100644 --- a/tests/integration_tests_vss.rs +++ b/tests/integration_tests_vss.rs @@ -9,7 +9,6 @@ mod common; -use common::random_announce_channel; use ldk_node::Builder; #[test] @@ -17,8 +16,7 @@ fn channel_full_cycle_with_vss_store() { let (bitcoind, electrsd) = common::setup_bitcoind_and_electrsd(); println!("== Node A =="); let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap()); - let announce_channel = random_announce_channel(); - let config_a = common::random_config(true, announce_channel); + let config_a = common::random_config(true); let mut builder_a = Builder::from_config(config_a); builder_a.set_esplora_server(esplora_url.clone()); let vss_base_url = std::env::var("TEST_VSS_BASE_URL").unwrap(); @@ -27,7 +25,7 @@ fn channel_full_cycle_with_vss_store() { node_a.start().unwrap(); println!("\n== Node B =="); - let config_b = common::random_config(true, announce_channel); + let config_b = common::random_config(true); let mut builder_b = Builder::from_config(config_b); builder_b.set_esplora_server(esplora_url); let node_b = builder_b.build_with_vss_store(vss_base_url, "node_2_store".to_string()).unwrap();