Skip to content

Commit 7d1934d

Browse files
fixup: LSPS5 tests -> move helper fn to the top. prefer methods instead of macros for better debugging
1 parent be0f7e8 commit 7d1934d

File tree

1 file changed

+147
-185
lines changed

1 file changed

+147
-185
lines changed

lightning-liquidity/tests/lsps5_integration_tests.rs

Lines changed: 147 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
mod common;
44

5-
use common::{create_service_and_client_nodes, get_lsps_message, LSPSNodes};
5+
use common::{create_service_and_client_nodes, get_lsps_message, LSPSNodes, LiquidityNode};
66

77
use lightning::check_closed_event;
88
use lightning::events::ClosureReason;
@@ -74,6 +74,147 @@ pub(crate) fn lsps5_test_setup<'a, 'b, 'c>(
7474
(lsps_nodes, validator)
7575
}
7676

77+
fn assert_lsps5_reject(
78+
service_node: &LiquidityNode<'_, '_, '_>, client_node: &LiquidityNode<'_, '_, '_>,
79+
) {
80+
let client_handler = client_node.liquidity_manager.lsps5_client_handler().unwrap();
81+
let service_node_id = service_node.inner.node.get_our_node_id();
82+
let client_node_id = client_node.inner.node.get_our_node_id();
83+
84+
let _ = client_handler
85+
.set_webhook(service_node_id, "App".to_string(), "https://example.org/webhook".to_string())
86+
.expect("Request should send");
87+
let request = get_lsps_message!(client_node, service_node_id);
88+
89+
let service_result =
90+
service_node.liquidity_manager.handle_custom_message(request, client_node_id);
91+
assert!(service_result.is_err(), "Service should reject request without prior interaction");
92+
93+
let req = get_lsps_message!(service_node, client_node_id);
94+
client_node.liquidity_manager.handle_custom_message(req, service_node_id).unwrap();
95+
let event = client_node.liquidity_manager.next_event().unwrap();
96+
match event {
97+
LiquidityEvent::LSPS5Client(LSPS5ClientEvent::WebhookRegistrationFailed {
98+
error, ..
99+
}) => {
100+
let error_to_check = LSPS5ProtocolError::NoPriorActivityError;
101+
assert_eq!(error, error_to_check.into());
102+
},
103+
_ => panic!("Expected WebhookRegistrationFailed event, got {:?}", event),
104+
}
105+
}
106+
107+
fn assert_lsps5_accept(
108+
service_node: &LiquidityNode<'_, '_, '_>, client_node: &LiquidityNode<'_, '_, '_>,
109+
) {
110+
let client_handler = client_node.liquidity_manager.lsps5_client_handler().unwrap();
111+
let service_node_id = service_node.inner.node.get_our_node_id();
112+
let client_node_id = client_node.inner.node.get_our_node_id();
113+
114+
let _ = client_handler
115+
.set_webhook(service_node_id, "App".to_string(), "https://example.org/webhook".to_string())
116+
.expect("Request should send");
117+
let request = get_lsps_message!(client_node, service_node_id);
118+
119+
let result = service_node.liquidity_manager.handle_custom_message(request, client_node_id);
120+
assert!(result.is_ok(), "Service should accept request after prior interaction");
121+
let _ = service_node.liquidity_manager.next_event().unwrap();
122+
let response = get_lsps_message!(service_node, client_node_id);
123+
client_node
124+
.liquidity_manager
125+
.handle_custom_message(response, service_node_id)
126+
.expect("Client should handle response");
127+
let event = client_node.liquidity_manager.next_event().unwrap();
128+
match event {
129+
LiquidityEvent::LSPS5Client(LSPS5ClientEvent::WebhookRegistered { .. }) => {},
130+
_ => panic!("Expected WebhookRegistered event, got {:?}", event),
131+
}
132+
}
133+
134+
fn establish_lsps2_prior_interaction(lsps_nodes: &LSPSNodes) {
135+
let service_node = &lsps_nodes.service_node;
136+
let client_node = &lsps_nodes.client_node;
137+
138+
let service_node_id = service_node.inner.node.get_our_node_id();
139+
let client_node_id = client_node.inner.node.get_our_node_id();
140+
141+
let lsps2_client = client_node.liquidity_manager.lsps2_client_handler().unwrap();
142+
let lsps2_service = service_node.liquidity_manager.lsps2_service_handler().unwrap();
143+
144+
let get_info_request_id = lsps2_client.request_opening_params(service_node_id, None);
145+
let get_info_req = get_lsps_message!(client_node, service_node_id);
146+
service_node.liquidity_manager.handle_custom_message(get_info_req, client_node_id).unwrap();
147+
148+
let get_info_event = service_node.liquidity_manager.next_event().unwrap();
149+
let opening_fee_params = match get_info_event {
150+
LiquidityEvent::LSPS2Service(LSPS2ServiceEvent::GetInfo {
151+
request_id,
152+
counterparty_node_id,
153+
..
154+
}) => {
155+
assert_eq!(request_id, get_info_request_id);
156+
assert_eq!(counterparty_node_id, client_node_id);
157+
let raw_opening_params = LSPS2RawOpeningFeeParams {
158+
min_fee_msat: 1000,
159+
proportional: 0,
160+
valid_until: LSPSDateTime::from_str("2035-05-20T08:30:45Z").unwrap(),
161+
min_lifetime: 144,
162+
max_client_to_self_delay: 144,
163+
min_payment_size_msat: 1,
164+
max_payment_size_msat: 1_000_000_000,
165+
};
166+
lsps2_service
167+
.opening_fee_params_generated(
168+
&client_node_id,
169+
request_id.clone(),
170+
vec![raw_opening_params],
171+
)
172+
.unwrap();
173+
let response = get_lsps_message!(service_node, client_node_id);
174+
client_node.liquidity_manager.handle_custom_message(response, service_node_id).unwrap();
175+
match client_node.liquidity_manager.next_event().unwrap() {
176+
LiquidityEvent::LSPS2Client(LSPS2ClientEvent::OpeningParametersReady {
177+
opening_fee_params_menu,
178+
..
179+
}) => opening_fee_params_menu.first().unwrap().clone(),
180+
_ => panic!("Unexpected event"),
181+
}
182+
},
183+
_ => panic!("Unexpected event"),
184+
};
185+
186+
let payment_size_msat = Some(1_000_000);
187+
let buy_request_id = lsps2_client
188+
.select_opening_params(service_node_id, payment_size_msat, opening_fee_params.clone())
189+
.unwrap();
190+
let buy_req = get_lsps_message!(client_node, service_node_id);
191+
service_node.liquidity_manager.handle_custom_message(buy_req, client_node_id).unwrap();
192+
let _ = service_node.liquidity_manager.next_event().unwrap();
193+
194+
let intercept_scid = service_node.inner.node.get_intercept_scid();
195+
let user_channel_id = 7;
196+
let cltv_expiry_delta = 144;
197+
lsps2_service
198+
.invoice_parameters_generated(
199+
&client_node_id,
200+
buy_request_id.clone(),
201+
intercept_scid,
202+
cltv_expiry_delta,
203+
true,
204+
user_channel_id,
205+
)
206+
.unwrap();
207+
let buy_resp = get_lsps_message!(service_node, client_node_id);
208+
client_node.liquidity_manager.handle_custom_message(buy_resp, service_node_id).unwrap();
209+
let _ = client_node.liquidity_manager.next_event().unwrap();
210+
211+
let intercept_id = InterceptId([0; 32]);
212+
let payment_hash = PaymentHash([1; 32]);
213+
lsps2_service.htlc_intercepted(intercept_scid, intercept_id, 1_000_000, payment_hash).unwrap();
214+
215+
let _ = service_node.liquidity_manager.next_event().unwrap();
216+
}
217+
77218
pub(crate) fn lsps5_lsps2_test_setup<'a, 'b, 'c>(
78219
nodes: Vec<Node<'a, 'b, 'c>>, time_provider: Arc<dyn TimeProvider + Send + Sync>,
79220
) -> (LSPSNodes<'a, 'b, 'c>, LSPS5Validator) {
@@ -1230,65 +1371,6 @@ fn test_notifications_and_peer_connected_resets_cooldown() {
12301371
}
12311372
}
12321373

1233-
macro_rules! assert_lsps5_reject {
1234-
($client_handler:expr, $service_node:expr, $client_node:expr, $service_node_id:expr, $client_node_id:expr) => {{
1235-
let _ = $client_handler
1236-
.set_webhook(
1237-
$service_node_id,
1238-
"App".to_string(),
1239-
"https://example.org/webhook".to_string(),
1240-
)
1241-
.expect("Request should send");
1242-
let request = get_lsps_message!($client_node, $service_node_id);
1243-
1244-
let service_result =
1245-
$service_node.liquidity_manager.handle_custom_message(request, $client_node_id);
1246-
assert!(service_result.is_err(), "Service should reject request without prior interaction");
1247-
1248-
let req = get_lsps_message!($service_node, $client_node_id);
1249-
$client_node.liquidity_manager.handle_custom_message(req, $service_node_id).unwrap();
1250-
let event = $client_node.liquidity_manager.next_event().unwrap();
1251-
match event {
1252-
LiquidityEvent::LSPS5Client(LSPS5ClientEvent::WebhookRegistrationFailed {
1253-
error,
1254-
..
1255-
}) => {
1256-
let error_to_check = LSPS5ProtocolError::NoPriorActivityError;
1257-
assert_eq!(error, error_to_check.into());
1258-
},
1259-
_ => panic!("Expected WebhookRegistrationFailed event, got {:?}", event),
1260-
}
1261-
}};
1262-
}
1263-
1264-
macro_rules! assert_lsps5_accept {
1265-
($client_handler:expr, $service_node:expr, $client_node:expr, $service_node_id:expr, $client_node_id:expr) => {{
1266-
let _ = $client_handler
1267-
.set_webhook(
1268-
$service_node_id,
1269-
"App".to_string(),
1270-
"https://example.org/webhook".to_string(),
1271-
)
1272-
.expect("Request should send");
1273-
let request = get_lsps_message!($client_node, $service_node_id);
1274-
1275-
let result =
1276-
$service_node.liquidity_manager.handle_custom_message(request, $client_node_id);
1277-
assert!(result.is_ok(), "Service should accept request after prior interaction");
1278-
let _ = $service_node.liquidity_manager.next_event().unwrap();
1279-
let response = get_lsps_message!($service_node, $client_node_id);
1280-
$client_node
1281-
.liquidity_manager
1282-
.handle_custom_message(response, $service_node_id)
1283-
.expect("Client should handle response");
1284-
let event = $client_node.liquidity_manager.next_event().unwrap();
1285-
match event {
1286-
LiquidityEvent::LSPS5Client(LSPS5ClientEvent::WebhookRegistered { .. }) => {},
1287-
_ => panic!("Expected WebhookRegistered event, got {:?}", event),
1288-
}
1289-
}};
1290-
}
1291-
12921374
#[test]
12931375
fn webhook_update_affects_future_notifications() {
12941376
let mock_time_provider = Arc::new(MockTimeProvider::new(1000));
@@ -1363,28 +1445,14 @@ fn dos_protection() {
13631445
let client_node_id = client_node.inner.node.get_our_node_id();
13641446
let service_node_id = service_node.inner.node.get_our_node_id();
13651447

1366-
let client_handler = client_node.liquidity_manager.lsps5_client_handler().unwrap();
1367-
13681448
// no channel is open so far -> should reject
1369-
assert_lsps5_reject!(
1370-
client_handler,
1371-
service_node,
1372-
client_node,
1373-
service_node_id,
1374-
client_node_id
1375-
);
1449+
assert_lsps5_reject(&service_node, &client_node);
13761450

13771451
let (_, _, _, channel_id, funding_tx) =
13781452
create_chan_between_nodes(&service_node.inner, &client_node.inner);
13791453

13801454
// now that a channel is open, should accept
1381-
assert_lsps5_accept!(
1382-
client_handler,
1383-
service_node,
1384-
client_node,
1385-
service_node_id,
1386-
client_node_id
1387-
);
1455+
assert_lsps5_accept(&service_node, &client_node);
13881456

13891457
close_channel(&service_node.inner, &client_node.inner, &channel_id, funding_tx, true);
13901458
let node_a_reason = ClosureReason::CounterpartyInitiatedCooperativeClosure;
@@ -1393,13 +1461,7 @@ fn dos_protection() {
13931461
check_closed_event!(client_node.inner, 1, node_b_reason, [service_node_id], 100000);
13941462

13951463
// channel is now closed again -> should reject
1396-
assert_lsps5_reject!(
1397-
client_handler,
1398-
service_node,
1399-
client_node,
1400-
service_node_id,
1401-
client_node_id
1402-
);
1464+
assert_lsps5_reject(&service_node, &client_node);
14031465
}
14041466

14051467
#[test]
@@ -1411,109 +1473,9 @@ fn lsps2_state_allows_lsps5_request() {
14111473

14121474
let (lsps_nodes, _) = lsps5_lsps2_test_setup(nodes, Arc::new(DefaultTimeProvider));
14131475

1414-
let client_node_id = lsps_nodes.client_node.inner.node.get_our_node_id();
1415-
let service_node_id = lsps_nodes.service_node.inner.node.get_our_node_id();
1416-
let client_handler = lsps_nodes.client_node.liquidity_manager.lsps5_client_handler().unwrap();
1417-
1418-
assert_lsps5_reject!(
1419-
client_handler,
1420-
lsps_nodes.service_node,
1421-
lsps_nodes.client_node,
1422-
service_node_id,
1423-
client_node_id
1424-
);
1476+
assert_lsps5_reject(&lsps_nodes.service_node, &lsps_nodes.client_node);
14251477

14261478
establish_lsps2_prior_interaction(&lsps_nodes);
14271479

1428-
assert_lsps5_accept!(
1429-
client_handler,
1430-
lsps_nodes.service_node,
1431-
lsps_nodes.client_node,
1432-
service_node_id,
1433-
client_node_id
1434-
);
1435-
}
1436-
1437-
fn establish_lsps2_prior_interaction(lsps_nodes: &LSPSNodes) {
1438-
let service_node = &lsps_nodes.service_node;
1439-
let client_node = &lsps_nodes.client_node;
1440-
1441-
let service_node_id = service_node.inner.node.get_our_node_id();
1442-
let client_node_id = client_node.inner.node.get_our_node_id();
1443-
1444-
let lsps2_client = client_node.liquidity_manager.lsps2_client_handler().unwrap();
1445-
let lsps2_service = service_node.liquidity_manager.lsps2_service_handler().unwrap();
1446-
1447-
let get_info_request_id = lsps2_client.request_opening_params(service_node_id, None);
1448-
let get_info_req = get_lsps_message!(client_node, service_node_id);
1449-
service_node.liquidity_manager.handle_custom_message(get_info_req, client_node_id).unwrap();
1450-
1451-
let get_info_event = service_node.liquidity_manager.next_event().unwrap();
1452-
let opening_fee_params = match get_info_event {
1453-
LiquidityEvent::LSPS2Service(LSPS2ServiceEvent::GetInfo {
1454-
request_id,
1455-
counterparty_node_id,
1456-
..
1457-
}) => {
1458-
assert_eq!(request_id, get_info_request_id);
1459-
assert_eq!(counterparty_node_id, client_node_id);
1460-
let raw_opening_params = LSPS2RawOpeningFeeParams {
1461-
min_fee_msat: 1000,
1462-
proportional: 0,
1463-
valid_until: LSPSDateTime::from_str("2035-05-20T08:30:45Z").unwrap(),
1464-
min_lifetime: 144,
1465-
max_client_to_self_delay: 144,
1466-
min_payment_size_msat: 1,
1467-
max_payment_size_msat: 1_000_000_000,
1468-
};
1469-
lsps2_service
1470-
.opening_fee_params_generated(
1471-
&client_node_id,
1472-
request_id.clone(),
1473-
vec![raw_opening_params],
1474-
)
1475-
.unwrap();
1476-
let response = get_lsps_message!(service_node, client_node_id);
1477-
client_node.liquidity_manager.handle_custom_message(response, service_node_id).unwrap();
1478-
match client_node.liquidity_manager.next_event().unwrap() {
1479-
LiquidityEvent::LSPS2Client(LSPS2ClientEvent::OpeningParametersReady {
1480-
opening_fee_params_menu,
1481-
..
1482-
}) => opening_fee_params_menu.first().unwrap().clone(),
1483-
_ => panic!("Unexpected event"),
1484-
}
1485-
},
1486-
_ => panic!("Unexpected event"),
1487-
};
1488-
1489-
let payment_size_msat = Some(1_000_000);
1490-
let buy_request_id = lsps2_client
1491-
.select_opening_params(service_node_id, payment_size_msat, opening_fee_params.clone())
1492-
.unwrap();
1493-
let buy_req = get_lsps_message!(client_node, service_node_id);
1494-
service_node.liquidity_manager.handle_custom_message(buy_req, client_node_id).unwrap();
1495-
let _ = service_node.liquidity_manager.next_event().unwrap();
1496-
1497-
let intercept_scid = service_node.inner.node.get_intercept_scid();
1498-
let user_channel_id = 7;
1499-
let cltv_expiry_delta = 144;
1500-
lsps2_service
1501-
.invoice_parameters_generated(
1502-
&client_node_id,
1503-
buy_request_id.clone(),
1504-
intercept_scid,
1505-
cltv_expiry_delta,
1506-
true,
1507-
user_channel_id,
1508-
)
1509-
.unwrap();
1510-
let buy_resp = get_lsps_message!(service_node, client_node_id);
1511-
client_node.liquidity_manager.handle_custom_message(buy_resp, service_node_id).unwrap();
1512-
let _ = client_node.liquidity_manager.next_event().unwrap();
1513-
1514-
let intercept_id = InterceptId([0; 32]);
1515-
let payment_hash = PaymentHash([1; 32]);
1516-
lsps2_service.htlc_intercepted(intercept_scid, intercept_id, 1_000_000, payment_hash).unwrap();
1517-
1518-
let _ = service_node.liquidity_manager.next_event().unwrap();
1480+
assert_lsps5_accept(&lsps_nodes.service_node, &lsps_nodes.client_node);
15191481
}

0 commit comments

Comments
 (0)