Skip to content

Commit 18a04ea

Browse files
committed
f: config via builder enum setter
1 parent 8271a22 commit 18a04ea

File tree

6 files changed

+107
-66
lines changed

6 files changed

+107
-66
lines changed

src/builder.rs

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
use crate::chain::ChainSource;
99
use crate::config::{
10-
default_user_config, may_announce_channel, AnnounceError, BitcoindRestClientConfig, Config,
11-
ElectrumSyncConfig, EsploraSyncConfig, DEFAULT_ESPLORA_SERVER_URL, DEFAULT_LOG_FILENAME,
12-
DEFAULT_LOG_LEVEL, WALLET_KEYS_SEED_LEN,
10+
default_user_config, may_announce_channel, AnnounceError, AsyncPaymentsRole,
11+
BitcoindRestClientConfig, Config, ElectrumSyncConfig, EsploraSyncConfig,
12+
DEFAULT_ESPLORA_SERVER_URL, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL, WALLET_KEYS_SEED_LEN,
1313
};
1414

1515
use crate::connection::ConnectionManager;
@@ -242,6 +242,7 @@ pub struct NodeBuilder {
242242
liquidity_source_config: Option<LiquiditySourceConfig>,
243243
log_writer_config: Option<LogWriterConfig>,
244244
runtime_handle: Option<tokio::runtime::Handle>,
245+
async_payments_role: Option<AsyncPaymentsRole>,
245246
}
246247

247248
impl NodeBuilder {
@@ -267,6 +268,7 @@ impl NodeBuilder {
267268
liquidity_source_config,
268269
log_writer_config,
269270
runtime_handle,
271+
async_payments_role: None,
270272
}
271273
}
272274

@@ -545,6 +547,12 @@ impl NodeBuilder {
545547
Ok(self)
546548
}
547549

550+
/// Sets the role of the node in an asynchronous payments context.
551+
pub fn set_async_payments_role(&mut self, role: Option<AsyncPaymentsRole>) -> &mut Self {
552+
self.async_payments_role = role;
553+
self
554+
}
555+
548556
/// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
549557
/// previously configured.
550558
pub fn build(&self) -> Result<Node, BuildError> {
@@ -705,6 +713,7 @@ impl NodeBuilder {
705713
runtime,
706714
logger,
707715
Arc::new(vss_store),
716+
self.async_payments_role,
708717
)
709718
}
710719

@@ -737,6 +746,7 @@ impl NodeBuilder {
737746
runtime,
738747
logger,
739748
kv_store,
749+
self.async_payments_role,
740750
)
741751
}
742752
}
@@ -1085,6 +1095,7 @@ fn build_with_store_internal(
10851095
gossip_source_config: Option<&GossipSourceConfig>,
10861096
liquidity_source_config: Option<&LiquiditySourceConfig>, seed_bytes: [u8; 64],
10871097
runtime: Arc<Runtime>, logger: Arc<Logger>, kv_store: Arc<DynStore>,
1098+
async_payments_role: Option<AsyncPaymentsRole>,
10881099
) -> Result<Node, BuildError> {
10891100
optionally_install_rustls_cryptoprovider();
10901101

@@ -1379,8 +1390,14 @@ fn build_with_store_internal(
13791390
100;
13801391
}
13811392

1382-
if config.async_payment_services_enabled {
1383-
user_config.accept_forwards_to_priv_channels = true;
1393+
if let Some(role) = async_payments_role {
1394+
match role {
1395+
AsyncPaymentsRole::Server => {
1396+
user_config.accept_forwards_to_priv_channels = true;
1397+
user_config.enable_htlc_hold = true;
1398+
},
1399+
AsyncPaymentsRole::Client => user_config.hold_outbound_htlcs_at_next_hop = true,
1400+
}
13841401
}
13851402

13861403
let message_router =
@@ -1453,31 +1470,32 @@ fn build_with_store_internal(
14531470
}
14541471

14551472
// Initialize the PeerManager
1456-
let onion_messenger: Arc<OnionMessenger> = if config.async_payment_services_enabled {
1457-
Arc::new(OnionMessenger::new_with_offline_peer_interception(
1458-
Arc::clone(&keys_manager),
1459-
Arc::clone(&keys_manager),
1460-
Arc::clone(&logger),
1461-
Arc::clone(&channel_manager),
1462-
message_router,
1463-
Arc::clone(&channel_manager),
1464-
Arc::clone(&channel_manager),
1465-
IgnoringMessageHandler {},
1466-
IgnoringMessageHandler {},
1467-
))
1468-
} else {
1469-
Arc::new(OnionMessenger::new(
1470-
Arc::clone(&keys_manager),
1471-
Arc::clone(&keys_manager),
1472-
Arc::clone(&logger),
1473-
Arc::clone(&channel_manager),
1474-
message_router,
1475-
Arc::clone(&channel_manager),
1476-
Arc::clone(&channel_manager),
1477-
IgnoringMessageHandler {},
1478-
IgnoringMessageHandler {},
1479-
))
1480-
};
1473+
let onion_messenger: Arc<OnionMessenger> =
1474+
if let Some(AsyncPaymentsRole::Server) = async_payments_role {
1475+
Arc::new(OnionMessenger::new_with_offline_peer_interception(
1476+
Arc::clone(&keys_manager),
1477+
Arc::clone(&keys_manager),
1478+
Arc::clone(&logger),
1479+
Arc::clone(&channel_manager),
1480+
message_router,
1481+
Arc::clone(&channel_manager),
1482+
Arc::clone(&channel_manager),
1483+
IgnoringMessageHandler {},
1484+
IgnoringMessageHandler {},
1485+
))
1486+
} else {
1487+
Arc::new(OnionMessenger::new(
1488+
Arc::clone(&keys_manager),
1489+
Arc::clone(&keys_manager),
1490+
Arc::clone(&logger),
1491+
Arc::clone(&channel_manager),
1492+
message_router,
1493+
Arc::clone(&channel_manager),
1494+
Arc::clone(&channel_manager),
1495+
IgnoringMessageHandler {},
1496+
IgnoringMessageHandler {},
1497+
))
1498+
};
14811499
let ephemeral_bytes: [u8; 32] = keys_manager.get_secure_random_bytes();
14821500

14831501
// Initialize the GossipSource
@@ -1664,7 +1682,7 @@ fn build_with_store_internal(
16641682
},
16651683
};
16661684

1667-
let om_mailbox = if config.async_payment_services_enabled {
1685+
let om_mailbox = if let Some(AsyncPaymentsRole::Server) = async_payments_role {
16681686
Some(Arc::new(OnionMessageMailbox::new()))
16691687
} else {
16701688
None
@@ -1703,6 +1721,7 @@ fn build_with_store_internal(
17031721
is_listening,
17041722
node_metrics,
17051723
om_mailbox,
1724+
async_payments_role,
17061725
})
17071726
}
17081727

src/config.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -179,15 +179,6 @@ pub struct Config {
179179
/// **Note:** If unset, default parameters will be used, and you will be able to override the
180180
/// parameters on a per-payment basis in the corresponding method calls.
181181
pub route_parameters: Option<RouteParametersConfig>,
182-
/// Whether to enable the static invoice service to support async payment reception for clients.
183-
pub async_payment_services_enabled: bool,
184-
/// If this is set to true, then if we as an often-offline payer receive a [`StaticInvoice`] to
185-
/// pay, we will attempt to hold the corresponding outbound HTLCs with our next-hop channel
186-
/// counterparty(s) that support the `htlc_hold` feature. This allows our node to go offline once
187-
/// the HTLCs are locked in even though the recipient may not yet be online to receive them.
188-
///
189-
/// [`StaticInvoice`]: lightning::offers::static_invoice::StaticInvoice
190-
pub hold_outbound_htlcs_at_next_hop: bool,
191182
}
192183

193184
impl Default for Config {
@@ -202,8 +193,6 @@ impl Default for Config {
202193
anchor_channels_config: Some(AnchorChannelsConfig::default()),
203194
route_parameters: None,
204195
node_alias: None,
205-
async_payment_services_enabled: false,
206-
hold_outbound_htlcs_at_next_hop: false,
207196
}
208197
}
209198
}
@@ -338,13 +327,6 @@ pub(crate) fn default_user_config(config: &Config) -> UserConfig {
338327
user_config.channel_handshake_limits.force_announced_channel_preference = true;
339328
}
340329

341-
if config.async_payment_services_enabled {
342-
user_config.enable_htlc_hold = true;
343-
}
344-
if config.hold_outbound_htlcs_at_next_hop {
345-
user_config.hold_outbound_htlcs_at_next_hop = true;
346-
}
347-
348330
user_config
349331
}
350332

@@ -552,6 +534,17 @@ impl From<MaxDustHTLCExposure> for LdkMaxDustHTLCExposure {
552534
}
553535
}
554536

537+
#[derive(Debug, Clone, Copy)]
538+
/// The role of the node in an asynchronous payments context.
539+
pub enum AsyncPaymentsRole {
540+
/// Node acts a client in an async payments context. This means that if possible, it will instruct its peers to hold
541+
/// htlcs for it, so that it can go offline.
542+
Client,
543+
/// Node acts as a server in an async payments context. This means that it will hold async payments htlcs and onion
544+
/// messages for its peers.
545+
Server,
546+
}
547+
555548
#[cfg(test)]
556549
mod tests {
557550
use std::str::FromStr;

src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ pub use builder::BuildError;
126126
pub use builder::NodeBuilder as Builder;
127127

128128
use chain::ChainSource;
129+
use config::AsyncPaymentsRole;
129130
use config::{
130131
default_user_config, may_announce_channel, ChannelConfig, Config, NODE_ANN_BCAST_INTERVAL,
131132
PEER_RECONNECTION_INTERVAL, RGS_SYNC_INTERVAL,
@@ -207,6 +208,7 @@ pub struct Node {
207208
is_listening: Arc<AtomicBool>,
208209
node_metrics: Arc<RwLock<NodeMetrics>>,
209210
om_mailbox: Option<Arc<OnionMessageMailbox>>,
211+
async_payments_role: Option<AsyncPaymentsRole>,
210212
}
211213

212214
impl Node {
@@ -501,7 +503,8 @@ impl Node {
501503
Arc::clone(&self.logger),
502504
));
503505

504-
let static_invoice_store = if self.config.async_payment_services_enabled {
506+
let static_invoice_store = if let Some(AsyncPaymentsRole::Server) = self.async_payments_role
507+
{
505508
Some(StaticInvoiceStore::new(Arc::clone(&self.kv_store)))
506509
} else {
507510
None
@@ -830,9 +833,9 @@ impl Node {
830833
Bolt12Payment::new(
831834
Arc::clone(&self.channel_manager),
832835
Arc::clone(&self.payment_store),
833-
Arc::clone(&self.config),
834836
Arc::clone(&self.is_running),
835837
Arc::clone(&self.logger),
838+
self.async_payments_role,
836839
)
837840
}
838841

src/payment/bolt12.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//!
1010
//! [BOLT 12]: https://github.com/lightning/bolts/blob/master/12-offer-encoding.md
1111
12-
use crate::config::{Config, LDK_PAYMENT_RETRY_TIMEOUT};
12+
use crate::config::{AsyncPaymentsRole, LDK_PAYMENT_RETRY_TIMEOUT};
1313
use crate::error::Error;
1414
use crate::ffi::{maybe_deref, maybe_wrap};
1515
use crate::logger::{log_error, log_info, LdkLogger, Logger};
@@ -57,16 +57,17 @@ pub struct Bolt12Payment {
5757
channel_manager: Arc<ChannelManager>,
5858
payment_store: Arc<PaymentStore>,
5959
is_running: Arc<RwLock<bool>>,
60-
config: Arc<Config>,
6160
logger: Arc<Logger>,
61+
async_payments_role: Option<AsyncPaymentsRole>,
6262
}
6363

6464
impl Bolt12Payment {
6565
pub(crate) fn new(
6666
channel_manager: Arc<ChannelManager>, payment_store: Arc<PaymentStore>,
67-
config: Arc<Config>, is_running: Arc<RwLock<bool>>, logger: Arc<Logger>,
67+
is_running: Arc<RwLock<bool>>, logger: Arc<Logger>,
68+
async_payments_role: Option<AsyncPaymentsRole>,
6869
) -> Self {
69-
Self { channel_manager, payment_store, config, is_running, logger }
70+
Self { channel_manager, payment_store, is_running, logger, async_payments_role }
7071
}
7172

7273
/// Send a payment given an offer.
@@ -554,8 +555,11 @@ impl Bolt12Payment {
554555
fn blinded_paths_for_async_recipient_internal(
555556
&self, recipient_id: Vec<u8>,
556557
) -> Result<Vec<BlindedMessagePath>, Error> {
557-
if !self.config.async_payment_services_enabled {
558-
return Err(Error::AsyncPaymentServicesDisabled);
558+
match self.async_payments_role {
559+
Some(AsyncPaymentsRole::Server) => {},
560+
_ => {
561+
return Err(Error::AsyncPaymentServicesDisabled);
562+
},
559563
}
560564

561565
self.channel_manager

tests/common/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub(crate) mod logging;
1212

1313
use logging::TestLogWriter;
1414

15-
use ldk_node::config::{Config, ElectrumSyncConfig, EsploraSyncConfig};
15+
use ldk_node::config::{AsyncPaymentsRole, Config, ElectrumSyncConfig, EsploraSyncConfig};
1616
use ldk_node::io::sqlite_store::SqliteStore;
1717
use ldk_node::payment::{PaymentDirection, PaymentKind, PaymentStatus};
1818
use ldk_node::{
@@ -310,6 +310,13 @@ pub(crate) fn setup_two_nodes(
310310

311311
pub(crate) fn setup_node(
312312
chain_source: &TestChainSource, config: TestConfig, seed_bytes: Option<Vec<u8>>,
313+
) -> TestNode {
314+
setup_node_for_async_payments(chain_source, config, seed_bytes, None)
315+
}
316+
317+
pub(crate) fn setup_node_for_async_payments(
318+
chain_source: &TestChainSource, config: TestConfig, seed_bytes: Option<Vec<u8>>,
319+
async_payments_role: Option<AsyncPaymentsRole>,
313320
) -> TestNode {
314321
setup_builder!(builder, config.node_config);
315322
match chain_source {
@@ -375,6 +382,8 @@ pub(crate) fn setup_node(
375382
}
376383
}
377384

385+
builder.set_async_payments_role(async_payments_role);
386+
378387
let test_sync_store = Arc::new(TestSyncStore::new(config.node_config.storage_dir_path.into()));
379388
let node = builder.build_with_store(test_sync_store).unwrap();
380389
node.start().unwrap();

tests/integration_tests_rust.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ use common::{
1616
logging::{init_log_logger, validate_log_entry, TestLogWriter},
1717
open_channel, open_channel_push_amt, premine_and_distribute_funds, premine_blocks, prepare_rbf,
1818
random_config, random_listening_addresses, setup_bitcoind_and_electrsd, setup_builder,
19-
setup_node, setup_two_nodes, wait_for_tx, TestChainSource, TestSyncStore,
19+
setup_node, setup_node_for_async_payments, setup_two_nodes, wait_for_tx, TestChainSource,
20+
TestSyncStore,
2021
};
2122

22-
use ldk_node::config::EsploraSyncConfig;
23+
use ldk_node::config::{AsyncPaymentsRole, EsploraSyncConfig};
2324
use ldk_node::liquidity::LSPS2ServiceConfig;
2425
use ldk_node::payment::{
2526
ConfirmationStatus, PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus,
@@ -1139,23 +1140,35 @@ fn async_payment() {
11391140
let mut config_sender = random_config(true);
11401141
config_sender.node_config.listening_addresses = None;
11411142
config_sender.node_config.node_alias = None;
1142-
config_sender.node_config.hold_outbound_htlcs_at_next_hop = true;
11431143
config_sender.log_writer =
11441144
TestLogWriter::Custom(Arc::new(MultiNodeLogger::new("sender ".to_string())));
1145-
let node_sender = setup_node(&chain_source, config_sender, None);
1145+
let node_sender = setup_node_for_async_payments(
1146+
&chain_source,
1147+
config_sender,
1148+
None,
1149+
Some(AsyncPaymentsRole::Client),
1150+
);
11461151

11471152
let mut config_sender_lsp = random_config(true);
1148-
config_sender_lsp.node_config.async_payment_services_enabled = true;
11491153
config_sender_lsp.log_writer =
11501154
TestLogWriter::Custom(Arc::new(MultiNodeLogger::new("sender_lsp ".to_string())));
1151-
let node_sender_lsp = setup_node(&chain_source, config_sender_lsp, None);
1155+
let node_sender_lsp = setup_node_for_async_payments(
1156+
&chain_source,
1157+
config_sender_lsp,
1158+
None,
1159+
Some(AsyncPaymentsRole::Server),
1160+
);
11521161

11531162
let mut config_receiver_lsp = random_config(true);
1154-
config_receiver_lsp.node_config.async_payment_services_enabled = true;
11551163
config_receiver_lsp.log_writer =
11561164
TestLogWriter::Custom(Arc::new(MultiNodeLogger::new("receiver_lsp".to_string())));
11571165

1158-
let node_receiver_lsp = setup_node(&chain_source, config_receiver_lsp, None);
1166+
let node_receiver_lsp = setup_node_for_async_payments(
1167+
&chain_source,
1168+
config_receiver_lsp,
1169+
None,
1170+
Some(AsyncPaymentsRole::Server),
1171+
);
11591172

11601173
let mut config_receiver = random_config(true);
11611174
config_receiver.node_config.listening_addresses = None;

0 commit comments

Comments
 (0)