77
88use crate :: chain:: ChainSource ;
99use 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
1515use crate :: connection:: ConnectionManager ;
@@ -27,6 +27,7 @@ use crate::liquidity::{
2727} ;
2828use crate :: logger:: { log_error, LdkLogger , LogLevel , LogWriter , Logger } ;
2929use crate :: message_handler:: NodeCustomMessageHandler ;
30+ use crate :: payment:: asynchronous:: om_mailbox:: OnionMessageMailbox ;
3031use crate :: peer_store:: PeerStore ;
3132use crate :: runtime:: Runtime ;
3233use crate :: tx_broadcaster:: TransactionBroadcaster ;
@@ -191,6 +192,8 @@ pub enum BuildError {
191192 LoggerSetupFailed ,
192193 /// The given network does not match the node's previously configured network.
193194 NetworkMismatch ,
195+ /// The role of the node in an asynchronous payments context is not compatible with the current configuration.
196+ AsyncPaymentsConfigMismatch ,
194197}
195198
196199impl fmt:: Display for BuildError {
@@ -219,6 +222,12 @@ impl fmt::Display for BuildError {
219222 Self :: NetworkMismatch => {
220223 write ! ( f, "Given network does not match the node's previously configured network." )
221224 } ,
225+ Self :: AsyncPaymentsConfigMismatch => {
226+ write ! (
227+ f,
228+ "The async payments role is not compatible with the current configuration."
229+ )
230+ } ,
222231 }
223232 }
224233}
@@ -240,6 +249,7 @@ pub struct NodeBuilder {
240249 gossip_source_config : Option < GossipSourceConfig > ,
241250 liquidity_source_config : Option < LiquiditySourceConfig > ,
242251 log_writer_config : Option < LogWriterConfig > ,
252+ async_payments_role : Option < AsyncPaymentsRole > ,
243253 runtime_handle : Option < tokio:: runtime:: Handle > ,
244254}
245255
@@ -266,6 +276,7 @@ impl NodeBuilder {
266276 liquidity_source_config,
267277 log_writer_config,
268278 runtime_handle,
279+ async_payments_role : None ,
269280 }
270281 }
271282
@@ -544,6 +555,21 @@ impl NodeBuilder {
544555 Ok ( self )
545556 }
546557
558+ /// Sets the role of the node in an asynchronous payments context.
559+ ///
560+ /// See <https://github.com/lightning/bolts/pull/1149> for more information about the async payments protocol.
561+ pub fn set_async_payments_role (
562+ & mut self , role : Option < AsyncPaymentsRole > ,
563+ ) -> Result < & mut Self , BuildError > {
564+ if let Some ( AsyncPaymentsRole :: Server ) = role {
565+ may_announce_channel ( & self . config )
566+ . map_err ( |_| BuildError :: AsyncPaymentsConfigMismatch ) ?;
567+ }
568+
569+ self . async_payments_role = role;
570+ Ok ( self )
571+ }
572+
547573 /// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
548574 /// previously configured.
549575 pub fn build ( & self ) -> Result < Node , BuildError > {
@@ -700,6 +726,7 @@ impl NodeBuilder {
700726 self . chain_data_source_config . as_ref ( ) ,
701727 self . gossip_source_config . as_ref ( ) ,
702728 self . liquidity_source_config . as_ref ( ) ,
729+ self . async_payments_role ,
703730 seed_bytes,
704731 runtime,
705732 logger,
@@ -732,6 +759,7 @@ impl NodeBuilder {
732759 self . chain_data_source_config . as_ref ( ) ,
733760 self . gossip_source_config . as_ref ( ) ,
734761 self . liquidity_source_config . as_ref ( ) ,
762+ self . async_payments_role ,
735763 seed_bytes,
736764 runtime,
737765 logger,
@@ -989,6 +1017,13 @@ impl ArcedNodeBuilder {
9891017 self . inner . write ( ) . unwrap ( ) . set_node_alias ( node_alias) . map ( |_| ( ) )
9901018 }
9911019
1020+ /// Sets the role of the node in an asynchronous payments context.
1021+ pub fn set_async_payments_role (
1022+ & self , role : Option < AsyncPaymentsRole > ,
1023+ ) -> Result < ( ) , BuildError > {
1024+ self . inner . write ( ) . unwrap ( ) . set_async_payments_role ( role) . map ( |_| ( ) )
1025+ }
1026+
9921027 /// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
9931028 /// previously configured.
9941029 pub fn build ( & self ) -> Result < Arc < Node > , BuildError > {
@@ -1082,8 +1117,9 @@ impl ArcedNodeBuilder {
10821117fn build_with_store_internal (
10831118 config : Arc < Config > , chain_data_source_config : Option < & ChainDataSourceConfig > ,
10841119 gossip_source_config : Option < & GossipSourceConfig > ,
1085- liquidity_source_config : Option < & LiquiditySourceConfig > , seed_bytes : [ u8 ; 64 ] ,
1086- runtime : Arc < Runtime > , logger : Arc < Logger > , kv_store : Arc < DynStore > ,
1120+ liquidity_source_config : Option < & LiquiditySourceConfig > ,
1121+ async_payments_role : Option < AsyncPaymentsRole > , seed_bytes : [ u8 ; 64 ] , runtime : Arc < Runtime > ,
1122+ logger : Arc < Logger > , kv_store : Arc < DynStore > ,
10871123) -> Result < Node , BuildError > {
10881124 optionally_install_rustls_cryptoprovider ( ) ;
10891125
@@ -1378,8 +1414,14 @@ fn build_with_store_internal(
13781414 100 ;
13791415 }
13801416
1381- if config. async_payment_services_enabled {
1382- user_config. accept_forwards_to_priv_channels = true ;
1417+ if let Some ( role) = async_payments_role {
1418+ match role {
1419+ AsyncPaymentsRole :: Server => {
1420+ user_config. accept_forwards_to_priv_channels = true ;
1421+ user_config. enable_htlc_hold = true ;
1422+ } ,
1423+ AsyncPaymentsRole :: Client => user_config. hold_outbound_htlcs_at_next_hop = true ,
1424+ }
13831425 }
13841426
13851427 let message_router =
@@ -1452,17 +1494,32 @@ fn build_with_store_internal(
14521494 }
14531495
14541496 // Initialize the PeerManager
1455- let onion_messenger: Arc < OnionMessenger > = Arc :: new ( OnionMessenger :: new (
1456- Arc :: clone ( & keys_manager) ,
1457- Arc :: clone ( & keys_manager) ,
1458- Arc :: clone ( & logger) ,
1459- Arc :: clone ( & channel_manager) ,
1460- message_router,
1461- Arc :: clone ( & channel_manager) ,
1462- Arc :: clone ( & channel_manager) ,
1463- IgnoringMessageHandler { } ,
1464- IgnoringMessageHandler { } ,
1465- ) ) ;
1497+ let onion_messenger: Arc < OnionMessenger > =
1498+ if let Some ( AsyncPaymentsRole :: Server ) = async_payments_role {
1499+ Arc :: new ( OnionMessenger :: new_with_offline_peer_interception (
1500+ Arc :: clone ( & keys_manager) ,
1501+ Arc :: clone ( & keys_manager) ,
1502+ Arc :: clone ( & logger) ,
1503+ Arc :: clone ( & channel_manager) ,
1504+ message_router,
1505+ Arc :: clone ( & channel_manager) ,
1506+ Arc :: clone ( & channel_manager) ,
1507+ IgnoringMessageHandler { } ,
1508+ IgnoringMessageHandler { } ,
1509+ ) )
1510+ } else {
1511+ Arc :: new ( OnionMessenger :: new (
1512+ Arc :: clone ( & keys_manager) ,
1513+ Arc :: clone ( & keys_manager) ,
1514+ Arc :: clone ( & logger) ,
1515+ Arc :: clone ( & channel_manager) ,
1516+ message_router,
1517+ Arc :: clone ( & channel_manager) ,
1518+ Arc :: clone ( & channel_manager) ,
1519+ IgnoringMessageHandler { } ,
1520+ IgnoringMessageHandler { } ,
1521+ ) )
1522+ } ;
14661523 let ephemeral_bytes: [ u8 ; 32 ] = keys_manager. get_secure_random_bytes ( ) ;
14671524
14681525 // Initialize the GossipSource
@@ -1649,6 +1706,12 @@ fn build_with_store_internal(
16491706 } ,
16501707 } ;
16511708
1709+ let om_mailbox = if let Some ( AsyncPaymentsRole :: Server ) = async_payments_role {
1710+ Some ( Arc :: new ( OnionMessageMailbox :: new ( ) ) )
1711+ } else {
1712+ None
1713+ } ;
1714+
16521715 let ( stop_sender, _) = tokio:: sync:: watch:: channel ( ( ) ) ;
16531716 let ( background_processor_stop_sender, _) = tokio:: sync:: watch:: channel ( ( ) ) ;
16541717 let is_running = Arc :: new ( RwLock :: new ( false ) ) ;
@@ -1681,6 +1744,8 @@ fn build_with_store_internal(
16811744 is_running,
16821745 is_listening,
16831746 node_metrics,
1747+ om_mailbox,
1748+ async_payments_role,
16841749 } )
16851750}
16861751
0 commit comments