Skip to content

Commit

Permalink
Merge pull request #366 from tnull/2024-10-330-followups
Browse files Browse the repository at this point in the history
  • Loading branch information
tnull authored Oct 8, 2024
2 parents c9ebeb6 + 85862f5 commit 58188b8
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 555 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 7 additions & 3 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;

Expand Down Expand Up @@ -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(|_| ())
}
Expand Down
94 changes: 19 additions & 75 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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<Vec<SocketAddress>>,
/// 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<NodeAlias>,
/// The time in-between background sync attempts of the onchain wallet, in seconds.
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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| {
Expand All @@ -372,28 +326,18 @@ 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 =
SocketAddress::from_str("localhost:8000").expect("Socket address conversion failed.");
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));
}
}
Loading

0 comments on commit 58188b8

Please sign in to comment.