Skip to content

Commit 2e9248d

Browse files
committed
Allow to set LSPS1 liquidity source
We add support for LSPS1 liquidity sources. To this end we slightly refactor our logic to first create a `LiquiditySourceBuilder` that then can be used to `build()` the `LiquiditySource` with the configured services.
1 parent 8a58454 commit 2e9248d

File tree

3 files changed

+152
-40
lines changed

3 files changed

+152
-40
lines changed

src/builder.rs

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::gossip::GossipSource;
1818
use crate::io::sqlite_store::SqliteStore;
1919
use crate::io::utils::{read_node_metrics, write_node_metrics};
2020
use crate::io::vss_store::VssStore;
21-
use crate::liquidity::LiquiditySource;
21+
use crate::liquidity::LiquiditySourceBuilder;
2222
use crate::logger::{log_error, log_info, LdkLogger, LogLevel, LogWriter, Logger};
2323
use crate::message_handler::NodeCustomMessageHandler;
2424
use crate::payment::store::PaymentStore;
@@ -54,9 +54,6 @@ use lightning::util::sweep::OutputSweeper;
5454

5555
use lightning_persister::fs_store::FilesystemStore;
5656

57-
use lightning_liquidity::lsps2::client::LSPS2ClientConfig;
58-
use lightning_liquidity::{LiquidityClientConfig, LiquidityManager};
59-
6057
use bdk_wallet::template::Bip84;
6158
use bdk_wallet::KeychainKind;
6259
use bdk_wallet::Wallet as BdkWallet;
@@ -99,13 +96,15 @@ enum GossipSourceConfig {
9996

10097
#[derive(Debug, Clone)]
10198
struct LiquiditySourceConfig {
99+
// LSPS1 service's (node_id, address, token)
100+
lsps1_service: Option<(PublicKey, SocketAddress, Option<String>)>,
102101
// LSPS2 service's (node_id, address, token)
103102
lsps2_service: Option<(PublicKey, SocketAddress, Option<String>)>,
104103
}
105104

106105
impl Default for LiquiditySourceConfig {
107106
fn default() -> Self {
108-
Self { lsps2_service: None }
107+
Self { lsps1_service: None, lsps2_service: None }
109108
}
110109
}
111110

@@ -322,7 +321,26 @@ impl NodeBuilder {
322321
self
323322
}
324323

325-
/// Configures the [`Node`] instance to source its inbound liquidity from the given
324+
/// Configures the [`Node`] instance to source inbound liquidity from the given
325+
/// [LSPS1](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS1/README.md)
326+
/// service.
327+
///
328+
/// Will mark the LSP as trusted for 0-confirmation channels, see [`Config::trusted_peers_0conf`].
329+
///
330+
/// The given `token` will be used by the LSP to authenticate the user.
331+
pub fn set_liquidity_source_lsps1(
332+
&mut self, node_id: PublicKey, address: SocketAddress, token: Option<String>,
333+
) -> &mut Self {
334+
// Mark the LSP as trusted for 0conf
335+
self.config.trusted_peers_0conf.push(node_id.clone());
336+
337+
let liquidity_source_config =
338+
self.liquidity_source_config.get_or_insert(LiquiditySourceConfig::default());
339+
liquidity_source_config.lsps1_service = Some((node_id, address, token));
340+
self
341+
}
342+
343+
/// Configures the [`Node`] instance to source just-in-time inbound liquidity from the given
326344
/// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
327345
/// service.
328346
///
@@ -654,7 +672,20 @@ impl ArcedNodeBuilder {
654672
self.inner.write().unwrap().set_gossip_source_rgs(rgs_server_url);
655673
}
656674

657-
/// Configures the [`Node`] instance to source its inbound liquidity from the given
675+
/// Configures the [`Node`] instance to source inbound liquidity from the given
676+
/// [LSPS1](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS1/README.md)
677+
/// service.
678+
///
679+
/// Will mark the LSP as trusted for 0-confirmation channels, see [`Config::trusted_peers_0conf`].
680+
///
681+
/// The given `token` will be used by the LSP to authenticate the user.
682+
pub fn set_liquidity_source_lsps1(
683+
&self, node_id: PublicKey, address: SocketAddress, token: Option<String>,
684+
) {
685+
self.inner.write().unwrap().set_liquidity_source_lsps1(node_id, address, token);
686+
}
687+
688+
/// Configures the [`Node`] instance to source just-in-time inbound liquidity from the given
658689
/// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
659690
/// service.
660691
///
@@ -1129,30 +1160,24 @@ fn build_with_store_internal(
11291160
},
11301161
};
11311162

1132-
let liquidity_source = liquidity_source_config.as_ref().and_then(|lsc| {
1163+
let liquidity_source = liquidity_source_config.as_ref().map(|lsc| {
1164+
let mut liquidity_source_builder = LiquiditySourceBuilder::new(
1165+
Arc::clone(&channel_manager),
1166+
Arc::clone(&keys_manager),
1167+
Arc::clone(&chain_source),
1168+
Arc::clone(&config),
1169+
Arc::clone(&logger),
1170+
);
1171+
1172+
lsc.lsps1_service.as_ref().map(|(node_id, address, token)| {
1173+
liquidity_source_builder.lsps1_service(*node_id, address.clone(), token.clone())
1174+
});
1175+
11331176
lsc.lsps2_service.as_ref().map(|(node_id, address, token)| {
1134-
let lsps2_client_config = Some(LSPS2ClientConfig {});
1135-
let liquidity_client_config =
1136-
Some(LiquidityClientConfig { lsps1_client_config: None, lsps2_client_config });
1137-
let liquidity_manager = Arc::new(LiquidityManager::new(
1138-
Arc::clone(&keys_manager),
1139-
Arc::clone(&channel_manager),
1140-
Some(Arc::clone(&chain_source)),
1141-
None,
1142-
None,
1143-
liquidity_client_config,
1144-
));
1145-
Arc::new(LiquiditySource::new_lsps2(
1146-
*node_id,
1147-
address.clone(),
1148-
token.clone(),
1149-
Arc::clone(&channel_manager),
1150-
Arc::clone(&keys_manager),
1151-
liquidity_manager,
1152-
Arc::clone(&config),
1153-
Arc::clone(&logger),
1154-
))
1155-
})
1177+
liquidity_source_builder.lsps2_service(*node_id, address.clone(), token.clone())
1178+
});
1179+
1180+
Arc::new(liquidity_source_builder.build())
11561181
});
11571182

11581183
let custom_message_handler = if let Some(liquidity_source) = liquidity_source.as_ref() {

src/liquidity.rs

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66
// accordance with one or both of these licenses.
77

8+
use crate::chain::ChainSource;
89
use crate::logger::{log_debug, log_error, log_info, LdkLogger};
910
use crate::types::{ChannelManager, KeysManager, LiquidityManager, PeerManager};
1011
use crate::{Config, Error};
@@ -15,9 +16,12 @@ use lightning::routing::router::{RouteHint, RouteHintHop};
1516
use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, InvoiceBuilder, RoutingFees};
1617
use lightning_liquidity::events::Event;
1718
use lightning_liquidity::lsps0::ser::RequestId;
19+
use lightning_liquidity::lsps1::client::LSPS1ClientConfig;
20+
use lightning_liquidity::lsps2::client::LSPS2ClientConfig;
1821
use lightning_liquidity::lsps2::event::LSPS2ClientEvent;
1922
use lightning_liquidity::lsps2::msgs::OpeningFeeParams;
2023
use lightning_liquidity::lsps2::utils::compute_opening_fee;
24+
use lightning_liquidity::LiquidityClientConfig;
2125

2226
use bitcoin::hashes::{sha256, Hash};
2327
use bitcoin::secp256k1::{PublicKey, Secp256k1};
@@ -31,47 +35,126 @@ use std::time::Duration;
3135

3236
const LIQUIDITY_REQUEST_TIMEOUT_SECS: u64 = 5;
3337

38+
struct LSPS1Service {
39+
node_id: PublicKey,
40+
address: SocketAddress,
41+
token: Option<String>,
42+
client_config: LSPS1ClientConfig,
43+
}
44+
3445
struct LSPS2Service {
3546
node_id: PublicKey,
3647
address: SocketAddress,
3748
token: Option<String>,
49+
client_config: LSPS2ClientConfig,
3850
pending_fee_requests: Mutex<HashMap<RequestId, oneshot::Sender<LSPS2FeeResponse>>>,
3951
pending_buy_requests: Mutex<HashMap<RequestId, oneshot::Sender<LSPS2BuyResponse>>>,
4052
}
4153

42-
pub(crate) struct LiquiditySource<L: Deref>
54+
pub(crate) struct LiquiditySourceBuilder<L: Deref>
4355
where
4456
L::Target: LdkLogger,
4557
{
58+
lsps1_service: Option<LSPS1Service>,
4659
lsps2_service: Option<LSPS2Service>,
4760
channel_manager: Arc<ChannelManager>,
4861
keys_manager: Arc<KeysManager>,
49-
liquidity_manager: Arc<LiquidityManager>,
62+
chain_source: Arc<ChainSource>,
5063
config: Arc<Config>,
5164
logger: L,
5265
}
5366

54-
impl<L: Deref> LiquiditySource<L>
67+
impl<L: Deref> LiquiditySourceBuilder<L>
5568
where
5669
L::Target: LdkLogger,
5770
{
58-
pub(crate) fn new_lsps2(
59-
node_id: PublicKey, address: SocketAddress, token: Option<String>,
71+
pub(crate) fn new(
6072
channel_manager: Arc<ChannelManager>, keys_manager: Arc<KeysManager>,
61-
liquidity_manager: Arc<LiquidityManager>, config: Arc<Config>, logger: L,
73+
chain_source: Arc<ChainSource>, config: Arc<Config>, logger: L,
6274
) -> Self {
75+
let lsps1_service = None;
76+
let lsps2_service = None;
77+
Self {
78+
lsps1_service,
79+
lsps2_service,
80+
channel_manager,
81+
keys_manager,
82+
chain_source,
83+
config,
84+
logger,
85+
}
86+
}
87+
88+
pub(crate) fn lsps1_service(
89+
&mut self, node_id: PublicKey, address: SocketAddress, token: Option<String>,
90+
) -> &mut Self {
91+
// TODO: allow to set max_channel_fees_msat
92+
let client_config = LSPS1ClientConfig { max_channel_fees_msat: None };
93+
self.lsps1_service = Some(LSPS1Service { node_id, address, token, client_config });
94+
self
95+
}
96+
97+
pub(crate) fn lsps2_service(
98+
&mut self, node_id: PublicKey, address: SocketAddress, token: Option<String>,
99+
) -> &mut Self {
100+
let client_config = LSPS2ClientConfig {};
63101
let pending_fee_requests = Mutex::new(HashMap::new());
64102
let pending_buy_requests = Mutex::new(HashMap::new());
65-
let lsps2_service = Some(LSPS2Service {
103+
self.lsps2_service = Some(LSPS2Service {
66104
node_id,
67105
address,
68106
token,
107+
client_config,
69108
pending_fee_requests,
70109
pending_buy_requests,
71110
});
72-
Self { lsps2_service, channel_manager, keys_manager, liquidity_manager, config, logger }
111+
self
73112
}
74113

114+
pub(crate) fn build(self) -> LiquiditySource<L> {
115+
let lsps1_client_config = self.lsps1_service.as_ref().map(|s| s.client_config.clone());
116+
let lsps2_client_config = self.lsps2_service.as_ref().map(|s| s.client_config.clone());
117+
let liquidity_client_config =
118+
Some(LiquidityClientConfig { lsps1_client_config, lsps2_client_config });
119+
120+
let liquidity_manager = Arc::new(LiquidityManager::new(
121+
Arc::clone(&self.keys_manager),
122+
Arc::clone(&self.channel_manager),
123+
Some(Arc::clone(&self.chain_source)),
124+
None,
125+
None,
126+
liquidity_client_config,
127+
));
128+
129+
LiquiditySource {
130+
lsps1_service: self.lsps1_service,
131+
lsps2_service: self.lsps2_service,
132+
channel_manager: self.channel_manager,
133+
keys_manager: self.keys_manager,
134+
liquidity_manager,
135+
config: self.config,
136+
logger: self.logger,
137+
}
138+
}
139+
}
140+
141+
pub(crate) struct LiquiditySource<L: Deref>
142+
where
143+
L::Target: LdkLogger,
144+
{
145+
lsps1_service: Option<LSPS1Service>,
146+
lsps2_service: Option<LSPS2Service>,
147+
channel_manager: Arc<ChannelManager>,
148+
keys_manager: Arc<KeysManager>,
149+
liquidity_manager: Arc<LiquidityManager>,
150+
config: Arc<Config>,
151+
logger: L,
152+
}
153+
154+
impl<L: Deref> LiquiditySource<L>
155+
where
156+
L::Target: LdkLogger,
157+
{
75158
pub(crate) fn set_peer_manager(&self, peer_manager: Arc<PeerManager>) {
76159
let process_msgs_callback = move || peer_manager.process_events();
77160
self.liquidity_manager.set_process_msgs_callback(process_msgs_callback);
@@ -81,7 +164,11 @@ where
81164
self.liquidity_manager.as_ref()
82165
}
83166

84-
pub(crate) fn get_liquidity_source_details(&self) -> Option<(PublicKey, SocketAddress)> {
167+
pub(crate) fn get_lsps1_service_details(&self) -> Option<(PublicKey, SocketAddress)> {
168+
self.lsps1_service.as_ref().map(|s| (s.node_id, s.address.clone()))
169+
}
170+
171+
pub(crate) fn get_lsps2_service_details(&self) -> Option<(PublicKey, SocketAddress)> {
85172
self.lsps2_service.as_ref().map(|s| (s.node_id, s.address.clone()))
86173
}
87174

src/payment/bolt11.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ impl Bolt11Payment {
597597
self.liquidity_source.as_ref().ok_or(Error::LiquiditySourceUnavailable)?;
598598

599599
let (node_id, address) = liquidity_source
600-
.get_liquidity_source_details()
600+
.get_lsps2_service_details()
601601
.ok_or(Error::LiquiditySourceUnavailable)?;
602602

603603
let rt_lock = self.runtime.read().unwrap();

0 commit comments

Comments
 (0)