Skip to content

Commit 8f61e46

Browse files
authored
Merge pull request #396 from tnull/2024-11-onchain-recovery-test
2 parents 9d6a63f + c17c995 commit 8f61e46

File tree

2 files changed

+105
-4
lines changed

2 files changed

+105
-4
lines changed

tests/common/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub(crate) fn setup_two_nodes(
264264
) -> (TestNode, TestNode) {
265265
println!("== Node A ==");
266266
let config_a = random_config(anchor_channels);
267-
let node_a = setup_node(chain_source, config_a);
267+
let node_a = setup_node(chain_source, config_a, None);
268268

269269
println!("\n== Node B ==");
270270
let mut config_b = random_config(anchor_channels);
@@ -279,11 +279,13 @@ pub(crate) fn setup_two_nodes(
279279
.trusted_peers_no_reserve
280280
.push(node_a.node_id());
281281
}
282-
let node_b = setup_node(chain_source, config_b);
282+
let node_b = setup_node(chain_source, config_b, None);
283283
(node_a, node_b)
284284
}
285285

286-
pub(crate) fn setup_node(chain_source: &TestChainSource, config: Config) -> TestNode {
286+
pub(crate) fn setup_node(
287+
chain_source: &TestChainSource, config: Config, seed_bytes: Option<Vec<u8>>,
288+
) -> TestNode {
287289
setup_builder!(builder, config);
288290
match chain_source {
289291
TestChainSource::Esplora(electrsd) => {
@@ -302,6 +304,11 @@ pub(crate) fn setup_node(chain_source: &TestChainSource, config: Config) -> Test
302304
builder.set_chain_source_bitcoind_rpc(rpc_host, rpc_port, rpc_user, rpc_password);
303305
},
304306
}
307+
308+
if let Some(seed) = seed_bytes {
309+
builder.set_entropy_seed_bytes(seed).unwrap();
310+
}
311+
305312
let test_sync_store = Arc::new(TestSyncStore::new(config.storage_dir_path.into()));
306313
let node = builder.build_with_store(test_sync_store).unwrap();
307314
node.start().unwrap();

tests/integration_tests_rust.rs

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use ldk_node::{Builder, Event, NodeError};
2121
use lightning::ln::channelmanager::PaymentId;
2222
use lightning::util::persist::KVStore;
2323

24+
use bitcoincore_rpc::RpcApi;
25+
2426
use bitcoin::Amount;
2527

2628
use std::sync::Arc;
@@ -315,12 +317,104 @@ fn onchain_spend_receive() {
315317
assert!(node_b.list_balances().spendable_onchain_balance_sats < 100000);
316318
}
317319

320+
#[test]
321+
fn onchain_wallet_recovery() {
322+
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
323+
324+
let chain_source = TestChainSource::Esplora(&electrsd);
325+
326+
let seed_bytes = vec![42u8; 64];
327+
328+
let original_config = random_config(true);
329+
let original_node = setup_node(&chain_source, original_config, Some(seed_bytes.clone()));
330+
331+
let premine_amount_sat = 100_000;
332+
333+
let addr_1 = original_node.onchain_payment().new_address().unwrap();
334+
335+
premine_and_distribute_funds(
336+
&bitcoind.client,
337+
&electrsd.client,
338+
vec![addr_1],
339+
Amount::from_sat(premine_amount_sat),
340+
);
341+
original_node.sync_wallets().unwrap();
342+
assert_eq!(original_node.list_balances().spendable_onchain_balance_sats, premine_amount_sat);
343+
344+
let addr_2 = original_node.onchain_payment().new_address().unwrap();
345+
346+
let txid = bitcoind
347+
.client
348+
.send_to_address(
349+
&addr_2,
350+
Amount::from_sat(premine_amount_sat),
351+
None,
352+
None,
353+
None,
354+
None,
355+
None,
356+
None,
357+
)
358+
.unwrap();
359+
wait_for_tx(&electrsd.client, txid);
360+
361+
generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 1);
362+
363+
original_node.sync_wallets().unwrap();
364+
assert_eq!(
365+
original_node.list_balances().spendable_onchain_balance_sats,
366+
premine_amount_sat * 2
367+
);
368+
369+
original_node.stop().unwrap();
370+
drop(original_node);
371+
372+
// Now we start from scratch, only the seed remains the same.
373+
let recovered_config = random_config(true);
374+
let recovered_node = setup_node(&chain_source, recovered_config, Some(seed_bytes));
375+
376+
recovered_node.sync_wallets().unwrap();
377+
assert_eq!(
378+
recovered_node.list_balances().spendable_onchain_balance_sats,
379+
premine_amount_sat * 2
380+
);
381+
382+
// Check we sync even when skipping some addresses.
383+
let _addr_3 = recovered_node.onchain_payment().new_address().unwrap();
384+
let _addr_4 = recovered_node.onchain_payment().new_address().unwrap();
385+
let _addr_5 = recovered_node.onchain_payment().new_address().unwrap();
386+
let addr_6 = recovered_node.onchain_payment().new_address().unwrap();
387+
388+
let txid = bitcoind
389+
.client
390+
.send_to_address(
391+
&addr_6,
392+
Amount::from_sat(premine_amount_sat),
393+
None,
394+
None,
395+
None,
396+
None,
397+
None,
398+
None,
399+
)
400+
.unwrap();
401+
wait_for_tx(&electrsd.client, txid);
402+
403+
generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 1);
404+
405+
recovered_node.sync_wallets().unwrap();
406+
assert_eq!(
407+
recovered_node.list_balances().spendable_onchain_balance_sats,
408+
premine_amount_sat * 3
409+
);
410+
}
411+
318412
#[test]
319413
fn sign_verify_msg() {
320414
let (_bitcoind, electrsd) = setup_bitcoind_and_electrsd();
321415
let config = random_config(true);
322416
let chain_source = TestChainSource::Esplora(&electrsd);
323-
let node = setup_node(&chain_source, config);
417+
let node = setup_node(&chain_source, config, None);
324418

325419
// Tests arbitrary message signing and later verification
326420
let msg = "OK computer".as_bytes();

0 commit comments

Comments
 (0)