@@ -919,14 +919,16 @@ impl Drop for BackgroundProcessor {
919919
920920#[ cfg( all( feature = "std" , test) ) ]
921921mod tests {
922+ use bitcoin:: { ScriptBuf , Txid } ;
922923 use bitcoin:: blockdata:: constants:: { genesis_block, ChainHash } ;
923924 use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
924925 use bitcoin:: blockdata:: transaction:: { Transaction , TxOut } ;
926+ use bitcoin:: hashes:: Hash ;
925927 use bitcoin:: network:: constants:: Network ;
926928 use bitcoin:: secp256k1:: { SecretKey , PublicKey , Secp256k1 } ;
927- use lightning:: chain:: { BestBlock , Confirm , chainmonitor} ;
929+ use lightning:: chain:: { BestBlock , Confirm , chainmonitor, Filter } ;
928930 use lightning:: chain:: channelmonitor:: ANTI_REORG_DELAY ;
929- use lightning:: sign:: { InMemorySigner , KeysManager } ;
931+ use lightning:: sign:: { InMemorySigner , KeysManager , ChangeDestinationSource } ;
930932 use lightning:: chain:: transaction:: OutPoint ;
931933 use lightning:: events:: { Event , PathFailure , MessageSendEventsProvider , MessageSendEvent } ;
932934 use lightning:: { get_event_msg, get_event} ;
@@ -947,6 +949,7 @@ mod tests {
947949 CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE , CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE , CHANNEL_MANAGER_PERSISTENCE_KEY ,
948950 NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE , NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE , NETWORK_GRAPH_PERSISTENCE_KEY ,
949951 SCORER_PERSISTENCE_PRIMARY_NAMESPACE , SCORER_PERSISTENCE_SECONDARY_NAMESPACE , SCORER_PERSISTENCE_KEY } ;
952+ use lightning:: util:: sweep:: { OutputSweeper , OutputSpendStatus } ;
950953 use lightning_persister:: fs_store:: FilesystemStore ;
951954 use std:: collections:: VecDeque ;
952955 use std:: { fs, env} ;
@@ -1009,6 +1012,9 @@ mod tests {
10091012 logger : Arc < test_utils:: TestLogger > ,
10101013 best_block : BestBlock ,
10111014 scorer : Arc < LockingWrapper < TestScorer > > ,
1015+ sweeper : Arc < OutputSweeper < Arc < test_utils:: TestBroadcaster > , Arc < TestWallet > ,
1016+ Arc < test_utils:: TestFeeEstimator > , Arc < dyn Filter + Sync + Send > , Arc < FilesystemStore > ,
1017+ Arc < test_utils:: TestLogger > , Arc < KeysManager > > > ,
10121018 }
10131019
10141020 impl Node {
@@ -1247,6 +1253,14 @@ mod tests {
12471253 }
12481254 }
12491255
1256+ struct TestWallet { }
1257+
1258+ impl ChangeDestinationSource for TestWallet {
1259+ fn get_change_destination_script ( & self ) -> Result < ScriptBuf , ( ) > {
1260+ Ok ( ScriptBuf :: new ( ) )
1261+ }
1262+ }
1263+
12501264 fn get_full_filepath ( filepath : String , filename : String ) -> String {
12511265 let mut path = PathBuf :: from ( filepath) ;
12521266 path. push ( filename) ;
@@ -1271,10 +1285,15 @@ mod tests {
12711285 let router = Arc :: new ( DefaultRouter :: new ( network_graph. clone ( ) , logger. clone ( ) , Arc :: clone ( & keys_manager) , scorer. clone ( ) , Default :: default ( ) ) ) ;
12721286 let chain_source = Arc :: new ( test_utils:: TestChainSource :: new ( Network :: Bitcoin ) ) ;
12731287 let kv_store = Arc :: new ( FilesystemStore :: new ( format ! ( "{}_persister_{}" , & persist_dir, i) . into ( ) ) ) ;
1288+ let now = Duration :: from_secs ( genesis_block. header . time as u64 ) ;
1289+ let keys_manager = Arc :: new ( KeysManager :: new ( & seed, now. as_secs ( ) , now. subsec_nanos ( ) ) ) ;
12741290 let chain_monitor = Arc :: new ( chainmonitor:: ChainMonitor :: new ( Some ( chain_source. clone ( ) ) , tx_broadcaster. clone ( ) , logger. clone ( ) , fee_estimator. clone ( ) , kv_store. clone ( ) ) ) ;
12751291 let best_block = BestBlock :: from_network ( network) ;
12761292 let params = ChainParameters { network, best_block } ;
12771293 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 ) ) ;
1294+ let wallet = Arc :: new ( TestWallet { } ) ;
1295+ let sweeper = Arc :: new ( OutputSweeper :: new ( best_block, Arc :: clone ( & tx_broadcaster) , Arc :: clone ( & fee_estimator) ,
1296+ None :: < Arc < dyn Filter + Sync + Send > > , Arc :: clone ( & keys_manager) , wallet, Arc :: clone ( & kv_store) , Arc :: clone ( & logger) ) ) ;
12781297 let p2p_gossip_sync = Arc :: new ( P2PGossipSync :: new ( network_graph. clone ( ) , Some ( chain_source. clone ( ) ) , logger. clone ( ) ) ) ;
12791298 let rapid_gossip_sync = Arc :: new ( RapidGossipSync :: new ( network_graph. clone ( ) , logger. clone ( ) ) ) ;
12801299 let msg_handler = MessageHandler {
@@ -1283,7 +1302,7 @@ mod tests {
12831302 onion_message_handler : IgnoringMessageHandler { } , custom_message_handler : IgnoringMessageHandler { }
12841303 } ;
12851304 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 } ;
1305+ 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 } ;
12871306 nodes. push ( node) ;
12881307 }
12891308
@@ -1352,15 +1371,40 @@ mod tests {
13521371 1 => {
13531372 node. node . transactions_confirmed ( & header, & txdata, height) ;
13541373 node. chain_monitor . transactions_confirmed ( & header, & txdata, height) ;
1374+ node. sweeper . transactions_confirmed ( & header, & txdata, height) ;
13551375 } ,
13561376 x if x == depth => {
1377+ // We need the TestBroadcaster to know about the new height so that it doesn't think
1378+ // we're violating the time lock requirements of transactions broadcasted at that
1379+ // point.
1380+ node. tx_broadcaster . blocks . lock ( ) . unwrap ( ) . push ( ( genesis_block ( Network :: Bitcoin ) , height) ) ;
13571381 node. node . best_block_updated ( & header, height) ;
13581382 node. chain_monitor . best_block_updated ( & header, height) ;
1383+ node. sweeper . best_block_updated ( & header, height) ;
13591384 } ,
13601385 _ => { } ,
13611386 }
13621387 }
13631388 }
1389+
1390+ fn advance_chain ( node : & mut Node , num_blocks : u32 ) {
1391+ for i in 1 ..=num_blocks {
1392+ let prev_blockhash = node. best_block . block_hash ;
1393+ let height = node. best_block . height + 1 ;
1394+ let header = create_dummy_header ( prev_blockhash, height) ;
1395+ node. best_block = BestBlock :: new ( header. block_hash ( ) , height) ;
1396+ if i == num_blocks {
1397+ // We need the TestBroadcaster to know about the new height so that it doesn't think
1398+ // we're violating the time lock requirements of transactions broadcasted at that
1399+ // point.
1400+ node. tx_broadcaster . blocks . lock ( ) . unwrap ( ) . push ( ( genesis_block ( Network :: Bitcoin ) , height) ) ;
1401+ node. node . best_block_updated ( & header, height) ;
1402+ node. chain_monitor . best_block_updated ( & header, height) ;
1403+ node. sweeper . best_block_updated ( & header, height) ;
1404+ }
1405+ }
1406+ }
1407+
13641408 fn confirm_transaction ( node : & mut Node , tx : & Transaction ) {
13651409 confirm_transaction_depth ( node, tx, ANTI_REORG_DELAY ) ;
13661410 }
@@ -1592,6 +1636,9 @@ mod tests {
15921636 let _as_channel_update = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendChannelUpdate , nodes[ 1 ] . node. get_our_node_id( ) ) ;
15931637 nodes[ 1 ] . node . handle_channel_ready ( & nodes[ 0 ] . node . get_our_node_id ( ) , & as_funding) ;
15941638 let _bs_channel_update = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendChannelUpdate , nodes[ 0 ] . node. get_our_node_id( ) ) ;
1639+ let broadcast_funding = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) . unwrap ( ) ;
1640+ assert_eq ! ( broadcast_funding. txid( ) , funding_tx. txid( ) ) ;
1641+ assert ! ( nodes[ 0 ] . tx_broadcaster. txn_broadcasted. lock( ) . unwrap( ) . is_empty( ) ) ;
15951642
15961643 if !std:: thread:: panicking ( ) {
15971644 bg_processor. stop ( ) . unwrap ( ) ;
@@ -1617,10 +1664,95 @@ mod tests {
16171664 . recv_timeout ( Duration :: from_secs ( EVENT_DEADLINE ) )
16181665 . expect ( "Events not handled within deadline" ) ;
16191666 match event {
1620- Event :: SpendableOutputs { .. } => { } ,
1667+ Event :: SpendableOutputs { outputs, channel_id } => {
1668+ nodes[ 0 ] . sweeper . track_spendable_outputs ( outputs, channel_id, false , Some ( 153 ) ) ;
1669+ } ,
16211670 _ => panic ! ( "Unexpected event: {:?}" , event) ,
16221671 }
16231672
1673+ // Check we don't generate an initial sweeping tx until we reach the required height.
1674+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1675+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1676+ if let Some ( sweep_tx_0) = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) {
1677+ assert ! ( !tracked_output. is_spent_in( & sweep_tx_0) ) ;
1678+ match tracked_output. status {
1679+ OutputSpendStatus :: PendingInitialBroadcast { delayed_until_height } => {
1680+ assert_eq ! ( delayed_until_height, Some ( 153 ) ) ;
1681+ }
1682+ _ => panic ! ( "Unexpected status" ) ,
1683+ }
1684+ }
1685+
1686+ advance_chain ( & mut nodes[ 0 ] , 3 ) ;
1687+
1688+ // Check we generate an initial sweeping tx.
1689+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1690+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1691+ let sweep_tx_0 = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) . unwrap ( ) ;
1692+ match tracked_output. status {
1693+ OutputSpendStatus :: PendingFirstConfirmation { latest_spending_tx, .. } => {
1694+ assert_eq ! ( sweep_tx_0. txid( ) , latest_spending_tx. txid( ) ) ;
1695+ }
1696+ _ => panic ! ( "Unexpected status" ) ,
1697+ }
1698+
1699+ // Check we regenerate and rebroadcast the sweeping tx each block.
1700+ advance_chain ( & mut nodes[ 0 ] , 1 ) ;
1701+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1702+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1703+ let sweep_tx_1 = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) . unwrap ( ) ;
1704+ match tracked_output. status {
1705+ OutputSpendStatus :: PendingFirstConfirmation { latest_spending_tx, .. } => {
1706+ assert_eq ! ( sweep_tx_1. txid( ) , latest_spending_tx. txid( ) ) ;
1707+ }
1708+ _ => panic ! ( "Unexpected status" ) ,
1709+ }
1710+ assert_ne ! ( sweep_tx_0, sweep_tx_1) ;
1711+
1712+ advance_chain ( & mut nodes[ 0 ] , 1 ) ;
1713+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1714+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1715+ let sweep_tx_2 = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . pop ( ) . unwrap ( ) ;
1716+ match tracked_output. status {
1717+ OutputSpendStatus :: PendingFirstConfirmation { latest_spending_tx, .. } => {
1718+ assert_eq ! ( sweep_tx_2. txid( ) , latest_spending_tx. txid( ) ) ;
1719+ }
1720+ _ => panic ! ( "Unexpected status" ) ,
1721+ }
1722+ assert_ne ! ( sweep_tx_0, sweep_tx_2) ;
1723+ assert_ne ! ( sweep_tx_1, sweep_tx_2) ;
1724+
1725+ // Check we still track the spendable outputs up to ANTI_REORG_DELAY confirmations.
1726+ confirm_transaction_depth ( & mut nodes[ 0 ] , & sweep_tx_2, 5 ) ;
1727+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1728+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1729+ match tracked_output. status {
1730+ OutputSpendStatus :: PendingThresholdConfirmations { latest_spending_tx, .. } => {
1731+ assert_eq ! ( sweep_tx_2. txid( ) , latest_spending_tx. txid( ) ) ;
1732+ }
1733+ _ => panic ! ( "Unexpected status" ) ,
1734+ }
1735+
1736+ // Check we still see the transaction as confirmed if we unconfirm any untracked
1737+ // transaction. (We previously had a bug that would mark tracked transactions as
1738+ // unconfirmed if any transaction at an unknown block height would be unconfirmed.)
1739+ let unconf_txid = Txid :: from_slice ( & [ 0 ; 32 ] ) . unwrap ( ) ;
1740+ nodes[ 0 ] . sweeper . transaction_unconfirmed ( & unconf_txid) ;
1741+
1742+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 1 ) ;
1743+ let tracked_output = nodes[ 0 ] . sweeper . tracked_spendable_outputs ( ) . first ( ) . unwrap ( ) . clone ( ) ;
1744+ match tracked_output. status {
1745+ OutputSpendStatus :: PendingThresholdConfirmations { latest_spending_tx, .. } => {
1746+ assert_eq ! ( sweep_tx_2. txid( ) , latest_spending_tx. txid( ) ) ;
1747+ }
1748+ _ => panic ! ( "Unexpected status" ) ,
1749+ }
1750+
1751+ // Check we stop tracking the spendable outputs when one of the txs reaches
1752+ // ANTI_REORG_DELAY confirmations.
1753+ confirm_transaction_depth ( & mut nodes[ 0 ] , & sweep_tx_0, ANTI_REORG_DELAY ) ;
1754+ assert_eq ! ( nodes[ 0 ] . sweeper. tracked_spendable_outputs( ) . len( ) , 0 ) ;
1755+
16241756 if !std:: thread:: panicking ( ) {
16251757 bg_processor. stop ( ) . unwrap ( ) ;
16261758 }
0 commit comments