Skip to content

Commit 338b9c5

Browse files
committed
Implement LiquidityManager event handling
1 parent 61b2f37 commit 338b9c5

File tree

3 files changed

+140
-14
lines changed

3 files changed

+140
-14
lines changed

bindings/ldk_node.udl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ enum NodeError {
131131
"InvalidNetwork",
132132
"DuplicatePayment",
133133
"InsufficientFunds",
134+
"LiquiditySourceUnavailable",
134135
};
135136

136137
[Error]

src/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ pub enum Error {
6363
DuplicatePayment,
6464
/// The available funds are insufficient to complete the given operation.
6565
InsufficientFunds,
66+
/// The given operation failed due to the required liquidity source being unavailable.
67+
LiquiditySourceUnavailable,
6668
}
6769

6870
impl fmt::Display for Error {
@@ -106,6 +108,9 @@ impl fmt::Display for Error {
106108
Self::InsufficientFunds => {
107109
write!(f, "The available funds are insufficient to complete the given operation.")
108110
}
111+
Self::LiquiditySourceUnavailable => {
112+
write!(f, "The given operation failed due to the required liquidity source being unavailable.")
113+
}
109114
}
110115
}
111116
}

src/liquidity.rs

Lines changed: 134 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
1+
use crate::logger::log_error;
12
use crate::types::{ChannelManager, KeysManager, LiquidityManager, PeerManager};
23
use crate::Config;
34

45
use lightning::ln::msgs::SocketAddress;
56
use lightning::util::logger::Logger;
67
use lightning::util::persist::KVStore;
78
use lightning_liquidity::events::Event;
9+
use lightning_liquidity::lsps0::msgs::RequestId;
810
use lightning_liquidity::lsps2::event::LSPS2ClientEvent;
11+
use lightning_liquidity::lsps2::msgs::OpeningFeeParams;
912

1013
use bitcoin::secp256k1::PublicKey;
1114

15+
use tokio::sync::oneshot;
16+
17+
use std::collections::HashMap;
1218
use std::ops::Deref;
13-
use std::sync::Arc;
19+
use std::sync::{Arc, Mutex};
1420

1521
struct LSPS2Service {
1622
address: SocketAddress,
1723
node_id: PublicKey,
1824
token: Option<String>,
25+
pending_fee_requests: Mutex<HashMap<RequestId, oneshot::Sender<LSPS2FeeResponse>>>,
26+
pending_buy_requests: Mutex<HashMap<RequestId, oneshot::Sender<LSPS2BuyResponse>>>,
1927
}
2028

2129
pub(crate) struct LiquiditySource<K: KVStore + Sync + Send + 'static, L: Deref>
@@ -39,7 +47,15 @@ where
3947
channel_manager: Arc<ChannelManager<K>>, keys_manager: Arc<KeysManager>,
4048
liquidity_manager: Arc<LiquidityManager<K>>, config: Arc<Config>, logger: L,
4149
) -> Self {
42-
let lsps2_service = Some(LSPS2Service { address, node_id, token });
50+
let pending_fee_requests = Mutex::new(HashMap::new());
51+
let pending_buy_requests = Mutex::new(HashMap::new());
52+
let lsps2_service = Some(LSPS2Service {
53+
address,
54+
node_id,
55+
token,
56+
pending_fee_requests,
57+
pending_buy_requests,
58+
});
4359
Self { lsps2_service, channel_manager, keys_manager, liquidity_manager, config, logger }
4460
}
4561

@@ -55,19 +71,123 @@ where
5571
pub(crate) async fn handle_next_event(&self) {
5672
match self.liquidity_manager.next_event_async().await {
5773
Event::LSPS2Client(LSPS2ClientEvent::OpeningParametersReady {
58-
counterparty_node_id: _,
59-
opening_fee_params_menu: _,
60-
min_payment_size_msat: _,
61-
max_payment_size_msat: _,
62-
}) => {}
74+
request_id,
75+
counterparty_node_id,
76+
opening_fee_params_menu,
77+
}) => {
78+
if let Some(lsps2_service) = self.lsps2_service.as_ref() {
79+
if counterparty_node_id != lsps2_service.node_id {
80+
debug_assert!(
81+
false,
82+
"Received response from unexpected LSP counterparty. This should never happen."
83+
);
84+
log_error!(
85+
self.logger,
86+
"Received response from unexpected LSP counterparty. This should never happen."
87+
);
88+
return;
89+
}
90+
91+
if let Some(sender) =
92+
lsps2_service.pending_fee_requests.lock().unwrap().remove(&request_id)
93+
{
94+
let response = LSPS2FeeResponse {
95+
opening_fee_params_menu,
96+
};
97+
98+
match sender.send(response) {
99+
Ok(()) => (),
100+
Err(e) => {
101+
log_error!(
102+
self.logger,
103+
"Failed to handle response from liquidity service: {:?}",
104+
e
105+
);
106+
}
107+
}
108+
} else {
109+
debug_assert!(
110+
false,
111+
"Received response from liquidity service for unknown request."
112+
);
113+
log_error!(
114+
self.logger,
115+
"Received response from liquidity service for unknown request."
116+
);
117+
}
118+
} else {
119+
log_error!(
120+
self.logger,
121+
"Received unexpected LSPS2Client::OpeningParametersReady event!"
122+
);
123+
}
124+
}
63125
Event::LSPS2Client(LSPS2ClientEvent::InvoiceParametersReady {
64-
counterparty_node_id: _,
65-
intercept_scid: _,
66-
cltv_expiry_delta: _,
67-
payment_size_msat: _,
68-
user_channel_id: _,
69-
}) => {}
70-
_ => {}
126+
request_id,
127+
counterparty_node_id,
128+
intercept_scid,
129+
cltv_expiry_delta,
130+
..
131+
}) => {
132+
if let Some(lsps2_service) = self.lsps2_service.as_ref() {
133+
if counterparty_node_id != lsps2_service.node_id {
134+
debug_assert!(
135+
false,
136+
"Received response from unexpected LSP counterparty. This should never happen."
137+
);
138+
log_error!(
139+
self.logger,
140+
"Received response from unexpected LSP counterparty. This should never happen."
141+
);
142+
return;
143+
}
144+
145+
if let Some(sender) =
146+
lsps2_service.pending_buy_requests.lock().unwrap().remove(&request_id)
147+
{
148+
let response = LSPS2BuyResponse { intercept_scid, cltv_expiry_delta };
149+
150+
match sender.send(response) {
151+
Ok(()) => (),
152+
Err(e) => {
153+
log_error!(
154+
self.logger,
155+
"Failed to handle response from liquidity service: {:?}",
156+
e
157+
);
158+
}
159+
}
160+
} else {
161+
debug_assert!(
162+
false,
163+
"Received response from liquidity service for unknown request."
164+
);
165+
log_error!(
166+
self.logger,
167+
"Received response from liquidity service for unknown request."
168+
);
169+
}
170+
} else {
171+
log_error!(
172+
self.logger,
173+
"Received unexpected LSPS2Client::InvoiceParametersReady event!"
174+
);
175+
}
176+
}
177+
e => {
178+
log_error!(self.logger, "Received unexpected liquidity event: {:?}", e);
179+
}
71180
}
72181
}
73182
}
183+
184+
#[derive(Debug, Clone)]
185+
pub(crate) struct LSPS2FeeResponse {
186+
opening_fee_params_menu: Vec<OpeningFeeParams>,
187+
}
188+
189+
#[derive(Debug, Clone)]
190+
pub(crate) struct LSPS2BuyResponse {
191+
intercept_scid: u64,
192+
cltv_expiry_delta: u32,
193+
}

0 commit comments

Comments
 (0)