+fn do_test_restored_packages_retry() {
+ // Tests that we'll retry packages that were previously timelocked after we've restored them.
+ let chanmon_cfgs = create_chanmon_cfgs(2);
+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+ let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+ // Open a channel, lock in an HTLC, and immediately broadcast the commitment transaction. This
+ // ensures that the HTLC timeout package is held until we reach its expiration height.
+ let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 50_000_000);
+ route_payment(&nodes[0], &[&nodes[1]], 10_000_000);
+
+ nodes[0].node.force_close_broadcasting_latest_txn(&chan_id, &nodes[1].node.get_our_node_id()).unwrap();
+ check_added_monitors(&nodes[0], 1);
+ check_closed_broadcast(&nodes[0], 1, true);
+ check_closed_event(&nodes[0], 1, ClosureReason::HolderForceClosed, false);
+
+ let commitment_tx = {
+ let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
+ assert_eq!(txn.len(), 1);
+ assert_eq!(txn[0].output.len(), 3);
+ check_spends!(txn[0], funding_tx);
+ txn.pop().unwrap()
+ };
+
+ mine_transaction(&nodes[0], &commitment_tx);
+
+ // Connect blocks until the HTLC's expiration is met, expecting a transaction broadcast.
+ connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1);
+ let htlc_timeout_tx = {
+ let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
+ assert_eq!(txn.len(), 1);
+ check_spends!(txn[0], commitment_tx);
+ txn.pop().unwrap()
+ };
+
+ // Connecting more blocks should result in the HTLC transactions being rebroadcast.
+ connect_blocks(&nodes[0], 6);
+ {
+ let txn = nodes[0].tx_broadcaster.txn_broadcast();
+ if !nodes[0].connect_style.borrow().skips_blocks() {
+ assert_eq!(txn.len(), 6);
+ } else {
+ assert!(txn.len() < 6);
+ }
+ for tx in txn {
+ assert_eq!(tx.input.len(), htlc_timeout_tx.input.len());
+ assert_eq!(tx.output.len(), htlc_timeout_tx.output.len());
+ assert_eq!(tx.input[0].previous_output, htlc_timeout_tx.input[0].previous_output);
+ assert_eq!(tx.output[0], htlc_timeout_tx.output[0]);
+ }
+ }
+}
+
+#[test]
+fn test_restored_packages_retry() {
+ do_test_restored_packages_retry();
+}
+