Skip to content

Commit dec6f22

Browse files
committed
Add test for payment persistence after node restart
Add integration test that verifies 200 payments are correctly persisted and retrievable via `list_payments` after restarting a node. Co-Authored-By: Claude AI
1 parent f1885be commit dec6f22

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

tests/integration_tests_rust.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,3 +2317,120 @@ async fn lsps2_lsp_trusts_client_but_client_does_not_claim() {
23172317
Some(6)
23182318
);
23192319
}
2320+
2321+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
2322+
async fn payment_persistence_after_restart() {
2323+
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
2324+
let chain_source = TestChainSource::Esplora(&electrsd);
2325+
2326+
// Setup nodes manually so we can restart node_a with the same config
2327+
println!("== Node A ==");
2328+
let config_a = random_config(true);
2329+
2330+
let num_payments = 200;
2331+
let payment_amount_msat = 1_000_000; // 1000 sats per payment
2332+
2333+
{
2334+
let node_a = setup_node(&chain_source, config_a.clone());
2335+
2336+
println!("\n== Node B ==");
2337+
let config_b = random_config(true);
2338+
let node_b = setup_node(&chain_source, config_b);
2339+
2340+
let addr_a = node_a.onchain_payment().new_address().unwrap();
2341+
let addr_b = node_b.onchain_payment().new_address().unwrap();
2342+
2343+
// Premine sufficient funds for a large channel and many payments
2344+
let premine_amount_sat = 10_000_000;
2345+
premine_and_distribute_funds(
2346+
&bitcoind.client,
2347+
&electrsd.client,
2348+
vec![addr_a, addr_b],
2349+
Amount::from_sat(premine_amount_sat),
2350+
)
2351+
.await;
2352+
node_a.sync_wallets().unwrap();
2353+
node_b.sync_wallets().unwrap();
2354+
assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
2355+
assert_eq!(node_b.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
2356+
2357+
// Open a large channel from node_a to node_b
2358+
let channel_amount_sat = 5_000_000;
2359+
open_channel(&node_a, &node_b, channel_amount_sat, true, &electrsd).await;
2360+
generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await;
2361+
node_a.sync_wallets().unwrap();
2362+
node_b.sync_wallets().unwrap();
2363+
expect_channel_ready_event!(node_a, node_b.node_id());
2364+
expect_channel_ready_event!(node_b, node_a.node_id());
2365+
2366+
// Send 200 payments from node_a to node_b
2367+
println!("\nSending {} payments from A to B...", num_payments);
2368+
let invoice_description =
2369+
Bolt11InvoiceDescription::Direct(Description::new(String::from("test")).unwrap());
2370+
2371+
for i in 0..num_payments {
2372+
let invoice = node_b
2373+
.bolt11_payment()
2374+
.receive(payment_amount_msat, &invoice_description.clone().into(), 3600)
2375+
.unwrap();
2376+
let payment_id = node_a.bolt11_payment().send(&invoice, None).unwrap();
2377+
expect_event!(node_a, PaymentSuccessful);
2378+
expect_event!(node_b, PaymentReceived);
2379+
2380+
if (i + 1) % 50 == 0 {
2381+
println!("Completed {} payments", i + 1);
2382+
}
2383+
2384+
// Verify payment succeeded
2385+
assert_eq!(node_a.payment(&payment_id).unwrap().status, PaymentStatus::Succeeded);
2386+
}
2387+
println!("All {} payments completed successfully", num_payments);
2388+
2389+
// Verify node_a has 200 outbound Bolt11 payments before shutdown
2390+
let outbound_payments_before = node_a.list_payments_with_filter(|p| {
2391+
p.direction == PaymentDirection::Outbound
2392+
&& matches!(p.kind, PaymentKind::Bolt11 { .. })
2393+
});
2394+
assert_eq!(outbound_payments_before.len(), num_payments);
2395+
2396+
// Shut down both nodes
2397+
println!("\nShutting down nodes...");
2398+
node_a.stop().unwrap();
2399+
node_b.stop().unwrap();
2400+
}
2401+
2402+
// Restart node_a with the same config
2403+
println!("\nRestarting node A...");
2404+
let restarted_node_a = setup_node(&chain_source, config_a);
2405+
2406+
// Assert all 200 payments are still in the store
2407+
let outbound_payments_after = restarted_node_a.list_payments_with_filter(|p| {
2408+
p.direction == PaymentDirection::Outbound && matches!(p.kind, PaymentKind::Bolt11 { .. })
2409+
});
2410+
assert_eq!(
2411+
outbound_payments_after.len(),
2412+
num_payments,
2413+
"Expected {} payments after restart, found {}",
2414+
num_payments,
2415+
outbound_payments_after.len()
2416+
);
2417+
2418+
// Verify all payments have the correct status
2419+
for payment in &outbound_payments_after {
2420+
assert_eq!(
2421+
payment.status,
2422+
PaymentStatus::Succeeded,
2423+
"Payment {:?} has unexpected status {:?}",
2424+
payment.id,
2425+
payment.status
2426+
);
2427+
assert_eq!(payment.amount_msat, Some(payment_amount_msat));
2428+
}
2429+
2430+
println!(
2431+
"Successfully verified {} payments persisted after restart",
2432+
outbound_payments_after.len()
2433+
);
2434+
2435+
restarted_node_a.stop().unwrap();
2436+
}

0 commit comments

Comments
 (0)