Handle retrying sign_counterparty_commitment failures
[rust-lightning] / lightning / src / ln / functional_tests.rs
index b252a352c48df981c2a2d102ba188c9943942143..8ceb9728931972e4d172540b801db379370404eb 100644 (file)
@@ -15,7 +15,7 @@ use crate::chain;
 use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
 use crate::chain::chaininterface::LowerBoundedFeeEstimator;
 use crate::chain::channelmonitor;
-use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
+use crate::chain::channelmonitor::{CLOSED_CHANNEL_UPDATE_ID, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
 use crate::chain::transaction::OutPoint;
 use crate::sign::{EcdsaChannelSigner, EntropySource, SignerProvider};
 use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination, PaymentFailureReason};
@@ -40,7 +40,7 @@ use crate::util::config::{UserConfig, MaxDustHTLCExposure};
 use bitcoin::hash_types::BlockHash;
 use bitcoin::blockdata::script::{Builder, Script};
 use bitcoin::blockdata::opcodes;
-use bitcoin::blockdata::constants::genesis_block;
+use bitcoin::blockdata::constants::ChainHash;
 use bitcoin::network::constants::Network;
 use bitcoin::{PackedLockTime, Sequence, Transaction, TxIn, TxOut, Witness};
 use bitcoin::OutPoint as BitcoinOutPoint;
@@ -1338,9 +1338,9 @@ fn test_duplicate_htlc_different_direction_onchain() {
        for e in events {
                match e {
                        MessageSendEvent::BroadcastChannelUpdate { .. } => {},
-                       MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::SendErrorMessage { ref msg } } => {
+                       MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::DisconnectPeer { ref msg } } => {
                                assert_eq!(node_id, nodes[1].node.get_our_node_id());
-                               assert_eq!(msg.data, "Channel closed because commitment or closing transaction was confirmed on chain.");
+                               assert_eq!(msg.as_ref().unwrap().data, "Channel closed because commitment or closing transaction was confirmed on chain.");
                        },
                        MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, .. } } => {
                                assert!(update_add_htlcs.is_empty());
@@ -1865,7 +1865,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
        // attempt to send amt_msat > their_max_htlc_value_in_flight_msat
        {
                let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)
-                       .with_bolt11_features(nodes[2].node.invoice_features()).unwrap().with_max_channel_saturation_power_of_half(0);
+                       .with_bolt11_features(nodes[2].node.bolt11_invoice_features()).unwrap().with_max_channel_saturation_power_of_half(0);
                let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, recv_value_0);
                route.paths[0].hops.last_mut().unwrap().fee_msat += 1;
                assert!(route.paths[0].hops.iter().rev().skip(1).all(|h| h.fee_msat == feemsat));
@@ -1890,7 +1890,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
                }
 
                let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)
-                       .with_bolt11_features(nodes[2].node.invoice_features()).unwrap().with_max_channel_saturation_power_of_half(0);
+                       .with_bolt11_features(nodes[2].node.bolt11_invoice_features()).unwrap().with_max_channel_saturation_power_of_half(0);
                let route = get_route!(nodes[0], payment_params, recv_value_0).unwrap();
                let (payment_preimage, ..) = send_along_route(&nodes[0], route, &[&nodes[1], &nodes[2]], recv_value_0);
                claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
@@ -2369,7 +2369,7 @@ fn channel_monitor_network_test() {
                        _ => panic!("Unexpected event"),
                };
                match events[1] {
-                       MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { .. }, node_id } => {
+                       MessageSendEvent::HandleError { action: ErrorAction::DisconnectPeer { .. }, node_id } => {
                                assert_eq!(node_id, nodes[4].node.get_our_node_id());
                        },
                        _ => panic!("Unexpected event"),
@@ -2401,13 +2401,14 @@ fn channel_monitor_network_test() {
                        _ => panic!("Unexpected event"),
                };
                match events[1] {
-                       MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { .. }, node_id } => {
+                       MessageSendEvent::HandleError { action: ErrorAction::DisconnectPeer { .. }, node_id } => {
                                assert_eq!(node_id, nodes[3].node.get_our_node_id());
                        },
                        _ => panic!("Unexpected event"),
                }
                check_added_monitors!(nodes[4], 1);
                test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS);
+               check_closed_event!(nodes[4], 1, ClosureReason::HolderForceClosed, [nodes[3].node.get_our_node_id()], 100000);
 
                mine_transaction(&nodes[4], &node_txn[0]);
                check_preimage_claim(&nodes[4], &node_txn);
@@ -2419,9 +2420,8 @@ fn channel_monitor_network_test() {
        assert_eq!(nodes[4].node.list_channels().len(), 0);
 
        assert_eq!(nodes[3].chain_monitor.chain_monitor.watch_channel(OutPoint { txid: chan_3.3.txid(), index: 0 }, chan_3_mon),
-               ChannelMonitorUpdateStatus::Completed);
-       check_closed_event!(nodes[3], 1, ClosureReason::CommitmentTxConfirmed, [nodes[4].node.get_our_node_id()], 100000);
-       check_closed_event!(nodes[4], 1, ClosureReason::CommitmentTxConfirmed, [nodes[3].node.get_our_node_id()], 100000);
+               Ok(ChannelMonitorUpdateStatus::Completed));
+       check_closed_event!(nodes[3], 1, ClosureReason::HolderForceClosed, [nodes[4].node.get_our_node_id()], 100000);
 }
 
 #[test]
@@ -2913,7 +2913,7 @@ fn test_htlc_on_chain_success() {
        let nodes_0_event = remove_first_msg_event_to_node(&nodes[0].node.get_our_node_id(), &mut events);
 
        match nodes_2_event {
-               MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { .. }, node_id: _ } => {},
+               MessageSendEvent::HandleError { action: ErrorAction::DisconnectPeer { .. }, node_id: _ } => {},
                _ => panic!("Unexpected event"),
        }
 
@@ -3358,7 +3358,7 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use
 
        let nodes_2_event = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut events);
        match nodes_2_event {
-               MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { msg: msgs::ErrorMessage { channel_id, ref data } }, node_id: _ } => {
+               MessageSendEvent::HandleError { action: ErrorAction::DisconnectPeer { msg: Some(msgs::ErrorMessage { channel_id, ref data }) }, node_id: _ } => {
                        assert_eq!(channel_id, chan_2.2);
                        assert_eq!(data.as_str(), "Channel closed because commitment or closing transaction was confirmed on chain.");
                },
@@ -3721,7 +3721,7 @@ fn test_peer_disconnected_before_funding_broadcasted() {
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
 
-       check_closed_event!(&nodes[0], 1, ClosureReason::DisconnectedPeer, false
+       check_closed_event!(&nodes[0], 2, ClosureReason::DisconnectedPeer, true
                , [nodes[1].node.get_our_node_id()], 1000000);
        check_closed_event!(&nodes[1], 1, ClosureReason::DisconnectedPeer, false
                , [nodes[0].node.get_our_node_id()], 1000000);
@@ -4920,7 +4920,7 @@ fn test_onchain_to_onchain_claim() {
        let nodes_0_event = remove_first_msg_event_to_node(&nodes[0].node.get_our_node_id(), &mut msg_events);
 
        match nodes_2_event {
-               MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { .. }, node_id: _ } => {},
+               MessageSendEvent::HandleError { action: ErrorAction::DisconnectPeer { .. }, node_id: _ } => {},
                _ => panic!("Unexpected event"),
        }
 
@@ -4990,7 +4990,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
        // script push size limit so that the below script length checks match
        // ACCEPTED_HTLC_SCRIPT_WEIGHT.
        let payment_params = PaymentParameters::from_node_id(nodes[3].node.get_our_node_id(), TEST_FINAL_CLTV - 40)
-               .with_bolt11_features(nodes[3].node.invoice_features()).unwrap();
+               .with_bolt11_features(nodes[3].node.bolt11_invoice_features()).unwrap();
        let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[3], payment_params, 800_000);
        send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2], &nodes[3]]], 800_000, duplicate_payment_hash, payment_secret);
 
@@ -5660,7 +5660,7 @@ fn do_htlc_claim_local_commitment_only(use_dust: bool) {
        test_txn_broadcast(&nodes[1], &chan, None, if use_dust { HTLCType::NONE } else { HTLCType::SUCCESS });
        check_closed_broadcast!(nodes[1], true);
        check_added_monitors!(nodes[1], 1);
-       check_closed_event!(nodes[1], 1, ClosureReason::CommitmentTxConfirmed, [nodes[0].node.get_our_node_id()], 100000);
+       check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed, [nodes[0].node.get_our_node_id()], 100000);
 }
 
 fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) {
@@ -5691,7 +5691,7 @@ fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) {
        test_txn_broadcast(&nodes[0], &chan, None, HTLCType::NONE);
        check_closed_broadcast!(nodes[0], true);
        check_added_monitors!(nodes[0], 1);
-       check_closed_event!(nodes[0], 1, ClosureReason::CommitmentTxConfirmed, [nodes[1].node.get_our_node_id()], 100000);
+       check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed, [nodes[1].node.get_our_node_id()], 100000);
 }
 
 fn do_htlc_claim_previous_remote_commitment_only(use_dust: bool, check_revoke_no_close: bool) {
@@ -5737,7 +5737,7 @@ fn do_htlc_claim_previous_remote_commitment_only(use_dust: bool, check_revoke_no
                test_txn_broadcast(&nodes[0], &chan, None, HTLCType::NONE);
                check_closed_broadcast!(nodes[0], true);
                check_added_monitors!(nodes[0], 1);
-               check_closed_event!(nodes[0], 1, ClosureReason::CommitmentTxConfirmed, [nodes[1].node.get_our_node_id()], 100000);
+               check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed, [nodes[1].node.get_our_node_id()], 100000);
        } else {
                expect_payment_failed!(nodes[0], our_payment_hash, true);
        }
@@ -5830,8 +5830,8 @@ fn bolt2_open_channel_sending_node_checks_part2() {
        assert!(node0_to_1_send_open_channel.to_self_delay==BREAKDOWN_TIMEOUT);
 
        // BOLT #2 spec: Sending node must ensure the chain_hash value identifies the chain it wishes to open the channel within.
-       let chain_hash=genesis_block(Network::Testnet).header.block_hash();
-       assert_eq!(node0_to_1_send_open_channel.chain_hash,chain_hash);
+       let chain_hash = ChainHash::using_genesis_block(Network::Testnet);
+       assert_eq!(node0_to_1_send_open_channel.chain_hash, chain_hash);
 
        // BOLT #2 spec: Sending node must set funding_pubkey, revocation_basepoint, htlc_basepoint, payment_basepoint, and delayed_payment_basepoint to valid DER-encoded, compressed, secp256k1 pubkeys.
        assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.funding_pubkey.serialize()).is_ok());
@@ -6281,7 +6281,7 @@ fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() {
        let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0);
 
        let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), 0)
-               .with_bolt11_features(nodes[1].node.invoice_features()).unwrap();
+               .with_bolt11_features(nodes[1].node.bolt11_invoice_features()).unwrap();
        let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], payment_params, 100000000);
        route.paths[0].hops.last_mut().unwrap().cltv_expiry_delta = 500000001;
        unwrap_send_err!(nodes[0].node.send_payment_with_route(&route, our_payment_hash,
@@ -7227,11 +7227,11 @@ fn test_check_htlc_underpaying() {
 
        let scorer = test_utils::TestScorer::new();
        let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
-       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(),
-               TEST_FINAL_CLTV).with_bolt11_features(nodes[1].node.invoice_features()).unwrap();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
+               .with_bolt11_features(nodes[1].node.bolt11_invoice_features()).unwrap();
        let route_params = RouteParameters::from_payment_params_and_value(payment_params, 10_000);
        let route = get_route(&nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(),
-               None, nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap();
+               None, nodes[0].logger, &scorer, &Default::default(), &random_seed_bytes).unwrap();
        let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]);
        let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200, None).unwrap();
        nodes[0].node.send_payment_with_route(&route, our_payment_hash,
@@ -7380,7 +7380,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() {
 
        let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
        let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), 30)
-               .with_bolt11_features(nodes[0].node.invoice_features()).unwrap();
+               .with_bolt11_features(nodes[0].node.bolt11_invoice_features()).unwrap();
        let (route,_, _, _) = get_route_and_payment_hash!(nodes[1], nodes[0], payment_params, 3000000);
        send_along_route(&nodes[1], route, &vec!(&nodes[0])[..], 3000000);
 
@@ -7484,17 +7484,18 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
 
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000);
        // Lock HTLC in both directions (using a slightly lower CLTV delay to provide timely RBF bumps)
-       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), 50).with_bolt11_features(nodes[1].node.invoice_features()).unwrap();
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), 50).with_bolt11_features(nodes[1].node.bolt11_invoice_features()).unwrap();
        let scorer = test_utils::TestScorer::new();
        let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
        let route_params = RouteParameters::from_payment_params_and_value(payment_params, 3_000_000);
        let route = get_route(&nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(), None,
-               nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap();
+               nodes[0].logger, &scorer, &Default::default(), &random_seed_bytes).unwrap();
        let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 3_000_000).0;
-       let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), 50).with_bolt11_features(nodes[0].node.invoice_features()).unwrap();
+       let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), 50)
+               .with_bolt11_features(nodes[0].node.bolt11_invoice_features()).unwrap();
        let route_params = RouteParameters::from_payment_params_and_value(payment_params, 3_000_000);
        let route = get_route(&nodes[1].node.get_our_node_id(), &route_params, &nodes[1].network_graph.read_only(), None,
-               nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap();
+               nodes[0].logger, &scorer, &Default::default(), &random_seed_bytes).unwrap();
        send_along_route(&nodes[1], route, &[&nodes[0]], 3_000_000);
 
        let revoked_local_txn = get_local_commitment_txn!(nodes[1], chan.2);
@@ -7860,9 +7861,9 @@ fn test_channel_conf_timeout() {
        let close_ev = nodes[1].node.get_and_clear_pending_msg_events();
        assert_eq!(close_ev.len(), 1);
        match close_ev[0] {
-               MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, ref node_id } => {
+               MessageSendEvent::HandleError { action: ErrorAction::DisconnectPeer { ref msg }, ref node_id } => {
                        assert_eq!(*node_id, nodes[0].node.get_our_node_id());
-                       assert_eq!(msg.data, "Channel closed because funding transaction failed to confirm within 2016 blocks");
+                       assert_eq!(msg.as_ref().unwrap().data, "Channel closed because funding transaction failed to confirm within 2016 blocks");
                },
                _ => panic!("Unexpected event"),
        }
@@ -8453,7 +8454,7 @@ fn test_update_err_monitor_lockdown() {
                        new_monitor
                };
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
-               assert_eq!(watchtower.watch_channel(outpoint, new_monitor), ChannelMonitorUpdateStatus::Completed);
+               assert_eq!(watchtower.watch_channel(outpoint, new_monitor), Ok(ChannelMonitorUpdateStatus::Completed));
                watchtower
        };
        let block = create_dummy_block(BlockHash::all_zeros(), 42, Vec::new());
@@ -8475,7 +8476,7 @@ fn test_update_err_monitor_lockdown() {
                let mut node_0_peer_state_lock;
                if let ChannelPhase::Funded(ref mut channel) = get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan_1.2) {
                        if let Ok(Some(update)) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
-                               assert_eq!(watchtower.chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::PermanentFailure);
+                               assert_eq!(watchtower.chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::InProgress);
                                assert_eq!(nodes[0].chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::Completed);
                        } else { assert!(false); }
                } else {
@@ -8526,7 +8527,7 @@ fn test_concurrent_monitor_claim() {
                        new_monitor
                };
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &alice_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
-               assert_eq!(watchtower.watch_channel(outpoint, new_monitor), ChannelMonitorUpdateStatus::Completed);
+               assert_eq!(watchtower.watch_channel(outpoint, new_monitor), Ok(ChannelMonitorUpdateStatus::Completed));
                watchtower
        };
        let block = create_dummy_block(BlockHash::all_zeros(), 42, Vec::new());
@@ -8557,7 +8558,7 @@ fn test_concurrent_monitor_claim() {
                        new_monitor
                };
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &bob_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
-               assert_eq!(watchtower.watch_channel(outpoint, new_monitor), ChannelMonitorUpdateStatus::Completed);
+               assert_eq!(watchtower.watch_channel(outpoint, new_monitor), Ok(ChannelMonitorUpdateStatus::Completed));
                watchtower
        };
        watchtower_bob.chain_monitor.block_connected(&create_dummy_block(BlockHash::all_zeros(), 42, Vec::new()), HTLC_TIMEOUT_BROADCAST - 1);
@@ -8577,7 +8578,7 @@ fn test_concurrent_monitor_claim() {
                if let ChannelPhase::Funded(ref mut channel) = get_channel_ref!(nodes[0], nodes[1], node_0_per_peer_lock, node_0_peer_state_lock, chan_1.2) {
                        if let Ok(Some(update)) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].logger) {
                                // Watchtower Alice should already have seen the block and reject the update
-                               assert_eq!(watchtower_alice.chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::PermanentFailure);
+                               assert_eq!(watchtower_alice.chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::InProgress);
                                assert_eq!(watchtower_bob.chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::Completed);
                                assert_eq!(nodes[0].chain_monitor.update_channel(outpoint, &update), ChannelMonitorUpdateStatus::Completed);
                        } else { assert!(false); }
@@ -8603,7 +8604,7 @@ fn test_concurrent_monitor_claim() {
        let height = HTLC_TIMEOUT_BROADCAST + 1;
        connect_blocks(&nodes[0], height - nodes[0].best_block_info().1);
        check_closed_broadcast(&nodes[0], 1, true);
-       check_closed_event!(&nodes[0], 1, ClosureReason::CommitmentTxConfirmed, false,
+       check_closed_event!(&nodes[0], 1, ClosureReason::HolderForceClosed, false,
                [nodes[1].node.get_our_node_id()], 100000);
        watchtower_alice.chain_monitor.block_connected(&create_dummy_block(BlockHash::all_zeros(), 42, vec![bob_state_y.clone()]), height);
        check_added_monitors(&nodes[0], 1);
@@ -8653,7 +8654,7 @@ fn test_pre_lockin_no_chan_closed_update() {
        nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage { channel_id, data: "Hi".to_owned() });
        assert!(nodes[0].chain_monitor.added_monitors.lock().unwrap().is_empty());
        check_closed_event!(nodes[0], 2, ClosureReason::CounterpartyForceClosed { peer_msg: UntrustedString("Hi".to_string()) }, true,
-               [nodes[1].node.get_our_node_id(); 2], 100000);
+               [nodes[1].node.get_our_node_id()], 100000);
 }
 
 #[test]
@@ -9038,13 +9039,13 @@ fn test_duplicate_chan_id() {
                match a_peer_state.channel_by_id.remove(&open_chan_2_msg.temporary_channel_id).unwrap() {
                        ChannelPhase::UnfundedOutboundV1(chan) => {
                                let logger = test_utils::TestLogger::new();
-                               chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap()
+                               chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap()
                        },
                        _ => panic!("Unexpected ChannelPhase variant"),
                }
        };
        check_added_monitors!(nodes[0], 0);
-       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created.unwrap());
        // At this point we'll look up if the channel_id is present and immediately fail the channel
        // without trying to persist the `ChannelMonitor`.
        check_added_monitors!(nodes[1], 0);
@@ -9212,8 +9213,8 @@ fn test_invalid_funding_tx() {
        assert_eq!(events_2.len(), 1);
        if let MessageSendEvent::HandleError { node_id, action } = &events_2[0] {
                assert_eq!(*node_id, nodes[0].node.get_our_node_id());
-               if let msgs::ErrorAction::SendErrorMessage { msg } = action {
-                       assert_eq!(msg.data, "Channel closed because of an exception: ".to_owned() + expected_err);
+               if let msgs::ErrorAction::DisconnectPeer { msg } = action {
+                       assert_eq!(msg.as_ref().unwrap().data, "Channel closed because of an exception: ".to_owned() + expected_err);
                } else { panic!(); }
        } else { panic!(); }
        assert_eq!(nodes[1].node.list_channels().len(), 0);
@@ -9394,7 +9395,7 @@ fn do_test_dup_htlc_second_rejected(test_for_second_fail_panic: bool) {
        let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
 
        let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)
-               .with_bolt11_features(nodes[1].node.invoice_features()).unwrap();
+               .with_bolt11_features(nodes[1].node.bolt11_invoice_features()).unwrap();
        let route = get_route!(nodes[0], payment_params, 10_000).unwrap();
 
        let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(&nodes[1]);
@@ -9503,7 +9504,7 @@ fn test_inconsistent_mpp_params() {
        let chan_2_3 =create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 100_000, 0);
 
        let payment_params = PaymentParameters::from_node_id(nodes[3].node.get_our_node_id(), TEST_FINAL_CLTV)
-               .with_bolt11_features(nodes[3].node.invoice_features()).unwrap();
+               .with_bolt11_features(nodes[3].node.bolt11_invoice_features()).unwrap();
        let mut route = get_route!(nodes[0], payment_params, 15_000_000).unwrap();
        assert_eq!(route.paths.len(), 2);
        route.paths.sort_by(|path_a, _| {
@@ -9900,9 +9901,46 @@ fn test_non_final_funding_tx() {
                },
                _ => panic!()
        }
+       let events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 1);
+       match events[0] {
+               Event::ChannelClosed { channel_id, .. } => {
+                       assert_eq!(channel_id, temp_channel_id);
+               },
+               _ => panic!("Unexpected event"),
+       }
+}
+
+#[test]
+fn test_non_final_funding_tx_within_headroom() {
+       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 nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       let temp_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
+       let open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_message);
+       let accept_channel_message = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel_message);
+
+       let best_height = nodes[0].node.best_block.read().unwrap().height();
+
+       let chan_id = *nodes[0].network_chan_count.borrow();
+       let events = nodes[0].node.get_and_clear_pending_events();
+       let input = TxIn { previous_output: BitcoinOutPoint::null(), script_sig: bitcoin::Script::new(), sequence: Sequence(1), witness: Witness::from_vec(vec!(vec!(1))) };
+       assert_eq!(events.len(), 1);
+       let mut tx = match events[0] {
+               Event::FundingGenerationReady { ref channel_value_satoshis, ref output_script, .. } => {
+                       // Timelock the transaction within a +1 headroom from the best block.
+                       Transaction { version: chan_id as i32, lock_time: PackedLockTime(best_height + 1), input: vec![input], output: vec![TxOut {
+                               value: *channel_value_satoshis, script_pubkey: output_script.clone(),
+                       }]}
+               },
+               _ => panic!("Unexpected event"),
+       };
 
-       // However, transaction should be accepted if it's in a +1 headroom from best block.
-       tx.lock_time = PackedLockTime(tx.lock_time.0 - 1);
+       // Transaction should be accepted if it's in a +1 headroom from best block.
        assert!(nodes[0].node.funding_transaction_generated(&temp_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).is_ok());
        get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
 }
@@ -9977,7 +10015,7 @@ fn accept_busted_but_better_fee() {
                MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, .. }, .. } => {
                        nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_fee.as_ref().unwrap());
                        check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError {
-                               err: "Peer's feerate much too low. Actual: 1000. Our expected lower limit: 5000 (- 250)".to_owned() },
+                               err: "Peer's feerate much too low. Actual: 1000. Our expected lower limit: 5000".to_owned() },
                                [nodes[0].node.get_our_node_id()], 100000);
                        check_closed_broadcast!(nodes[1], true);
                        check_added_monitors!(nodes[1], 1);
@@ -10361,3 +10399,271 @@ fn test_multi_post_event_actions() {
        do_test_multi_post_event_actions(true);
        do_test_multi_post_event_actions(false);
 }
+
+#[test]
+fn test_batch_channel_open() {
+       let chanmon_cfgs = create_chanmon_cfgs(3);
+       let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
+       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       // Initiate channel opening and create the batch channel funding transaction.
+       let (tx, funding_created_msgs) = create_batch_channel_funding(&nodes[0], &[
+               (&nodes[1], 100_000, 0, 42, None),
+               (&nodes[2], 200_000, 0, 43, None),
+       ]);
+
+       // Go through the funding_created and funding_signed flow with node 1.
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msgs[0]);
+       check_added_monitors(&nodes[1], 1);
+       expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
+
+       let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+       nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed_msg);
+       check_added_monitors(&nodes[0], 1);
+
+       // The transaction should not have been broadcast before all channels are ready.
+       assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
+
+       // Go through the funding_created and funding_signed flow with node 2.
+       nodes[2].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msgs[1]);
+       check_added_monitors(&nodes[2], 1);
+       expect_channel_pending_event(&nodes[2], &nodes[0].node.get_our_node_id());
+
+       let funding_signed_msg = get_event_msg!(nodes[2], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
+       nodes[0].node.handle_funding_signed(&nodes[2].node.get_our_node_id(), &funding_signed_msg);
+       check_added_monitors(&nodes[0], 1);
+
+       // The transaction should not have been broadcast before persisting all monitors has been
+       // completed.
+       assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
+       assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
+
+       // Complete the persistence of the monitor.
+       nodes[0].chain_monitor.complete_sole_pending_chan_update(
+               &OutPoint { txid: tx.txid(), index: 1 }.to_channel_id()
+       );
+       let events = nodes[0].node.get_and_clear_pending_events();
+
+       // The transaction should only have been broadcast now.
+       let broadcasted_txs = nodes[0].tx_broadcaster.txn_broadcast();
+       assert_eq!(broadcasted_txs.len(), 1);
+       assert_eq!(broadcasted_txs[0], tx);
+
+       assert_eq!(events.len(), 2);
+       assert!(events.iter().any(|e| matches!(
+               *e,
+               crate::events::Event::ChannelPending {
+                       ref counterparty_node_id,
+                       ..
+               } if counterparty_node_id == &nodes[1].node.get_our_node_id(),
+       )));
+       assert!(events.iter().any(|e| matches!(
+               *e,
+               crate::events::Event::ChannelPending {
+                       ref counterparty_node_id,
+                       ..
+               } if counterparty_node_id == &nodes[2].node.get_our_node_id(),
+       )));
+}
+
+#[test]
+fn test_disconnect_in_funding_batch() {
+       let chanmon_cfgs = create_chanmon_cfgs(3);
+       let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
+       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       // Initiate channel opening and create the batch channel funding transaction.
+       let (tx, funding_created_msgs) = create_batch_channel_funding(&nodes[0], &[
+               (&nodes[1], 100_000, 0, 42, None),
+               (&nodes[2], 200_000, 0, 43, None),
+       ]);
+
+       // Go through the funding_created and funding_signed flow with node 1.
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msgs[0]);
+       check_added_monitors(&nodes[1], 1);
+       expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
+
+       let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+       nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed_msg);
+       check_added_monitors(&nodes[0], 1);
+
+       // The transaction should not have been broadcast before all channels are ready.
+       assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
+
+       // The remaining peer in the batch disconnects.
+       nodes[0].node.peer_disconnected(&nodes[2].node.get_our_node_id());
+
+       // The channels in the batch will close immediately.
+       let channel_id_1 = OutPoint { txid: tx.txid(), index: 0 }.to_channel_id();
+       let channel_id_2 = OutPoint { txid: tx.txid(), index: 1 }.to_channel_id();
+       check_closed_events(&nodes[0], &[
+               ExpectedCloseEvent {
+                       channel_id: Some(channel_id_1),
+                       discard_funding: true,
+                       ..Default::default()
+               },
+               ExpectedCloseEvent {
+                       channel_id: Some(channel_id_2),
+                       discard_funding: true,
+                       ..Default::default()
+               },
+       ]);
+
+       // The monitor should become closed.
+       check_added_monitors(&nodes[0], 1);
+       {
+               let mut monitor_updates = nodes[0].chain_monitor.monitor_updates.lock().unwrap();
+               let monitor_updates_1 = monitor_updates.get(&channel_id_1).unwrap();
+               assert_eq!(monitor_updates_1.len(), 1);
+               assert_eq!(monitor_updates_1[0].update_id, CLOSED_CHANNEL_UPDATE_ID);
+       }
+
+       // The funding transaction should not have been broadcast, and therefore, we don't need
+       // to broadcast a force-close transaction for the closed monitor.
+       assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
+
+       // Ensure the channels don't exist anymore.
+       assert!(nodes[0].node.list_channels().is_empty());
+}
+
+#[test]
+fn test_batch_funding_close_after_funding_signed() {
+       let chanmon_cfgs = create_chanmon_cfgs(3);
+       let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
+       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+
+       // Initiate channel opening and create the batch channel funding transaction.
+       let (tx, funding_created_msgs) = create_batch_channel_funding(&nodes[0], &[
+               (&nodes[1], 100_000, 0, 42, None),
+               (&nodes[2], 200_000, 0, 43, None),
+       ]);
+
+       // Go through the funding_created and funding_signed flow with node 1.
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msgs[0]);
+       check_added_monitors(&nodes[1], 1);
+       expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
+
+       let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+       nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed_msg);
+       check_added_monitors(&nodes[0], 1);
+
+       // Go through the funding_created and funding_signed flow with node 2.
+       nodes[2].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msgs[1]);
+       check_added_monitors(&nodes[2], 1);
+       expect_channel_pending_event(&nodes[2], &nodes[0].node.get_our_node_id());
+
+       let funding_signed_msg = get_event_msg!(nodes[2], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
+       nodes[0].node.handle_funding_signed(&nodes[2].node.get_our_node_id(), &funding_signed_msg);
+       check_added_monitors(&nodes[0], 1);
+
+       // The transaction should not have been broadcast before all channels are ready.
+       assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
+
+       // Force-close the channel for which we've completed the initial monitor.
+       let channel_id_1 = OutPoint { txid: tx.txid(), index: 0 }.to_channel_id();
+       let channel_id_2 = OutPoint { txid: tx.txid(), index: 1 }.to_channel_id();
+       nodes[0].node.force_close_broadcasting_latest_txn(&channel_id_1, &nodes[1].node.get_our_node_id()).unwrap();
+       check_added_monitors(&nodes[0], 2);
+       {
+               let mut monitor_updates = nodes[0].chain_monitor.monitor_updates.lock().unwrap();
+               let monitor_updates_1 = monitor_updates.get(&channel_id_1).unwrap();
+               assert_eq!(monitor_updates_1.len(), 1);
+               assert_eq!(monitor_updates_1[0].update_id, CLOSED_CHANNEL_UPDATE_ID);
+               let monitor_updates_2 = monitor_updates.get(&channel_id_2).unwrap();
+               assert_eq!(monitor_updates_2.len(), 1);
+               assert_eq!(monitor_updates_2[0].update_id, CLOSED_CHANNEL_UPDATE_ID);
+       }
+       let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+       match msg_events[0] {
+               MessageSendEvent::HandleError { .. } => (),
+               _ => panic!("Unexpected message."),
+       }
+
+       // We broadcast the commitment transaction as part of the force-close.
+       {
+               let broadcasted_txs = nodes[0].tx_broadcaster.txn_broadcast();
+               assert_eq!(broadcasted_txs.len(), 1);
+               assert!(broadcasted_txs[0].txid() != tx.txid());
+               assert_eq!(broadcasted_txs[0].input.len(), 1);
+               assert_eq!(broadcasted_txs[0].input[0].previous_output.txid, tx.txid());
+       }
+
+       // All channels in the batch should close immediately.
+       check_closed_events(&nodes[0], &[
+               ExpectedCloseEvent {
+                       channel_id: Some(channel_id_1),
+                       discard_funding: true,
+                       ..Default::default()
+               },
+               ExpectedCloseEvent {
+                       channel_id: Some(channel_id_2),
+                       discard_funding: true,
+                       ..Default::default()
+               },
+       ]);
+
+       // Ensure the channels don't exist anymore.
+       assert!(nodes[0].node.list_channels().is_empty());
+}
+
+fn do_test_funding_and_commitment_tx_confirm_same_block(confirm_remote_commitment: bool) {
+       // Tests that a node will forget the channel (when it only requires 1 confirmation) if the
+       // funding and commitment transaction confirm in the same block.
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let mut min_depth_1_block_cfg = test_default_channel_config();
+       min_depth_1_block_cfg.channel_handshake_config.minimum_depth = 1;
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(min_depth_1_block_cfg), Some(min_depth_1_block_cfg)]);
+       let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       let funding_tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 1_000_000, 0);
+       let chan_id = chain::transaction::OutPoint { txid: funding_tx.txid(), index: 0 }.to_channel_id();
+
+       assert_eq!(nodes[0].node.list_channels().len(), 1);
+       assert_eq!(nodes[1].node.list_channels().len(), 1);
+
+       let (closing_node, other_node) = if confirm_remote_commitment {
+               (&nodes[1], &nodes[0])
+       } else {
+               (&nodes[0], &nodes[1])
+       };
+
+       closing_node.node.force_close_broadcasting_latest_txn(&chan_id, &other_node.node.get_our_node_id()).unwrap();
+       let mut msg_events = closing_node.node.get_and_clear_pending_msg_events();
+       assert_eq!(msg_events.len(), 1);
+       match msg_events.pop().unwrap() {
+               MessageSendEvent::HandleError { action: msgs::ErrorAction::DisconnectPeer { .. }, .. } => {},
+               _ => panic!("Unexpected event"),
+       }
+       check_added_monitors(closing_node, 1);
+       check_closed_event(closing_node, 1, ClosureReason::HolderForceClosed, false, &[other_node.node.get_our_node_id()], 1_000_000);
+
+       let commitment_tx = {
+               let mut txn = closing_node.tx_broadcaster.txn_broadcast();
+               assert_eq!(txn.len(), 1);
+               let commitment_tx = txn.pop().unwrap();
+               check_spends!(commitment_tx, funding_tx);
+               commitment_tx
+       };
+
+       mine_transactions(&nodes[0], &[&funding_tx, &commitment_tx]);
+       mine_transactions(&nodes[1], &[&funding_tx, &commitment_tx]);
+
+       check_closed_broadcast(other_node, 1, true);
+       check_added_monitors(other_node, 1);
+       check_closed_event(other_node, 1, ClosureReason::CommitmentTxConfirmed, false, &[closing_node.node.get_our_node_id()], 1_000_000);
+
+       assert!(nodes[0].node.list_channels().is_empty());
+       assert!(nodes[1].node.list_channels().is_empty());
+}
+
+#[test]
+fn test_funding_and_commitment_tx_confirm_same_block() {
+       do_test_funding_and_commitment_tx_confirm_same_block(false);
+       do_test_funding_and_commitment_tx_confirm_same_block(true);
+}