ldk_node/
config.rs

1// This file is Copyright its original authors, visible in version control history.
2//
3// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
6// accordance with one or both of these licenses.
7
8//! Objects for configuring the node.
9
10use std::fmt;
11use std::time::Duration;
12
13use bitcoin::secp256k1::PublicKey;
14use bitcoin::Network;
15use lightning::ln::msgs::SocketAddress;
16use lightning::routing::gossip::NodeAlias;
17use lightning::routing::router::RouteParametersConfig;
18use lightning::util::config::{
19	ChannelConfig as LdkChannelConfig, MaxDustHTLCExposure as LdkMaxDustHTLCExposure, UserConfig,
20};
21
22use crate::logger::LogLevel;
23
24// Config defaults
25const DEFAULT_NETWORK: Network = Network::Bitcoin;
26const DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS: u64 = 80;
27const DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS: u64 = 30;
28const DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 10;
29const DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER: u64 = 3;
30const DEFAULT_ANCHOR_PER_CHANNEL_RESERVE_SATS: u64 = 25_000;
31
32/// The default log level.
33pub const DEFAULT_LOG_LEVEL: LogLevel = LogLevel::Debug;
34
35/// The default log file name.
36pub const DEFAULT_LOG_FILENAME: &'static str = "ldk_node.log";
37
38/// The default storage directory.
39pub const DEFAULT_STORAGE_DIR_PATH: &str = "/tmp/ldk_node";
40
41// The default Esplora server we're using.
42pub(crate) const DEFAULT_ESPLORA_SERVER_URL: &str = "https://blockstream.info/api";
43
44// The default Esplora client timeout we're using.
45pub(crate) const DEFAULT_ESPLORA_CLIENT_TIMEOUT_SECS: u64 = 10;
46
47// The 'stop gap' parameter used by BDK's wallet sync. This seems to configure the threshold
48// number of derivation indexes after which BDK stops looking for new scripts belonging to the wallet.
49pub(crate) const BDK_CLIENT_STOP_GAP: usize = 20;
50
51// The number of concurrent requests made against the API provider.
52pub(crate) const BDK_CLIENT_CONCURRENCY: usize = 4;
53
54// The timeout after which we abandon retrying failed payments.
55pub(crate) const LDK_PAYMENT_RETRY_TIMEOUT: Duration = Duration::from_secs(10);
56
57// The interval (in block height) after which we retry archiving fully resolved channel monitors.
58pub(crate) const RESOLVED_CHANNEL_MONITOR_ARCHIVAL_INTERVAL: u32 = 6;
59
60// The time in-between peer reconnection attempts.
61pub(crate) const PEER_RECONNECTION_INTERVAL: Duration = Duration::from_secs(60);
62
63// The time in-between RGS sync attempts.
64pub(crate) const RGS_SYNC_INTERVAL: Duration = Duration::from_secs(60 * 60);
65
66// The time in-between external scores sync attempts.
67pub(crate) const EXTERNAL_PATHFINDING_SCORES_SYNC_INTERVAL: Duration = Duration::from_secs(60 * 60);
68
69// The time in-between node announcement broadcast attempts.
70pub(crate) const NODE_ANN_BCAST_INTERVAL: Duration = Duration::from_secs(60 * 60);
71
72// The lower limit which we apply to any configured wallet sync intervals.
73pub(crate) const WALLET_SYNC_INTERVAL_MINIMUM_SECS: u64 = 10;
74
75// The timeout after which we abort a wallet syncing operation.
76pub(crate) const BDK_WALLET_SYNC_TIMEOUT_SECS: u64 = 20;
77
78// The timeout after which we abort a wallet syncing operation.
79pub(crate) const LDK_WALLET_SYNC_TIMEOUT_SECS: u64 = 10;
80
81// The timeout after which we give up waiting on LDK's event handler to exit on shutdown.
82pub(crate) const LDK_EVENT_HANDLER_SHUTDOWN_TIMEOUT_SECS: u64 = 30;
83
84// The timeout after which we give up waiting on a background task to exit on shutdown.
85pub(crate) const BACKGROUND_TASK_SHUTDOWN_TIMEOUT_SECS: u64 = 5;
86
87// The timeout after which we abort a fee rate cache update operation.
88pub(crate) const FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS: u64 = 5;
89
90// The timeout after which we abort a transaction broadcast operation.
91pub(crate) const TX_BROADCAST_TIMEOUT_SECS: u64 = 5;
92
93// The timeout after which we abort a RGS sync operation.
94pub(crate) const RGS_SYNC_TIMEOUT_SECS: u64 = 5;
95
96/// The length in bytes of our wallets' keys seed.
97pub const WALLET_KEYS_SEED_LEN: usize = 64;
98
99// The timeout after which we abort a external scores sync operation.
100pub(crate) const EXTERNAL_PATHFINDING_SCORES_SYNC_TIMEOUT_SECS: u64 = 5;
101
102#[derive(Debug, Clone)]
103/// Represents the configuration of an [`Node`] instance.
104///
105/// ### Defaults
106///
107/// | Parameter                              | Value              |
108/// |----------------------------------------|--------------------|
109/// | `storage_dir_path`                     | /tmp/ldk_node/     |
110/// | `log_dir_path`                         | None               |
111/// | `network`                              | Bitcoin            |
112/// | `listening_addresses`                  | None               |
113/// | `node_alias`                           | None               |
114/// | `default_cltv_expiry_delta`            | 144                |
115/// | `onchain_wallet_sync_interval_secs`    | 80                 |
116/// | `wallet_sync_interval_secs`            | 30                 |
117/// | `fee_rate_cache_update_interval_secs`  | 600                |
118/// | `trusted_peers_0conf`                  | []                 |
119/// | `probing_liquidity_limit_multiplier`   | 3                  |
120/// | `log_level`                            | Debug              |
121/// | `anchor_channels_config`               | Some(..)           |
122/// | `route_parameters`                   | None               |
123///
124/// See [`AnchorChannelsConfig`] and [`RouteParametersConfig`] for more information regarding their
125/// respective default values.
126///
127/// [`Node`]: crate::Node
128pub struct Config {
129	/// The path where the underlying LDK and BDK persist their data.
130	pub storage_dir_path: String,
131	/// The used Bitcoin network.
132	pub network: Network,
133	/// The addresses on which the node will listen for incoming connections.
134	///
135	/// **Note**: We will only allow opening and accepting public channels if the `node_alias` and the
136	/// `listening_addresses` are set.
137	pub listening_addresses: Option<Vec<SocketAddress>>,
138	/// The addresses which the node will announce to the gossip network that it accepts connections on.
139	///
140	/// **Note**: If unset, the [`listening_addresses`] will be used as the list of addresses to announce.
141	///
142	/// [`listening_addresses`]: Config::listening_addresses
143	pub announcement_addresses: Option<Vec<SocketAddress>>,
144	/// The node alias that will be used when broadcasting announcements to the gossip network.
145	///
146	/// The provided alias must be a valid UTF-8 string and no longer than 32 bytes in total.
147	///
148	/// **Note**: We will only allow opening and accepting public channels if the `node_alias` and the
149	/// `listening_addresses` are set.
150	pub node_alias: Option<NodeAlias>,
151	/// A list of peers that we allow to establish zero confirmation channels to us.
152	///
153	/// **Note:** Allowing payments via zero-confirmation channels is potentially insecure if the
154	/// funding transaction ends up never being confirmed on-chain. Zero-confirmation channels
155	/// should therefore only be accepted from trusted peers.
156	pub trusted_peers_0conf: Vec<PublicKey>,
157	/// The liquidity factor by which we filter the outgoing channels used for sending probes.
158	///
159	/// Channels with available liquidity less than the required amount times this value won't be
160	/// used to send pre-flight probes.
161	pub probing_liquidity_limit_multiplier: u64,
162	/// Configuration options pertaining to Anchor channels, i.e., channels for which the
163	/// `option_anchors_zero_fee_htlc_tx` channel type is negotiated.
164	///
165	/// Please refer to [`AnchorChannelsConfig`] for further information on Anchor channels.
166	///
167	/// If set to `Some`, we'll try to open new channels with Anchors enabled, i.e., new channels
168	/// will be negotiated with the `option_anchors_zero_fee_htlc_tx` channel type if supported by
169	/// the counterparty. Note that this won't prevent us from opening non-Anchor channels if the
170	/// counterparty doesn't support `option_anchors_zero_fee_htlc_tx`. If set to `None`, new
171	/// channels will be negotiated with the legacy `option_static_remotekey` channel type only.
172	///
173	/// **Note:** If set to `None` *after* some Anchor channels have already been
174	/// opened, no dedicated emergency on-chain reserve will be maintained for these channels,
175	/// which can be dangerous if only insufficient funds are available at the time of channel
176	/// closure. We *will* however still try to get the Anchor spending transactions confirmed
177	/// on-chain with the funds available.
178	pub anchor_channels_config: Option<AnchorChannelsConfig>,
179	/// Configuration options for payment routing and pathfinding.
180	///
181	/// Setting the [`RouteParametersConfig`] provides flexibility to customize how payments are routed,
182	/// including setting limits on routing fees, CLTV expiry, and channel utilization.
183	///
184	/// **Note:** If unset, default parameters will be used, and you will be able to override the
185	/// parameters on a per-payment basis in the corresponding method calls.
186	pub route_parameters: Option<RouteParametersConfig>,
187}
188
189impl Default for Config {
190	fn default() -> Self {
191		Self {
192			storage_dir_path: DEFAULT_STORAGE_DIR_PATH.to_string(),
193			network: DEFAULT_NETWORK,
194			listening_addresses: None,
195			announcement_addresses: None,
196			trusted_peers_0conf: Vec::new(),
197			probing_liquidity_limit_multiplier: DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER,
198			anchor_channels_config: Some(AnchorChannelsConfig::default()),
199			route_parameters: None,
200			node_alias: None,
201		}
202	}
203}
204
205/// Configuration options pertaining to 'Anchor' channels, i.e., channels for which the
206/// `option_anchors_zero_fee_htlc_tx` channel type is negotiated.
207///
208/// Prior to the introduction of Anchor channels, the on-chain fees paying for the transactions
209/// issued on channel closure were pre-determined and locked-in at the time of the channel
210/// opening. This required to estimate what fee rate would be sufficient to still have the
211/// closing transactions be spendable on-chain (i.e., not be considered dust). This legacy
212/// design of pre-anchor channels proved inadequate in the unpredictable, often turbulent, fee
213/// markets we experience today.
214///
215/// In contrast, Anchor channels allow to determine an adequate fee rate *at the time of channel
216/// closure*, making them much more robust in the face of fee spikes. In turn, they require to
217/// maintain a reserve of on-chain funds to have the channel closure transactions confirmed
218/// on-chain, at least if the channel counterparty can't be trusted to do this for us.
219///
220/// See [BOLT 3] for more technical details on Anchor channels.
221///
222///
223/// ### Defaults
224///
225/// | Parameter                  | Value  |
226/// |----------------------------|--------|
227/// | `trusted_peers_no_reserve` | []     |
228/// | `per_channel_reserve_sats` | 25000  |
229///
230///
231/// [BOLT 3]: https://github.com/lightning/bolts/blob/master/03-transactions.md#htlc-timeout-and-htlc-success-transactions
232#[derive(Debug, Clone)]
233pub struct AnchorChannelsConfig {
234	/// A list of peers that we trust to get the required channel closing transactions confirmed
235	/// on-chain.
236	///
237	/// Channels with these peers won't count towards the retained on-chain reserve and we won't
238	/// take any action to get the required channel closing transactions confirmed ourselves.
239	///
240	/// **Note:** Trusting the channel counterparty to take the necessary actions to get the
241	/// required Anchor spending transactions confirmed on-chain is potentially insecure
242	/// as the channel may not be closed if they refuse to do so.
243	pub trusted_peers_no_reserve: Vec<PublicKey>,
244	/// The amount of satoshis per anchors-negotiated channel with an untrusted peer that we keep
245	/// as an emergency reserve in our on-chain wallet.
246	///
247	/// This allows for having the required Anchor output spending and HTLC transactions confirmed
248	/// when the channel is closed.
249	///
250	/// If the channel peer is not marked as trusted via
251	/// [`AnchorChannelsConfig::trusted_peers_no_reserve`], we will always try to spend the Anchor
252	/// outputs with *any* on-chain funds available, i.e., the total reserve value as well as any
253	/// spendable funds available in the on-chain wallet. Therefore, this per-channel multiplier is
254	/// really a emergency reserve that we maintain at all time to reduce reduce the risk of
255	/// insufficient funds at time of a channel closure. To this end, we will refuse to open
256	/// outbound or accept inbound channels if we don't have sufficient on-chain funds available to
257	/// cover the additional reserve requirement.
258	///
259	/// **Note:** Depending on the fee market at the time of closure, this reserve amount might or
260	/// might not suffice to successfully spend the Anchor output and have the HTLC transactions
261	/// confirmed on-chain, i.e., you may want to adjust this value accordingly.
262	pub per_channel_reserve_sats: u64,
263}
264
265impl Default for AnchorChannelsConfig {
266	fn default() -> Self {
267		Self {
268			trusted_peers_no_reserve: Vec::new(),
269			per_channel_reserve_sats: DEFAULT_ANCHOR_PER_CHANNEL_RESERVE_SATS,
270		}
271	}
272}
273
274/// Returns a [`Config`] object populated with default values.
275///
276/// See the documentation of [`Config`] for more information on the used defaults.
277///
278/// This is mostly meant for use in bindings, in Rust this is synonymous with
279/// [`Config::default()`].
280pub fn default_config() -> Config {
281	Config::default()
282}
283
284#[derive(Debug, PartialEq)]
285pub(crate) enum AnnounceError {
286	MissingNodeAlias,
287	MissingListeningAddresses,
288	MissingAliasAndAddresses,
289}
290
291impl fmt::Display for AnnounceError {
292	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293		match self {
294			AnnounceError::MissingNodeAlias => write!(f, "Node alias is not configured"),
295			AnnounceError::MissingListeningAddresses => {
296				write!(f, "Listening addresses are not configured")
297			},
298			AnnounceError::MissingAliasAndAddresses => {
299				write!(f, "Node alias and listening addresses are not configured")
300			},
301		}
302	}
303}
304
305pub(crate) fn may_announce_channel(config: &Config) -> Result<(), AnnounceError> {
306	let has_listening_addresses =
307		config.listening_addresses.as_ref().map_or(false, |addrs| !addrs.is_empty());
308
309	match (config.node_alias.is_some(), has_listening_addresses) {
310		(true, true) => Ok(()),
311		(true, false) => Err(AnnounceError::MissingListeningAddresses),
312		(false, true) => Err(AnnounceError::MissingNodeAlias),
313		(false, false) => Err(AnnounceError::MissingAliasAndAddresses),
314	}
315}
316
317pub(crate) fn default_user_config(config: &Config) -> UserConfig {
318	// Initialize the default config values.
319	//
320	// Note that methods such as Node::open_channel and Node::open_announced_channel might override
321	// some of the values set here, e.g. the ChannelHandshakeConfig, meaning these default values
322	// will mostly be relevant for inbound channels.
323	let mut user_config = UserConfig::default();
324	user_config.channel_handshake_limits.force_announced_channel_preference = false;
325	user_config.manually_accept_inbound_channels = true;
326	user_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx =
327		config.anchor_channels_config.is_some();
328	user_config.reject_inbound_splices = false;
329
330	if may_announce_channel(config).is_err() {
331		user_config.accept_forwards_to_priv_channels = false;
332		user_config.channel_handshake_config.announce_for_forwarding = false;
333		user_config.channel_handshake_limits.force_announced_channel_preference = true;
334	}
335
336	user_config
337}
338
339/// Options related to background syncing the Lightning and on-chain wallets.
340///
341/// ### Defaults
342///
343/// | Parameter                              | Value              |
344/// |----------------------------------------|--------------------|
345/// | `onchain_wallet_sync_interval_secs`    | 80                 |
346/// | `lightning_wallet_sync_interval_secs`  | 30                 |
347/// | `fee_rate_cache_update_interval_secs`  | 600                |
348#[derive(Debug, Copy, Clone, PartialEq, Eq)]
349pub struct BackgroundSyncConfig {
350	/// The time in-between background sync attempts of the onchain wallet, in seconds.
351	///
352	/// **Note:** A minimum of 10 seconds is enforced when background syncing is enabled.
353	pub onchain_wallet_sync_interval_secs: u64,
354
355	/// The time in-between background sync attempts of the LDK wallet, in seconds.
356	///
357	/// **Note:** A minimum of 10 seconds is enforced when background syncing is enabled.
358	pub lightning_wallet_sync_interval_secs: u64,
359
360	/// The time in-between background update attempts to our fee rate cache, in seconds.
361	///
362	/// **Note:** A minimum of 10 seconds is enforced when background syncing is enabled.
363	pub fee_rate_cache_update_interval_secs: u64,
364}
365
366impl Default for BackgroundSyncConfig {
367	fn default() -> Self {
368		Self {
369			onchain_wallet_sync_interval_secs: DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS,
370			lightning_wallet_sync_interval_secs: DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS,
371			fee_rate_cache_update_interval_secs: DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS,
372		}
373	}
374}
375
376/// Configuration for syncing with an Esplora backend.
377///
378/// Background syncing is enabled by default, using the default values specified in
379/// [`BackgroundSyncConfig`].
380#[derive(Debug, Copy, Clone, PartialEq, Eq)]
381pub struct EsploraSyncConfig {
382	/// Background sync configuration.
383	///
384	/// If set to `None`, background syncing will be disabled. Users will need to manually
385	/// sync via [`Node::sync_wallets`] for the wallets and fee rate updates.
386	///
387	/// [`Node::sync_wallets`]: crate::Node::sync_wallets
388	pub background_sync_config: Option<BackgroundSyncConfig>,
389}
390
391impl Default for EsploraSyncConfig {
392	fn default() -> Self {
393		Self { background_sync_config: Some(BackgroundSyncConfig::default()) }
394	}
395}
396
397/// Configuration for syncing with an Electrum backend.
398///
399/// Background syncing is enabled by default, using the default values specified in
400/// [`BackgroundSyncConfig`].
401#[derive(Debug, Copy, Clone, PartialEq, Eq)]
402pub struct ElectrumSyncConfig {
403	/// Background sync configuration.
404	///
405	/// If set to `None`, background syncing will be disabled. Users will need to manually
406	/// sync via [`Node::sync_wallets`] for the wallets and fee rate updates.
407	///
408	/// [`Node::sync_wallets`]: crate::Node::sync_wallets
409	pub background_sync_config: Option<BackgroundSyncConfig>,
410}
411
412impl Default for ElectrumSyncConfig {
413	fn default() -> Self {
414		Self { background_sync_config: Some(BackgroundSyncConfig::default()) }
415	}
416}
417
418/// Configuration for syncing with Bitcoin Core backend via REST.
419#[derive(Debug, Clone)]
420pub struct BitcoindRestClientConfig {
421	/// Host URL.
422	pub rest_host: String,
423	/// Host port.
424	pub rest_port: u16,
425}
426
427/// Options which apply on a per-channel basis and may change at runtime or based on negotiation
428/// with our counterparty.
429#[derive(Copy, Clone, Debug, PartialEq, Eq)]
430pub struct ChannelConfig {
431	/// Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound
432	/// over the channel.
433	/// This may be allowed to change at runtime in a later update, however doing so must result in
434	/// update messages sent to notify all nodes of our updated relay fee.
435	///
436	/// Please refer to [`LdkChannelConfig`] for further details.
437	pub forwarding_fee_proportional_millionths: u32,
438	/// Amount (in milli-satoshi) charged for payments forwarded outbound over the channel, in
439	/// excess of [`ChannelConfig::forwarding_fee_proportional_millionths`].
440	/// This may be allowed to change at runtime in a later update, however doing so must result in
441	/// update messages sent to notify all nodes of our updated relay fee.
442	///
443	/// Please refer to [`LdkChannelConfig`] for further details.
444	pub forwarding_fee_base_msat: u32,
445	/// The difference in the CLTV value between incoming HTLCs and an outbound HTLC forwarded over
446	/// the channel this config applies to.
447	///
448	/// Please refer to [`LdkChannelConfig`] for further details.
449	pub cltv_expiry_delta: u16,
450	/// Limit our total exposure to potential loss to on-chain fees on close, including in-flight
451	/// HTLCs which are burned to fees as they are too small to claim on-chain and fees on
452	/// commitment transaction(s) broadcasted by our counterparty in excess of our own fee estimate.
453	///
454	/// Please refer to [`LdkChannelConfig`] for further details.
455	pub max_dust_htlc_exposure: MaxDustHTLCExposure,
456	/// The additional fee we're willing to pay to avoid waiting for the counterparty's
457	/// `to_self_delay` to reclaim funds.
458	///
459	/// Please refer to [`LdkChannelConfig`] for further details.
460	pub force_close_avoidance_max_fee_satoshis: u64,
461	/// If set, allows this channel's counterparty to skim an additional fee off this node's inbound
462	/// HTLCs. Useful for liquidity providers to offload on-chain channel costs to end users.
463	///
464	/// Please refer to [`LdkChannelConfig`] for further details.
465	pub accept_underpaying_htlcs: bool,
466}
467
468impl From<LdkChannelConfig> for ChannelConfig {
469	fn from(value: LdkChannelConfig) -> Self {
470		Self {
471			forwarding_fee_proportional_millionths: value.forwarding_fee_proportional_millionths,
472			forwarding_fee_base_msat: value.forwarding_fee_base_msat,
473			cltv_expiry_delta: value.cltv_expiry_delta,
474			max_dust_htlc_exposure: value.max_dust_htlc_exposure.into(),
475			force_close_avoidance_max_fee_satoshis: value.force_close_avoidance_max_fee_satoshis,
476			accept_underpaying_htlcs: value.accept_underpaying_htlcs,
477		}
478	}
479}
480
481impl From<ChannelConfig> for LdkChannelConfig {
482	fn from(value: ChannelConfig) -> Self {
483		Self {
484			forwarding_fee_proportional_millionths: value.forwarding_fee_proportional_millionths,
485			forwarding_fee_base_msat: value.forwarding_fee_base_msat,
486			cltv_expiry_delta: value.cltv_expiry_delta,
487			max_dust_htlc_exposure: value.max_dust_htlc_exposure.into(),
488			force_close_avoidance_max_fee_satoshis: value.force_close_avoidance_max_fee_satoshis,
489			accept_underpaying_htlcs: value.accept_underpaying_htlcs,
490		}
491	}
492}
493
494impl Default for ChannelConfig {
495	fn default() -> Self {
496		LdkChannelConfig::default().into()
497	}
498}
499
500/// Options for how to set the max dust exposure allowed on a channel.
501///
502/// See [`LdkChannelConfig::max_dust_htlc_exposure`] for details.
503#[derive(Copy, Clone, Debug, PartialEq, Eq)]
504pub enum MaxDustHTLCExposure {
505	/// This sets a fixed limit on the total dust exposure in millisatoshis.
506	///
507	/// Please refer to [`LdkMaxDustHTLCExposure`] for further details.
508	FixedLimit {
509		/// The fixed limit, in millisatoshis.
510		limit_msat: u64,
511	},
512	/// This sets a multiplier on the feerate to determine the maximum allowed dust exposure.
513	///
514	/// Please refer to [`LdkMaxDustHTLCExposure`] for further details.
515	FeeRateMultiplier {
516		/// The applied fee rate multiplier.
517		multiplier: u64,
518	},
519}
520
521impl From<LdkMaxDustHTLCExposure> for MaxDustHTLCExposure {
522	fn from(value: LdkMaxDustHTLCExposure) -> Self {
523		match value {
524			LdkMaxDustHTLCExposure::FixedLimitMsat(limit_msat) => Self::FixedLimit { limit_msat },
525			LdkMaxDustHTLCExposure::FeeRateMultiplier(multiplier) => {
526				Self::FeeRateMultiplier { multiplier }
527			},
528		}
529	}
530}
531
532impl From<MaxDustHTLCExposure> for LdkMaxDustHTLCExposure {
533	fn from(value: MaxDustHTLCExposure) -> Self {
534		match value {
535			MaxDustHTLCExposure::FixedLimit { limit_msat } => Self::FixedLimitMsat(limit_msat),
536			MaxDustHTLCExposure::FeeRateMultiplier { multiplier } => {
537				Self::FeeRateMultiplier(multiplier)
538			},
539		}
540	}
541}
542
543#[derive(Debug, Clone, Copy)]
544/// The role of the node in an asynchronous payments context.
545///
546/// See <https://github.com/lightning/bolts/pull/1149> for more information about the async payments protocol.
547pub enum AsyncPaymentsRole {
548	/// Node acts a client in an async payments context. This means that if possible, it will instruct its peers to hold
549	/// HTLCs for it, so that it can go offline.
550	Client,
551	/// Node acts as a server in an async payments context. This means that it will hold async payments HTLCs and onion
552	/// messages for its peers.
553	Server,
554}
555
556#[cfg(test)]
557mod tests {
558	use std::str::FromStr;
559
560	use super::{may_announce_channel, AnnounceError, Config, NodeAlias, SocketAddress};
561
562	#[test]
563	fn node_announce_channel() {
564		// Default configuration with node alias and listening addresses unset
565		let mut node_config = Config::default();
566		assert_eq!(
567			may_announce_channel(&node_config),
568			Err(AnnounceError::MissingAliasAndAddresses)
569		);
570
571		// Set node alias with listening addresses unset
572		let alias_frm_str = |alias: &str| {
573			let mut bytes = [0u8; 32];
574			bytes[..alias.as_bytes().len()].copy_from_slice(alias.as_bytes());
575			NodeAlias(bytes)
576		};
577		node_config.node_alias = Some(alias_frm_str("LDK_Node"));
578		assert_eq!(
579			may_announce_channel(&node_config),
580			Err(AnnounceError::MissingListeningAddresses)
581		);
582
583		// Set announcement addresses with listening addresses unset
584		let announcement_address = SocketAddress::from_str("123.45.67.89:9735")
585			.expect("Socket address conversion failed.");
586		node_config.announcement_addresses = Some(vec![announcement_address]);
587		assert_eq!(
588			may_announce_channel(&node_config),
589			Err(AnnounceError::MissingListeningAddresses)
590		);
591
592		// Set node alias with an empty list of listening addresses
593		node_config.listening_addresses = Some(vec![]);
594		assert_eq!(
595			may_announce_channel(&node_config),
596			Err(AnnounceError::MissingListeningAddresses)
597		);
598
599		// Set node alias with a non-empty list of listening addresses
600		let socket_address =
601			SocketAddress::from_str("localhost:8000").expect("Socket address conversion failed.");
602		if let Some(ref mut addresses) = node_config.listening_addresses {
603			addresses.push(socket_address);
604		}
605		assert!(may_announce_channel(&node_config).is_ok());
606	}
607}