Skip to content

Follow-ups to #330 #366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading