@@ -919,14 +919,16 @@ impl Drop for BackgroundProcessor {
919
919
920
920
#[ cfg( all( feature = "std" , test) ) ]
921
921
mod tests {
922
+ use bitcoin:: ScriptBuf ;
922
923
use bitcoin:: blockdata:: constants:: { genesis_block, ChainHash } ;
923
924
use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
924
925
use bitcoin:: blockdata:: transaction:: { Transaction , TxOut } ;
925
926
use bitcoin:: network:: constants:: Network ;
926
927
use bitcoin:: secp256k1:: { SecretKey , PublicKey , Secp256k1 } ;
927
- use lightning:: chain:: { BestBlock , Confirm , chainmonitor} ;
928
+ use lightning:: chain:: { BestBlock , Confirm , chainmonitor, Filter } ;
928
929
use lightning:: chain:: channelmonitor:: ANTI_REORG_DELAY ;
929
- use lightning:: sign:: { InMemorySigner , KeysManager } ;
930
+ use lightning:: chain:: chaininterface:: { ConfirmationTarget , FeeEstimator } ;
931
+ use lightning:: sign:: { InMemorySigner , KeysManager , SpendableOutputDescriptor } ;
930
932
use lightning:: chain:: transaction:: OutPoint ;
931
933
use lightning:: events:: { Event , PathFailure , MessageSendEventsProvider , MessageSendEvent } ;
932
934
use lightning:: { get_event_msg, get_event} ;
@@ -947,6 +949,7 @@ mod tests {
947
949
CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE , CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE , CHANNEL_MANAGER_PERSISTENCE_KEY ,
948
950
NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE , NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE , NETWORK_GRAPH_PERSISTENCE_KEY ,
949
951
SCORER_PERSISTENCE_PRIMARY_NAMESPACE , SCORER_PERSISTENCE_SECONDARY_NAMESPACE , SCORER_PERSISTENCE_KEY } ;
952
+ use lightning:: util:: sweep:: { OutputSweeper , OutputSpendStatus } ;
950
953
use lightning_persister:: fs_store:: FilesystemStore ;
951
954
use std:: collections:: VecDeque ;
952
955
use std:: { fs, env} ;
@@ -1009,6 +1012,7 @@ mod tests {
1009
1012
logger : Arc < test_utils:: TestLogger > ,
1010
1013
best_block : BestBlock ,
1011
1014
scorer : Arc < LockingWrapper < TestScorer > > ,
1015
+ sweeper : Arc < OutputSweeper < Arc < test_utils:: TestBroadcaster > , Arc < dyn Filter + Sync + Send > , Arc < FilesystemStore > , Arc < test_utils:: TestLogger > > > ,
1012
1016
}
1013
1017
1014
1018
impl Node {
@@ -1271,10 +1275,30 @@ mod tests {
1271
1275
let router = Arc :: new ( DefaultRouter :: new ( network_graph. clone ( ) , logger. clone ( ) , Arc :: clone ( & keys_manager) , scorer. clone ( ) , Default :: default ( ) ) ) ;
1272
1276
let chain_source = Arc :: new ( test_utils:: TestChainSource :: new ( Network :: Bitcoin ) ) ;
1273
1277
let kv_store = Arc :: new ( FilesystemStore :: new ( format ! ( "{}_persister_{}" , & persist_dir, i) . into ( ) ) ) ;
1278
+ let now = Duration :: from_secs ( genesis_block. header . time as u64 ) ;
1279
+ let keys_manager = Arc :: new ( KeysManager :: new ( & seed, now. as_secs ( ) , now. subsec_nanos ( ) ) ) ;
1274
1280
let chain_monitor = Arc :: new ( chainmonitor:: ChainMonitor :: new ( Some ( chain_source. clone ( ) ) , tx_broadcaster. clone ( ) , logger. clone ( ) , fee_estimator. clone ( ) , kv_store. clone ( ) ) ) ;
1275
1281
let best_block = BestBlock :: from_network ( network) ;
1276
1282
let params = ChainParameters { network, best_block } ;
1277
1283
let manager = Arc :: new ( ChannelManager :: new ( fee_estimator. clone ( ) , chain_monitor. clone ( ) , tx_broadcaster. clone ( ) , router. clone ( ) , logger. clone ( ) , keys_manager. clone ( ) , keys_manager. clone ( ) , keys_manager. clone ( ) , UserConfig :: default ( ) , params, genesis_block. header . time ) ) ;
1284
+
1285
+ let spend_fee_estimator = Arc :: clone ( & fee_estimator) ;
1286
+ let spend_keys_manager = Arc :: clone ( & keys_manager) ;
1287
+ let spend_outputs_callback = move |output_descriptors : & [ & SpendableOutputDescriptor ] | {
1288
+ let fee_rate = spend_fee_estimator
1289
+ . get_est_sat_per_1000_weight ( ConfirmationTarget :: NonAnchorChannelFee ) ;
1290
+ spend_keys_manager. spend_spendable_outputs (
1291
+ output_descriptors,
1292
+ Vec :: new ( ) ,
1293
+ ScriptBuf :: new ( ) ,
1294
+ fee_rate,
1295
+ None ,
1296
+ & Secp256k1 :: new ( ) ,
1297
+ )
1298
+ } ;
1299
+ let sweeper = Arc :: new ( OutputSweeper :: new ( Arc :: clone ( & tx_broadcaster) ,
1300
+ Arc :: clone ( & kv_store) , best_block, None :: < Arc < dyn Filter + Sync + Send > > ,
1301
+ Arc :: clone ( & logger) , spend_outputs_callback) ) ;
1278
1302
let p2p_gossip_sync = Arc :: new ( P2PGossipSync :: new ( network_graph. clone ( ) , Some ( chain_source. clone ( ) ) , logger. clone ( ) ) ) ;
1279
1303
let rapid_gossip_sync = Arc :: new ( RapidGossipSync :: new ( network_graph. clone ( ) , logger. clone ( ) ) ) ;
1280
1304
let msg_handler = MessageHandler {
@@ -1283,7 +1307,7 @@ mod tests {
1283
1307
onion_message_handler : IgnoringMessageHandler { } , custom_message_handler : IgnoringMessageHandler { }
1284
1308
} ;
1285
1309
let peer_manager = Arc :: new ( PeerManager :: new ( msg_handler, 0 , & seed, logger. clone ( ) , keys_manager. clone ( ) ) ) ;
1286
- let node = Node { node : manager, p2p_gossip_sync, rapid_gossip_sync, peer_manager, chain_monitor, kv_store, tx_broadcaster, network_graph, logger, best_block, scorer } ;
1310
+ let node = Node { node : manager, p2p_gossip_sync, rapid_gossip_sync, peer_manager, chain_monitor, kv_store, tx_broadcaster, network_graph, logger, best_block, scorer, sweeper } ;
1287
1311
nodes. push ( node) ;
1288
1312
}
1289
1313
@@ -1352,15 +1376,32 @@ mod tests {
1352
1376
1 => {
1353
1377
node. node . transactions_confirmed ( & header, & txdata, height) ;
1354
1378
node. chain_monitor . transactions_confirmed ( & header, & txdata, height) ;
1379
+ node. sweeper . transactions_confirmed ( & header, & txdata, height) ;
1355
1380
} ,
1356
1381
x if x == depth => {
1357
1382
node. node . best_block_updated ( & header, height) ;
1358
1383
node. chain_monitor . best_block_updated ( & header, height) ;
1384
+ node. sweeper . best_block_updated ( & header, height) ;
1359
1385
} ,
1360
1386
_ => { } ,
1361
1387
}
1362
1388
}
1363
1389
}
1390
+
1391
+ fn advance_chain ( node : & mut Node , num_blocks : u32 ) {
1392
+ for i in 1 ..=num_blocks {
1393
+ let prev_blockhash = node. best_block . block_hash ;
1394
+ let height = node. best_block . height + 1 ;
1395
+ let header = create_dummy_header ( prev_blockhash, height) ;
1396
+ node. best_block = BestBlock :: new ( header. block_hash ( ) , height) ;
1397
+ if i == num_blocks {
1398
+ node. node . best_block_updated ( & header, height) ;
1399
+ node. chain_monitor . best_block_updated ( & header, height) ;
1400
+ node. sweeper . best_block_updated ( & header, height) ;
1401
+ }
1402
+ }
1403
+ }
1404
+
1364
1405
fn confirm_transaction ( node : & mut Node , tx : & Transaction ) {
1365
1406
confirm_transaction_depth ( node, tx, ANTI_REORG_DELAY ) ;
1366
1407
}
@@ -1592,6 +1633,9 @@ mod tests {
1592
1633
let _as_channel_update = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendChannelUpdate , nodes[ 1 ] . node. get_our_node_id( ) ) ;
1593
1634
nodes[ 1 ] . node . handle_channel_ready ( & nodes[ 0 ] . node . get_our_node_id ( ) , & as_funding) ;
1594
1635
let _bs_channel_update = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendChannelUpdate , nodes[ 0 ] . node. get_our_node_id( ) ) ;
1636
+ let broadcast_funding = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) . unwrap ( ) ;
1637
+ assert_eq ! ( broadcast_funding. txid( ) , funding_tx. txid( ) ) ;
1638
+ assert ! ( nodes[ 0 ] . tx_broadcaster. txn_broadcasted. lock( ) . unwrap( ) . is_empty( ) ) ;
1595
1639
1596
1640
if !std:: thread:: panicking ( ) {
1597
1641
bg_processor. stop ( ) . unwrap ( ) ;
@@ -1617,10 +1661,65 @@ mod tests {
1617
1661
. recv_timeout ( Duration :: from_secs ( EVENT_DEADLINE ) )
1618
1662
. expect ( "Events not handled within deadline" ) ;
1619
1663
match event {
1620
- Event :: SpendableOutputs { .. } => { } ,
1664
+ Event :: SpendableOutputs { outputs, channel_id } => {
1665
+ nodes[ 0 ] . sweeper . track_spendable_outputs ( outputs, channel_id, false ) ;
1666
+ } ,
1621
1667
_ => panic ! ( "Unexpected event: {:?}" , event) ,
1622
1668
}
1623
1669
1670
+ // Check we generate an initial sweeping tx.
1671
+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1672
+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1673
+ let sweep_tx_0 = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) . unwrap ( ) ;
1674
+ match tracked_output. status {
1675
+ OutputSpendStatus :: PendingFirstConfirmation { latest_spending_tx, .. } => {
1676
+ assert_eq ! ( sweep_tx_0. txid( ) , latest_spending_tx. txid( ) ) ;
1677
+ }
1678
+ _ => panic ! ( "Unexpected status" ) ,
1679
+ }
1680
+
1681
+ // Check we regenerate and rebroadcast the sweeping tx each block.
1682
+ advance_chain ( & mut nodes[ 0 ] , 1 ) ;
1683
+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1684
+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1685
+ let sweep_tx_1 = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) . unwrap ( ) ;
1686
+ match tracked_output. status {
1687
+ OutputSpendStatus :: PendingFirstConfirmation { latest_spending_tx, .. } => {
1688
+ assert_eq ! ( sweep_tx_1. txid( ) , latest_spending_tx. txid( ) ) ;
1689
+ }
1690
+ _ => panic ! ( "Unexpected status" ) ,
1691
+ }
1692
+ assert_ne ! ( sweep_tx_0, sweep_tx_1) ;
1693
+
1694
+ advance_chain ( & mut nodes[ 0 ] , 1 ) ;
1695
+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1696
+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1697
+ let sweep_tx_2 = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) . unwrap ( ) ;
1698
+ match tracked_output. status {
1699
+ OutputSpendStatus :: PendingFirstConfirmation { latest_spending_tx, .. } => {
1700
+ assert_eq ! ( sweep_tx_2. txid( ) , latest_spending_tx. txid( ) ) ;
1701
+ }
1702
+ _ => panic ! ( "Unexpected status" ) ,
1703
+ }
1704
+ assert_ne ! ( sweep_tx_0, sweep_tx_2) ;
1705
+ assert_ne ! ( sweep_tx_1, sweep_tx_2) ;
1706
+
1707
+ // Check we still track the spendable outputs up to ANTI_REORG_DELAY confirmations.
1708
+ confirm_transaction_depth ( & mut nodes[ 0 ] , & sweep_tx_2, 5 ) ;
1709
+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1710
+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1711
+ match tracked_output. status {
1712
+ OutputSpendStatus :: PendingThresholdConfirmations { latest_spending_tx, .. } => {
1713
+ assert_eq ! ( sweep_tx_2. txid( ) , latest_spending_tx. txid( ) ) ;
1714
+ }
1715
+ _ => panic ! ( "Unexpected status" ) ,
1716
+ }
1717
+
1718
+ // Check we stop tracking the spendable outputs when one of the txs reaches
1719
+ // ANTI_REORG_DELAY confirmations.
1720
+ confirm_transaction_depth ( & mut nodes[ 0 ] , & sweep_tx_0, ANTI_REORG_DELAY ) ;
1721
+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 0 ) ;
1722
+
1624
1723
if !std:: thread:: panicking ( ) {
1625
1724
bg_processor. stop ( ) . unwrap ( ) ;
1626
1725
}
0 commit comments