Skip to content

Commit f19c1ed

Browse files
martinsaposnictnull
authored andcommitted
LSPS1: Add initial integration test
We add the first LSPS1 integration test. This is based on the unfinished work in #3864, but rebased to account for the new ways we now do integration test setup.
1 parent fd85279 commit f19c1ed

File tree

1 file changed

+273
-0
lines changed

1 file changed

+273
-0
lines changed
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
#![cfg(all(test, feature = "time", lsps1_service))]
2+
3+
mod common;
4+
5+
use common::create_service_and_client_nodes_with_kv_stores;
6+
use common::{get_lsps_message, LSPSNodes};
7+
8+
use lightning::ln::peer_handler::CustomMessageHandler;
9+
use lightning_liquidity::events::LiquidityEvent;
10+
use lightning_liquidity::lsps0::ser::LSPSDateTime;
11+
use lightning_liquidity::lsps1::client::LSPS1ClientConfig;
12+
use lightning_liquidity::lsps1::event::LSPS1ClientEvent;
13+
use lightning_liquidity::lsps1::event::LSPS1ServiceEvent;
14+
use lightning_liquidity::lsps1::msgs::LSPS1OrderState;
15+
use lightning_liquidity::lsps1::msgs::{
16+
LSPS1OnchainPaymentInfo, LSPS1Options, LSPS1OrderParams, LSPS1PaymentInfo,
17+
};
18+
use lightning_liquidity::lsps1::service::LSPS1ServiceConfig;
19+
use lightning_liquidity::utils::time::DefaultTimeProvider;
20+
use lightning_liquidity::{LiquidityClientConfig, LiquidityServiceConfig};
21+
22+
use lightning::ln::functional_test_utils::{
23+
create_chanmon_cfgs, create_node_cfgs, create_node_chanmgrs,
24+
};
25+
use lightning::util::test_utils::TestStore;
26+
27+
use std::str::FromStr;
28+
use std::sync::Arc;
29+
30+
use lightning::ln::functional_test_utils::{create_network, Node};
31+
32+
fn build_lsps1_configs(
33+
supported_options: LSPS1Options,
34+
) -> (LiquidityServiceConfig, LiquidityClientConfig) {
35+
let lsps1_service_config =
36+
LSPS1ServiceConfig { token: None, supported_options: Some(supported_options) };
37+
let service_config = LiquidityServiceConfig {
38+
lsps1_service_config: Some(lsps1_service_config),
39+
lsps2_service_config: None,
40+
lsps5_service_config: None,
41+
advertise_service: true,
42+
};
43+
44+
let lsps1_client_config = LSPS1ClientConfig { max_channel_fees_msat: None };
45+
let client_config = LiquidityClientConfig {
46+
lsps1_client_config: Some(lsps1_client_config),
47+
lsps2_client_config: None,
48+
lsps5_client_config: None,
49+
};
50+
51+
(service_config, client_config)
52+
}
53+
54+
fn setup_test_lsps1_nodes_with_kv_stores<'a, 'b, 'c>(
55+
nodes: Vec<Node<'a, 'b, 'c>>, service_kv_store: Arc<TestStore>,
56+
client_kv_store: Arc<TestStore>, supported_options: LSPS1Options,
57+
) -> LSPSNodes<'a, 'b, 'c> {
58+
let (service_config, client_config) = build_lsps1_configs(supported_options);
59+
let lsps_nodes = create_service_and_client_nodes_with_kv_stores(
60+
nodes,
61+
service_config,
62+
client_config,
63+
Arc::new(DefaultTimeProvider),
64+
service_kv_store,
65+
client_kv_store,
66+
);
67+
lsps_nodes
68+
}
69+
70+
fn setup_test_lsps1_nodes<'a, 'b, 'c>(
71+
nodes: Vec<Node<'a, 'b, 'c>>, supported_options: LSPS1Options,
72+
) -> LSPSNodes<'a, 'b, 'c> {
73+
let service_kv_store = Arc::new(TestStore::new(false));
74+
let client_kv_store = Arc::new(TestStore::new(false));
75+
setup_test_lsps1_nodes_with_kv_stores(
76+
nodes,
77+
service_kv_store,
78+
client_kv_store,
79+
supported_options,
80+
)
81+
}
82+
83+
#[test]
84+
fn lsps1_happy_path() {
85+
let chanmon_cfgs = create_chanmon_cfgs(2);
86+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
87+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
88+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
89+
90+
let expected_options_supported = LSPS1Options {
91+
min_required_channel_confirmations: 0,
92+
min_funding_confirms_within_blocks: 6,
93+
supports_zero_channel_reserve: true,
94+
max_channel_expiry_blocks: 144,
95+
min_initial_client_balance_sat: 10_000_000,
96+
max_initial_client_balance_sat: 100_000_000,
97+
min_initial_lsp_balance_sat: 100_000,
98+
max_initial_lsp_balance_sat: 100_000_000,
99+
min_channel_balance_sat: 100_000,
100+
max_channel_balance_sat: 100_000_000,
101+
};
102+
103+
let LSPSNodes { service_node, client_node } =
104+
setup_test_lsps1_nodes(nodes, expected_options_supported.clone());
105+
let service_node_id = service_node.inner.node.get_our_node_id();
106+
let client_node_id = client_node.inner.node.get_our_node_id();
107+
let client_handler = client_node.liquidity_manager.lsps1_client_handler().unwrap();
108+
let service_handler = service_node.liquidity_manager.lsps1_service_handler().unwrap();
109+
110+
let request_supported_options_id = client_handler.request_supported_options(service_node_id);
111+
let request_supported_options = get_lsps_message!(client_node, service_node_id);
112+
113+
service_node
114+
.liquidity_manager
115+
.handle_custom_message(request_supported_options, client_node_id)
116+
.unwrap();
117+
118+
let get_info_message = get_lsps_message!(service_node, client_node_id);
119+
120+
client_node.liquidity_manager.handle_custom_message(get_info_message, service_node_id).unwrap();
121+
122+
let get_info_event = client_node.liquidity_manager.next_event().unwrap();
123+
if let LiquidityEvent::LSPS1Client(LSPS1ClientEvent::SupportedOptionsReady {
124+
request_id,
125+
counterparty_node_id,
126+
supported_options,
127+
}) = get_info_event
128+
{
129+
assert_eq!(request_id, request_supported_options_id);
130+
assert_eq!(counterparty_node_id, service_node_id);
131+
assert_eq!(expected_options_supported, supported_options);
132+
} else {
133+
panic!("Unexpected event");
134+
}
135+
136+
let order_params = LSPS1OrderParams {
137+
lsp_balance_sat: 100_000,
138+
client_balance_sat: 10_000_000,
139+
required_channel_confirmations: 0,
140+
funding_confirms_within_blocks: 6,
141+
channel_expiry_blocks: 144,
142+
token: None,
143+
announce_channel: true,
144+
};
145+
146+
let _create_order_id =
147+
client_handler.create_order(&service_node_id, order_params.clone(), None);
148+
let create_order = get_lsps_message!(client_node, service_node_id);
149+
150+
service_node.liquidity_manager.handle_custom_message(create_order, client_node_id).unwrap();
151+
152+
let _request_for_payment_event = service_node.liquidity_manager.next_event().unwrap();
153+
154+
if let LiquidityEvent::LSPS1Service(LSPS1ServiceEvent::RequestForPaymentDetails {
155+
request_id,
156+
counterparty_node_id,
157+
order,
158+
}) = _request_for_payment_event
159+
{
160+
assert_eq!(request_id, _create_order_id.clone());
161+
assert_eq!(counterparty_node_id, client_node_id);
162+
assert_eq!(order, order_params);
163+
} else {
164+
panic!("Unexpected event");
165+
}
166+
167+
let json_str = r#"{
168+
"state": "EXPECT_PAYMENT",
169+
"expires_at": "2025-01-01T00:00:00Z",
170+
"fee_total_sat": "9999",
171+
"order_total_sat": "200999",
172+
"address": "bc1p5uvtaxzkjwvey2tfy49k5vtqfpjmrgm09cvs88ezyy8h2zv7jhas9tu4yr",
173+
"min_onchain_payment_confirmations": 1,
174+
"min_fee_for_0conf": 253
175+
}"#;
176+
177+
let onchain: LSPS1OnchainPaymentInfo =
178+
serde_json::from_str(json_str).expect("Failed to parse JSON");
179+
let payment_info = LSPS1PaymentInfo { bolt11: None, bolt12: None, onchain: Some(onchain) };
180+
let _now = LSPSDateTime::from_str("2024-01-01T00:00:00Z").expect("Failed to parse date");
181+
182+
let _ = service_handler
183+
.send_payment_details(_create_order_id.clone(), &client_node_id, payment_info.clone(), _now)
184+
.unwrap();
185+
186+
let create_order_response = get_lsps_message!(service_node, client_node_id);
187+
188+
client_node
189+
.liquidity_manager
190+
.handle_custom_message(create_order_response, service_node_id)
191+
.unwrap();
192+
193+
let order_created_event = client_node.liquidity_manager.next_event().unwrap();
194+
let expected_order_id = if let LiquidityEvent::LSPS1Client(LSPS1ClientEvent::OrderCreated {
195+
request_id,
196+
counterparty_node_id,
197+
order_id,
198+
order,
199+
payment,
200+
channel,
201+
}) = order_created_event
202+
{
203+
assert_eq!(request_id, _create_order_id);
204+
assert_eq!(counterparty_node_id, service_node_id);
205+
assert_eq!(order, order_params);
206+
assert_eq!(payment, payment_info);
207+
assert!(channel.is_none());
208+
order_id
209+
} else {
210+
panic!("Unexpected event");
211+
};
212+
213+
let check_order_status_id =
214+
client_handler.check_order_status(&service_node_id, expected_order_id.clone());
215+
let check_order_status = get_lsps_message!(client_node, service_node_id);
216+
217+
service_node
218+
.liquidity_manager
219+
.handle_custom_message(check_order_status, client_node_id)
220+
.unwrap();
221+
222+
let _check_payment_confirmation_event = service_node.liquidity_manager.next_event().unwrap();
223+
224+
if let LiquidityEvent::LSPS1Service(LSPS1ServiceEvent::CheckPaymentConfirmation {
225+
request_id,
226+
counterparty_node_id,
227+
order_id,
228+
}) = _check_payment_confirmation_event
229+
{
230+
assert_eq!(request_id, check_order_status_id);
231+
assert_eq!(counterparty_node_id, client_node_id);
232+
assert_eq!(order_id, expected_order_id.clone());
233+
} else {
234+
panic!("Unexpected event");
235+
}
236+
237+
let _ = service_handler
238+
.update_order_status(
239+
check_order_status_id.clone(),
240+
client_node_id,
241+
expected_order_id.clone(),
242+
LSPS1OrderState::Created,
243+
None,
244+
)
245+
.unwrap();
246+
247+
let order_status_response = get_lsps_message!(service_node, client_node_id);
248+
249+
client_node
250+
.liquidity_manager
251+
.handle_custom_message(order_status_response, service_node_id)
252+
.unwrap();
253+
254+
let order_status_event = client_node.liquidity_manager.next_event().unwrap();
255+
if let LiquidityEvent::LSPS1Client(LSPS1ClientEvent::OrderStatus {
256+
request_id,
257+
counterparty_node_id,
258+
order_id,
259+
order,
260+
payment,
261+
channel,
262+
}) = order_status_event
263+
{
264+
assert_eq!(request_id, check_order_status_id);
265+
assert_eq!(counterparty_node_id, service_node_id);
266+
assert_eq!(order, order_params);
267+
assert_eq!(payment, payment_info);
268+
assert!(channel.is_none());
269+
assert_eq!(order_id, expected_order_id);
270+
} else {
271+
panic!("Unexpected event");
272+
}
273+
}

0 commit comments

Comments
 (0)