Merge pull request #554 from TheBlueMatt/2020-03-stale-mon-fail-man-deser
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Fri, 20 Mar 2020 23:58:51 +0000 (23:58 +0000)
committerGitHub <noreply@github.com>
Fri, 20 Mar 2020 23:58:51 +0000 (23:58 +0000)
Fail to deserialize ChannelManager if it is ahead of any monitor(s)

1  2 
lightning/src/ln/functional_tests.rs

index 9669c7852ccdf91b755585b028d985c580a6e9b2,7cd546dbe8e26223eb14aad51f0a6372c7df0fa3..8ea9dcf753c07159bb376d0ace428e88754e59b4
@@@ -3839,6 -3839,13 +3839,13 @@@ fn test_manager_serialize_deserialize_i
        create_announced_chan_between_nodes(&nodes, 2, 0, InitFeatures::supported(), InitFeatures::supported());
        let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3, InitFeatures::supported(), InitFeatures::supported());
  
+       let mut node_0_stale_monitors_serialized = Vec::new();
+       for monitor in nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter() {
+               let mut writer = test_utils::TestVecWriter(Vec::new());
+               monitor.1.write_for_disk(&mut writer).unwrap();
+               node_0_stale_monitors_serialized.push(writer.0);
+       }
        let (our_payment_preimage, _) = route_payment(&nodes[2], &[&nodes[0], &nodes[1]], 1000000);
  
        // Serialize the ChannelManager here, but the monitor we keep up-to-date
        fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
        new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new()), &fee_estimator);
        nodes[0].chan_monitor = &new_chan_monitor;
+       let mut node_0_stale_monitors = Vec::new();
+       for serialized in node_0_stale_monitors_serialized.iter() {
+               let mut read = &serialized[..];
+               let (_, monitor) = <(Sha256dHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut read, Arc::new(test_utils::TestLogger::new())).unwrap();
+               assert!(read.is_empty());
+               node_0_stale_monitors.push(monitor);
+       }
        let mut node_0_monitors = Vec::new();
        for serialized in node_0_monitors_serialized.iter() {
                let mut read = &serialized[..];
                node_0_monitors.push(monitor);
        }
  
-       let mut nodes_0_read = &nodes_0_serialized[..];
        keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new()));
-       let (_, nodes_0_deserialized_tmp) = <(Sha256dHash, ChannelManager<EnforcingChannelKeys, &test_utils::TestChannelMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+       let mut nodes_0_read = &nodes_0_serialized[..];
+       if let Err(msgs::DecodeError::InvalidValue) =
+               <(Sha256dHash, ChannelManager<EnforcingChannelKeys, &test_utils::TestChannelMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+               default_config: UserConfig::default(),
+               keys_manager: &keys_manager,
+               fee_estimator: &fee_estimator,
+               monitor: nodes[0].chan_monitor,
+               tx_broadcaster: nodes[0].tx_broadcaster.clone(),
+               logger: Arc::new(test_utils::TestLogger::new()),
+               channel_monitors: &mut node_0_stale_monitors.iter_mut().map(|monitor| { (monitor.get_funding_txo().unwrap(), monitor) }).collect(),
+       }) { } else {
+               panic!("If the monitor(s) are stale, this indicates a bug and we should get an Err return");
+       };
+       let mut nodes_0_read = &nodes_0_serialized[..];
+       let (_, nodes_0_deserialized_tmp) =
+               <(Sha256dHash, ChannelManager<EnforcingChannelKeys, &test_utils::TestChannelMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                default_config: UserConfig::default(),
                keys_manager: &keys_manager,
                fee_estimator: &fee_estimator,
@@@ -4049,8 -4081,6 +4081,8 @@@ fn test_claim_sizeable_push_msat() 
  
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
        nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 0);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
 +
        let spend_txn = check_spendable_outputs!(nodes[1], 1);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], node_txn[0]);
@@@ -4079,8 -4109,6 +4111,8 @@@ fn test_claim_on_remote_sizeable_push_m
        nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 0);
        check_closed_broadcast!(nodes[1], false);
        check_added_monitors!(nodes[1], 1);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
 +
        let spend_txn = check_spendable_outputs!(nodes[1], 1);
        assert_eq!(spend_txn.len(), 2);
        assert_eq!(spend_txn[0], spend_txn[1]);
@@@ -4104,21 -4132,17 +4136,21 @@@ fn test_claim_on_remote_revoked_sizeabl
        assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid());
  
        claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 3_000_000);
 -      let  header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 -      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
 +      let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 0);
        check_closed_broadcast!(nodes[1], false);
        check_added_monitors!(nodes[1], 1);
  
        let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
 +      let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
 +
        let spend_txn = check_spendable_outputs!(nodes[1], 1);
        assert_eq!(spend_txn.len(), 3);
 -      assert_eq!(spend_txn[0], spend_txn[2]); // to_remote output on revoked remote commitment_tx
 +      assert_eq!(spend_txn[0], spend_txn[1]); // to_remote output on revoked remote commitment_tx
        check_spends!(spend_txn[0], revoked_local_txn[0]);
 -      check_spends!(spend_txn[1], node_txn[0]);
 +      check_spends!(spend_txn[2], node_txn[0]);
  }
  
  #[test]
@@@ -4158,72 -4182,15 +4190,72 @@@ fn test_static_spendable_outputs_preima
        assert_eq!(node_txn.len(), 3);
        check_spends!(node_txn[0], commitment_tx[0]);
        assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
 -eprintln!("{:?}", node_txn[1]);
        check_spends!(node_txn[1], chan_1.3);
        check_spends!(node_txn[2], node_txn[1]);
  
 -      let spend_txn = check_spendable_outputs!(nodes[1], 1); // , 0, 0, 1, 1);
 +      let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
 +
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], node_txn[0]);
  }
  
 +#[test]
 +fn test_static_spendable_outputs_timeout_tx() {
 +      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);
 +
 +      // Create some initial channels
 +      let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported());
 +
 +      // Rebalance the network a bit by relaying one payment through all the channels ...
 +      send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
 +
 +      let (_, our_payment_hash) = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3_000_000);
 +
 +      let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2);
 +      assert_eq!(commitment_tx[0].input.len(), 1);
 +      assert_eq!(commitment_tx[0].input[0].previous_output.txid, chan_1.3.txid());
 +
 +      // Settle A's commitment tx on B' chain
 +      let header = BlockHeader { version: 0x2000_0000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
 +      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()] }, 0);
 +      check_added_monitors!(nodes[1], 1);
 +      let events = nodes[1].node.get_and_clear_pending_msg_events();
 +      match events[0] {
 +              MessageSendEvent::BroadcastChannelUpdate { .. } => {},
 +              _ => panic!("Unexpected event"),
 +      }
 +
 +      // Check B's monitor was able to send back output descriptor event for timeout tx on A's commitment tx
 +      let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
 +      assert_eq!(node_txn.len(), 3); // ChannelManager : 2 (local commitent tx + HTLC-timeout), ChannelMonitor: timeout tx
 +      check_spends!(node_txn[0],  commitment_tx[0].clone());
 +      assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
 +      check_spends!(node_txn[1], chan_1.3.clone());
 +      check_spends!(node_txn[2], node_txn[1]);
 +
 +      let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
 +      let events = nodes[1].node.get_and_clear_pending_events();
 +      assert_eq!(events.len(), 1);
 +      match events[0] {
 +              Event::PaymentFailed { payment_hash, .. } => {
 +                      assert_eq!(payment_hash, our_payment_hash);
 +              },
 +              _ => panic!("Unexpected event"),
 +      }
 +
 +      let spend_txn = check_spendable_outputs!(nodes[1], 1);
 +      assert_eq!(spend_txn.len(), 3); // SpendableOutput: remote_commitment_tx.to_remote (*2), timeout_tx.output (*1)
 +      check_spends!(spend_txn[2], node_txn[0].clone());
 +}
 +
  #[test]
  fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
        let chanmon_cfgs = create_chanmon_cfgs(2);
        claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 3_000_000);
  
        let  header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 -      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
 +      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 0);
        check_closed_broadcast!(nodes[1], false);
        check_added_monitors!(nodes[1], 1);
  
        assert_eq!(node_txn[0].input.len(), 2);
        check_spends!(node_txn[0], revoked_local_txn[0]);
  
 +      let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
 +
        let spend_txn = check_spendable_outputs!(nodes[1], 1);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], node_txn[0]);
@@@ -4292,7 -4255,7 +4324,7 @@@ fn test_static_spendable_outputs_justic
        check_spends!(revoked_htlc_txn[1], chan_1.3);
  
        // B will generate justice tx from A's revoked commitment/HTLC tx
 -      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1);
 +      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 0);
        check_closed_broadcast!(nodes[1], false);
        check_added_monitors!(nodes[1], 1);
  
        assert_eq!(node_txn[3].input.len(), 1);
        check_spends!(node_txn[3], revoked_local_txn[0]);
  
 +      let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone(), node_txn[2].clone()] }, 1);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
 +
        // Check B's ChannelMonitor was able to generate the right spendable output descriptor
        let spend_txn = check_spendable_outputs!(nodes[1], 1);
        assert_eq!(spend_txn.len(), 2);
@@@ -4357,18 -4316,13 +4389,18 @@@ fn test_static_spendable_outputs_justic
        assert_eq!(node_txn[2].input.len(), 1);
        check_spends!(node_txn[2], revoked_htlc_txn[0]);
  
 +      let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[0].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone(), node_txn[2].clone()] }, 1);
 +      connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
 +
        // Check A's ChannelMonitor was able to generate the right spendable output descriptor
        let spend_txn = check_spendable_outputs!(nodes[0], 1);
        assert_eq!(spend_txn.len(), 5); // Duplicated SpendableOutput due to block rescan after revoked htlc output tracking
 +      assert_eq!(spend_txn[0], spend_txn[1]);
        assert_eq!(spend_txn[0], spend_txn[2]);
        check_spends!(spend_txn[0], revoked_local_txn[0]); // spending to_remote output from revoked local tx
 -      check_spends!(spend_txn[1], node_txn[0]); // spending justice tx output from revoked local tx htlc received output
 -      check_spends!(spend_txn[3], node_txn[2]); // spending justice tx output on htlc success tx
 +      check_spends!(spend_txn[3], node_txn[0]); // spending justice tx output from revoked local tx htlc received output
 +      check_spends!(spend_txn[4], node_txn[2]); // spending justice tx output on htlc success tx
  }
  
  #[test]
@@@ -4626,23 -4580,16 +4658,23 @@@ fn test_dynamic_spendable_outputs_local
                MessageSendEvent::BroadcastChannelUpdate { .. } => {},
                _ => panic!("Unexepected event"),
        }
 -      let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
 -      assert_eq!(node_txn[0].input.len(), 1);
 -      assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
 -      check_spends!(node_txn[0], local_txn[0]);
 +      let node_txn = {
 +              let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
 +              assert_eq!(node_txn[0].input.len(), 1);
 +              assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
 +              check_spends!(node_txn[0], local_txn[0]);
 +              vec![node_txn[0].clone(), node_txn[2].clone()]
 +      };
 +
 +      let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[1].block_notifier.block_connected(&Block { header: header_201, txdata: node_txn.clone() }, 201);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 201, true, header_201.bitcoin_hash());
  
        // Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor
        let spend_txn = check_spendable_outputs!(nodes[1], 1);
        assert_eq!(spend_txn.len(), 2);
        check_spends!(spend_txn[0], node_txn[0]);
 -      check_spends!(spend_txn[1], node_txn[2]);
 +      check_spends!(spend_txn[1], node_txn[1]);
  }
  
  fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, announce_latest: bool) {
@@@ -4908,7 -4855,7 +4940,7 @@@ fn test_dynamic_spendable_outputs_local
        // Create some initial channels
        let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported());
  
 -      route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000).0;
 +      let (_, our_payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000);
        let local_txn = get_local_commitment_txn!(nodes[0], chan_1.2);
        assert_eq!(local_txn[0].input.len(), 1);
        check_spends!(local_txn[0], chan_1.3);
        check_closed_broadcast!(nodes[0], false);
        check_added_monitors!(nodes[0], 1);
  
 -      let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
 -      assert_eq!(node_txn[0].input.len(), 1);
 -      assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
 -      check_spends!(node_txn[0], local_txn[0]);
 +      let htlc_timeout = {
 +              let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
 +              assert_eq!(node_txn[0].input.len(), 1);
 +              assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
 +              check_spends!(node_txn[0], local_txn[0]);
 +              node_txn[0].clone()
 +      };
 +
 +      let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 +      nodes[0].block_notifier.block_connected(&Block { header: header_201, txdata: vec![htlc_timeout.clone()] }, 201);
 +      connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 201, true, header_201.bitcoin_hash());
 +      let events = nodes[0].node.get_and_clear_pending_events();
 +      assert_eq!(events.len(), 1);
 +      match events[0] {
 +              Event::PaymentFailed { payment_hash, .. } => {
 +                      assert_eq!(payment_hash, our_payment_hash);
 +              },
 +              _ => panic!("Unexpected event"),
 +      }
  
        // Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor
        let spend_txn = check_spendable_outputs!(nodes[0], 1);
 -      assert_eq!(spend_txn.len(), 8);
 -      assert_eq!(spend_txn[0], spend_txn[2]);
 -      assert_eq!(spend_txn[0], spend_txn[4]);
 -      assert_eq!(spend_txn[0], spend_txn[6]);
 -      assert_eq!(spend_txn[1], spend_txn[3]);
 -      assert_eq!(spend_txn[1], spend_txn[5]);
 -      assert_eq!(spend_txn[1], spend_txn[7]);
 +      assert_eq!(spend_txn.len(), 3);
 +      assert_eq!(spend_txn[0], spend_txn[1]);
        check_spends!(spend_txn[0], local_txn[0]);
 -      check_spends!(spend_txn[1], node_txn[0]);
 +      check_spends!(spend_txn[2], htlc_timeout);
  }
  
  #[test]
@@@ -4960,16 -4897,12 +4992,16 @@@ fn test_static_output_closing_tx() 
        let closing_tx = close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true).2;
  
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
 -      nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 1);
 +      nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 0);
 +      connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash());
 +
        let spend_txn = check_spendable_outputs!(nodes[0], 2);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], closing_tx);
  
 -      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 1);
 +      nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 0);
 +      connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash());
 +
        let spend_txn = check_spendable_outputs!(nodes[1], 2);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], closing_tx);
@@@ -6821,8 -6754,7 +6853,8 @@@ fn test_data_loss_protect() 
        check_spends!(node_txn[0], chan.3);
        assert_eq!(node_txn[0].output.len(), 2);
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
 -      nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()]}, 1);
 +      nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()]}, 0);
 +      connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash());
        let spend_txn = check_spendable_outputs!(nodes[0], 1);
        assert_eq!(spend_txn.len(), 1);
        check_spends!(spend_txn[0], node_txn[0]);