Skip to content

Commit f430a91

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 c6b5eaf commit f430a91

File tree

3 files changed

+152
-40
lines changed

3 files changed

+152
-40
lines changed

src/builder.rs

+55-30
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::gossip::GossipSource;
1515
use crate::io::sqlite_store::SqliteStore;
1616
use crate::io::utils::{read_node_metrics, write_node_metrics};
1717
use crate::io::vss_store::VssStore;
18-
use crate::liquidity::LiquiditySource;
18+
use crate::liquidity::LiquiditySourceBuilder;
1919
use crate::logger::{log_error, log_info, FilesystemLogger, Logger};
2020
use crate::message_handler::NodeCustomMessageHandler;
2121
use crate::payment::store::PaymentStore;
@@ -51,9 +51,6 @@ use lightning::util::sweep::OutputSweeper;
5151

5252
use lightning_persister::fs_store::FilesystemStore;
5353

54-
use lightning_liquidity::lsps2::client::LSPS2ClientConfig;
55-
use lightning_liquidity::{LiquidityClientConfig, LiquidityManager};
56-
5754
use bdk_wallet::template::Bip84;
5855
use bdk_wallet::KeychainKind;
5956
use bdk_wallet::Wallet as BdkWallet;
@@ -96,13 +93,15 @@ enum GossipSourceConfig {
9693

9794
#[derive(Debug, Clone)]
9895
struct LiquiditySourceConfig {
96+
// LSPS1 service's (node_id, address, token)
97+
lsps1_service: Option<(PublicKey, SocketAddress, Option<String>)>,
9998
// LSPS2 service's (node_id, address, token)
10099
lsps2_service: Option<(PublicKey, SocketAddress, Option<String>)>,
101100
}
102101

103102
impl Default for LiquiditySourceConfig {
104103
fn default() -> Self {
105-
Self { lsps2_service: None }
104+
Self { lsps1_service: None, lsps2_service: None }
106105
}
107106
}
108107

@@ -273,7 +272,26 @@ impl NodeBuilder {
273272
self
274273
}
275274

276-
/// Configures the [`Node`] instance to source its inbound liquidity from the given
275+
/// Configures the [`Node`] instance to source inbound liquidity from the given
276+
/// [LSPS1](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS1/README.md)
277+
/// service.
278+
///
279+
/// Will mark the LSP as trusted for 0-confirmation channels, see [`Config::trusted_peers_0conf`].
280+
///
281+
/// The given `token` will be used by the LSP to authenticate the user.
282+
pub fn set_liquidity_source_lsps1(
283+
&mut self, node_id: PublicKey, address: SocketAddress, token: Option<String>,
284+
) -> &mut Self {
285+
// Mark the LSP as trusted for 0conf
286+
self.config.trusted_peers_0conf.push(node_id.clone());
287+
288+
let liquidity_source_config =
289+
self.liquidity_source_config.get_or_insert(LiquiditySourceConfig::default());
290+
liquidity_source_config.lsps1_service = Some((node_id, address, token));
291+
self
292+
}
293+
294+
/// Configures the [`Node`] instance to source just-in-time inbound liquidity from the given
277295
/// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
278296
/// service.
279297
///
@@ -592,7 +610,20 @@ impl ArcedNodeBuilder {
592610
self.inner.write().unwrap().set_gossip_source_rgs(rgs_server_url);
593611
}
594612

595-
/// Configures the [`Node`] instance to source its inbound liquidity from the given
613+
/// Configures the [`Node`] instance to source inbound liquidity from the given
614+
/// [LSPS1](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS1/README.md)
615+
/// service.
616+
///
617+
/// Will mark the LSP as trusted for 0-confirmation channels, see [`Config::trusted_peers_0conf`].
618+
///
619+
/// The given `token` will be used by the LSP to authenticate the user.
620+
pub fn set_liquidity_source_lsps1(
621+
&self, node_id: PublicKey, address: SocketAddress, token: Option<String>,
622+
) {
623+
self.inner.write().unwrap().set_liquidity_source_lsps1(node_id, address, token);
624+
}
625+
626+
/// Configures the [`Node`] instance to source just-in-time inbound liquidity from the given
596627
/// [LSPS2](https://github.com/BitcoinAndLightningLayerSpecs/lsp/blob/main/LSPS2/README.md)
597628
/// service.
598629
///
@@ -1056,30 +1087,24 @@ fn build_with_store_internal(
10561087
},
10571088
};
10581089

1059-
let liquidity_source = liquidity_source_config.as_ref().and_then(|lsc| {
1090+
let liquidity_source = liquidity_source_config.as_ref().map(|lsc| {
1091+
let mut liquidity_source_builder = LiquiditySourceBuilder::new(
1092+
Arc::clone(&channel_manager),
1093+
Arc::clone(&keys_manager),
1094+
Arc::clone(&chain_source),
1095+
Arc::clone(&config),
1096+
Arc::clone(&logger),
1097+
);
1098+
1099+
lsc.lsps1_service.as_ref().map(|(node_id, address, token)| {
1100+
liquidity_source_builder.lsps1_service(*node_id, address.clone(), token.clone())
1101+
});
1102+
10601103
lsc.lsps2_service.as_ref().map(|(node_id, address, token)| {
1061-
let lsps2_client_config = Some(LSPS2ClientConfig {});
1062-
let liquidity_client_config =
1063-
Some(LiquidityClientConfig { lsps1_client_config: None, lsps2_client_config });
1064-
let liquidity_manager = Arc::new(LiquidityManager::new(
1065-
Arc::clone(&keys_manager),
1066-
Arc::clone(&channel_manager),
1067-
Some(Arc::clone(&chain_source)),
1068-
None,
1069-
None,
1070-
liquidity_client_config,
1071-
));
1072-
Arc::new(LiquiditySource::new_lsps2(
1073-
*node_id,
1074-
address.clone(),
1075-
token.clone(),
1076-
Arc::clone(&channel_manager),
1077-
Arc::clone(&keys_manager),
1078-
liquidity_manager,
1079-
Arc::clone(&config),
1080-
Arc::clone(&logger),
1081-
))
1082-
})
1104+
liquidity_source_builder.lsps2_service(*node_id, address.clone(), token.clone())
1105+
});
1106+
1107+
Arc::new(liquidity_source_builder.build())
10831108
});
10841109

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

src/liquidity.rs

+96-9
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, Logger};
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, 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: Logger,
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: Logger,
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: Logger,
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: Logger,
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ impl Bolt11Payment {
576576
self.liquidity_source.as_ref().ok_or(Error::LiquiditySourceUnavailable)?;
577577

578578
let (node_id, address) = liquidity_source
579-
.get_liquidity_source_details()
579+
.get_lsps2_service_details()
580580
.ok_or(Error::LiquiditySourceUnavailable)?;
581581

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

0 commit comments

Comments
 (0)