Merge branch '2022-02-bal-panic' into 2022-02-0.0.105-sec
authorMatt Corallo <git@bluematt.me>
Tue, 1 Mar 2022 02:23:14 +0000 (02:23 +0000)
committerMatt Corallo <git@bluematt.me>
Tue, 1 Mar 2022 02:23:14 +0000 (02:23 +0000)
1  2 
lightning/src/chain/channelmonitor.rs

index 91544f11334e4eb5bcf4683da632262cfd7dce82,a0948dfbbc91cb34b288deabfe6f8f424d79f9cd..fb2cbaddf533a9aa56cbc8586ba7f68f997345f7
@@@ -473,19 -473,6 +473,19 @@@ pub(crate) enum ChannelMonitorUpdateSte
        },
  }
  
 +impl ChannelMonitorUpdateStep {
 +      fn variant_name(&self) -> &'static str {
 +              match self {
 +                      ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo",
 +                      ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo",
 +                      ChannelMonitorUpdateStep::PaymentPreimage { .. } => "PaymentPreimage",
 +                      ChannelMonitorUpdateStep::CommitmentSecret { .. } => "CommitmentSecret",
 +                      ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
 +                      ChannelMonitorUpdateStep::ShutdownScript { .. } => "ShutdownScript",
 +              }
 +      }
 +}
 +
  impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
        (0, LatestHolderCommitmentTXInfo) => {
                (0, commitment_tx, required),
@@@ -1392,8 -1379,23 +1392,23 @@@ impl<Signer: Sign> ChannelMonitor<Signe
                        ($holder_commitment: expr, $htlc_iter: expr) => {
                                for htlc in $htlc_iter {
                                        if let Some(htlc_input_idx) = htlc.transaction_output_index {
-                                               if us.htlcs_resolved_on_chain.iter().any(|v| v.input_idx == htlc_input_idx) {
-                                                       assert!(us.funding_spend_confirmed.is_some());
+                                               if let Some(conf_thresh) = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
+                                                       if let OnchainEvent::MaturingOutput { descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) } = &event.event {
+                                                               if descriptor.outpoint.index as u32 == htlc_input_idx { Some(event.confirmation_threshold()) } else { None }
+                                                       } else { None }
+                                               }) {
+                                                       debug_assert!($holder_commitment);
+                                                       res.push(Balance::ClaimableAwaitingConfirmations {
+                                                               claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                               confirmation_height: conf_thresh,
+                                                       });
+                                               } else if us.htlcs_resolved_on_chain.iter().any(|v| v.input_idx == htlc_input_idx) {
+                                                       // Funding transaction spends should be fully confirmed by the time any
+                                                       // HTLC transactions are resolved, unless we're talking about a holder
+                                                       // commitment tx, whose resolution is delayed until the CSV timeout is
+                                                       // reached, even though HTLCs may be resolved after only
+                                                       // ANTI_REORG_DELAY confirmations.
+                                                       debug_assert!($holder_commitment || us.funding_spend_confirmed.is_some());
                                                } else if htlc.offered == $holder_commitment {
                                                        // If the payment was outbound, check if there's an HTLCUpdate
                                                        // indicating we have spent this HTLC with a timeout, claiming it back
@@@ -1884,21 -1886,16 +1899,21 @@@ impl<Signer: Sign> ChannelMonitorImpl<S
                    F::Target: FeeEstimator,
                    L::Target: Logger,
        {
 +              log_info!(logger, "Applying update to monitor {}, bringing update_id from {} to {} with {} changes.",
 +                      log_funding_info!(self), self.latest_update_id, updates.update_id, updates.updates.len());
                // ChannelMonitor updates may be applied after force close if we receive a
                // preimage for a broadcasted commitment transaction HTLC output that we'd
                // like to claim on-chain. If this is the case, we no longer have guaranteed
                // access to the monitor's update ID, so we use a sentinel value instead.
                if updates.update_id == CLOSED_CHANNEL_UPDATE_ID {
 +                      assert_eq!(updates.updates.len(), 1);
                        match updates.updates[0] {
                                ChannelMonitorUpdateStep::PaymentPreimage { .. } => {},
 -                              _ => panic!("Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage"),
 +                              _ => {
 +                                      log_error!(logger, "Attempted to apply post-force-close ChannelMonitorUpdate of type {}", updates.updates[0].variant_name());
 +                                      panic!("Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage");
 +                              },
                        }
 -                      assert_eq!(updates.updates.len(), 1);
                } else if self.latest_update_id + 1 != updates.update_id {
                        panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!");
                }