Skip to content

Commit a65e6c5

Browse files
committed
Add basic OutputSweeper test in BP
.. we simply check that the `OutputSweeper` generates a spending tx and that the `TrackedSpendableOutput` is pruned once it reaches `ANTI_REORG_DELAY`.
1 parent d24747a commit a65e6c5

File tree

1 file changed

+46
-4
lines changed
  • lightning-background-processor/src

1 file changed

+46
-4
lines changed

lightning-background-processor/src/lib.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -918,14 +918,16 @@ impl Drop for BackgroundProcessor {
918918

919919
#[cfg(all(feature = "std", test))]
920920
mod tests {
921+
use bitcoin::ScriptBuf;
921922
use bitcoin::blockdata::constants::{genesis_block, ChainHash};
922923
use bitcoin::blockdata::locktime::absolute::LockTime;
923924
use bitcoin::blockdata::transaction::{Transaction, TxOut};
924925
use bitcoin::network::constants::Network;
925926
use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1};
926-
use lightning::chain::{BestBlock, Confirm, chainmonitor};
927+
use lightning::chain::{BestBlock, Confirm, chainmonitor, Filter};
927928
use lightning::chain::channelmonitor::ANTI_REORG_DELAY;
928-
use lightning::sign::{InMemorySigner, KeysManager};
929+
use lightning::chain::chaininterface::{ConfirmationTarget, FeeEstimator};
930+
use lightning::sign::{InMemorySigner, KeysManager, SpendableOutputDescriptor};
929931
use lightning::chain::transaction::OutPoint;
930932
use lightning::events::{Event, PathFailure, MessageSendEventsProvider, MessageSendEvent};
931933
use lightning::{get_event_msg, get_event};
@@ -946,6 +948,7 @@ mod tests {
946948
CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE, CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE, CHANNEL_MANAGER_PERSISTENCE_KEY,
947949
NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE, NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE, NETWORK_GRAPH_PERSISTENCE_KEY,
948950
SCORER_PERSISTENCE_PRIMARY_NAMESPACE, SCORER_PERSISTENCE_SECONDARY_NAMESPACE, SCORER_PERSISTENCE_KEY};
951+
use lightning::util::sweep::OutputSweeper;
949952
use lightning_persister::fs_store::FilesystemStore;
950953
use std::collections::VecDeque;
951954
use std::{fs, env};
@@ -1008,6 +1011,7 @@ mod tests {
10081011
logger: Arc<test_utils::TestLogger>,
10091012
best_block: BestBlock,
10101013
scorer: Arc<LockingWrapper<TestScorer>>,
1014+
sweeper: Arc<OutputSweeper<Arc<test_utils::TestBroadcaster>, Arc<KeysManager>, Arc<dyn Filter + Sync + Send>, Arc<FilesystemStore>, Arc<test_utils::TestLogger>>>,
10111015
}
10121016

10131017
impl Node {
@@ -1270,10 +1274,30 @@ mod tests {
12701274
let router = Arc::new(DefaultRouter::new(network_graph.clone(), logger.clone(), Arc::clone(&keys_manager), scorer.clone(), Default::default()));
12711275
let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Bitcoin));
12721276
let kv_store = Arc::new(FilesystemStore::new(format!("{}_persister_{}", &persist_dir, i).into()));
1277+
let now = Duration::from_secs(genesis_block.header.time as u64);
1278+
let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos()));
12731279
let chain_monitor = Arc::new(chainmonitor::ChainMonitor::new(Some(chain_source.clone()), tx_broadcaster.clone(), logger.clone(), fee_estimator.clone(), kv_store.clone()));
12741280
let best_block = BestBlock::from_network(network);
12751281
let params = ChainParameters { network, best_block };
12761282
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));
1283+
1284+
let spend_fee_estimator = Arc::clone(&fee_estimator);
1285+
let spend_keys_manager = Arc::clone(&keys_manager);
1286+
let spend_outputs_callback = move |output_descriptors: &[&SpendableOutputDescriptor]| {
1287+
let fee_rate = spend_fee_estimator
1288+
.get_est_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee);
1289+
spend_keys_manager.spend_spendable_outputs(
1290+
output_descriptors,
1291+
Vec::new(),
1292+
ScriptBuf::new(),
1293+
fee_rate,
1294+
None,
1295+
&Secp256k1::new(),
1296+
)
1297+
};
1298+
let sweeper = Arc::new(OutputSweeper::new(Arc::clone(&tx_broadcaster),
1299+
Arc::clone(&keys_manager), Arc::clone(&kv_store), best_block,
1300+
None::<Arc<dyn Filter + Sync + Send>>, Arc::clone(&logger), None, spend_outputs_callback));
12771301
let p2p_gossip_sync = Arc::new(P2PGossipSync::new(network_graph.clone(), Some(chain_source.clone()), logger.clone()));
12781302
let rapid_gossip_sync = Arc::new(RapidGossipSync::new(network_graph.clone(), logger.clone()));
12791303
let msg_handler = MessageHandler {
@@ -1282,7 +1306,7 @@ mod tests {
12821306
onion_message_handler: IgnoringMessageHandler{}, custom_message_handler: IgnoringMessageHandler{}
12831307
};
12841308
let peer_manager = Arc::new(PeerManager::new(msg_handler, 0, &seed, logger.clone(), keys_manager.clone()));
1285-
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 };
1309+
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 };
12861310
nodes.push(node);
12871311
}
12881312

@@ -1351,15 +1375,18 @@ mod tests {
13511375
1 => {
13521376
node.node.transactions_confirmed(&header, &txdata, height);
13531377
node.chain_monitor.transactions_confirmed(&header, &txdata, height);
1378+
node.sweeper.transactions_confirmed(&header, &txdata, height);
13541379
},
13551380
x if x == depth => {
13561381
node.node.best_block_updated(&header, height);
13571382
node.chain_monitor.best_block_updated(&header, height);
1383+
node.sweeper.best_block_updated(&header, height);
13581384
},
13591385
_ => {},
13601386
}
13611387
}
13621388
}
1389+
13631390
fn confirm_transaction(node: &mut Node, tx: &Transaction) {
13641391
confirm_transaction_depth(node, tx, ANTI_REORG_DELAY);
13651392
}
@@ -1591,6 +1618,9 @@ mod tests {
15911618
let _as_channel_update = get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id());
15921619
nodes[1].node.handle_channel_ready(&nodes[0].node.get_our_node_id(), &as_funding);
15931620
let _bs_channel_update = get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id());
1621+
let broadcast_funding = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().pop().unwrap();
1622+
assert_eq!(broadcast_funding.txid(), funding_tx.txid());
1623+
assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
15941624

15951625
if !std::thread::panicking() {
15961626
bg_processor.stop().unwrap();
@@ -1616,10 +1646,22 @@ mod tests {
16161646
.recv_timeout(Duration::from_secs(EVENT_DEADLINE))
16171647
.expect("Events not handled within deadline");
16181648
match event {
1619-
Event::SpendableOutputs { .. } => {},
1649+
Event::SpendableOutputs { outputs, channel_id } => {
1650+
nodes[0].sweeper.track_spendable_outputs(outputs, channel_id, false);
1651+
},
16201652
_ => panic!("Unexpected event: {:?}", event),
16211653
}
16221654

1655+
assert_eq!(nodes[0].sweeper.tracked_spendable_outputs().len(), 1);
1656+
let tracked_output = nodes[0].sweeper.tracked_spendable_outputs().first().unwrap().clone();
1657+
let sweep_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().pop().unwrap();
1658+
assert_eq!(sweep_tx.txid(), tracked_output.latest_spending_tx.as_ref().unwrap().txid());
1659+
1660+
confirm_transaction_depth(&mut nodes[0], &sweep_tx, 5);
1661+
assert_eq!(nodes[0].sweeper.tracked_spendable_outputs().len(), 1);
1662+
confirm_transaction_depth(&mut nodes[0], &sweep_tx, ANTI_REORG_DELAY);
1663+
assert_eq!(nodes[0].sweeper.tracked_spendable_outputs().len(), 0);
1664+
16231665
if !std::thread::panicking() {
16241666
bg_processor.stop().unwrap();
16251667
}

0 commit comments

Comments
 (0)