Merge pull request #1720 from TheBlueMatt/2022-09-fix-fuzz-warnings
[rust-lightning] / lightning / src / chain / channelmonitor.rs
index ed84750590a1c95ac220ce9408c40135b5aca0ec..28f3b59996c904c202b2bba0a62e476777005529 100644 (file)
@@ -37,7 +37,7 @@ use bitcoin::secp256k1;
 use ln::{PaymentHash, PaymentPreimage};
 use ln::msgs::DecodeError;
 use ln::chan_utils;
-use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCType, ChannelTransactionParameters, HolderCommitmentTransaction};
+use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction};
 use ln::channelmanager::HTLCSource;
 use chain;
 use chain::{BestBlock, WatchedOutput};
@@ -793,7 +793,10 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
        // of block connection between ChannelMonitors and the ChannelManager.
        funding_spend_seen: bool,
 
+       /// Set to `Some` of the confirmed transaction spending the funding input of the channel after
+       /// reaching `ANTI_REORG_DELAY` confirmations.
        funding_spend_confirmed: Option<Txid>,
+
        confirmed_commitment_tx_counterparty_output: CommitmentTxCounterpartyOutputInfo,
        /// The set of HTLCs which have been either claimed or failed on chain and have reached
        /// the requisite confirmations on the claim/fail transaction (either ANTI_REORG_DELAY or the
@@ -1630,7 +1633,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
        /// confirmations on the claim transaction.
        ///
        /// Note that for `ChannelMonitors` which track a channel which went on-chain with versions of
-       /// LDK prior to 0.0.108, balances may not be fully captured if our counterparty broadcasted
+       /// LDK prior to 0.0.111, balances may not be fully captured if our counterparty broadcasted
        /// a revoked state.
        ///
        /// See [`Balance`] for additional details on the types of claimable balances which
@@ -2650,6 +2653,11 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
                let txid = commitment_tx.txid();
                let mut holder_transactions = vec![commitment_tx];
+               // When anchor outputs are present, the HTLC transactions are only valid once the commitment
+               // transaction confirms.
+               if self.onchain_tx_handler.opt_anchors() {
+                       return holder_transactions;
+               }
                for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
                        if let Some(vout) = htlc.0.transaction_output_index {
                                let preimage = if !htlc.0.offered {
@@ -2683,6 +2691,11 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                let commitment_tx = self.onchain_tx_handler.get_fully_signed_copy_holder_tx(&self.funding_redeemscript);
                let txid = commitment_tx.txid();
                let mut holder_transactions = vec![commitment_tx];
+               // When anchor outputs are present, the HTLC transactions are only final once the commitment
+               // transaction confirms due to the CSV 1 encumberance.
+               if self.onchain_tx_handler.opt_anchors() {
+                       return holder_transactions;
+               }
                for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
                        if let Some(vout) = htlc.0.transaction_output_index {
                                let preimage = if !htlc.0.offered {
@@ -3068,6 +3081,16 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        }
 
        fn should_broadcast_holder_commitment_txn<L: Deref>(&self, logger: &L) -> bool where L::Target: Logger {
+               // There's no need to broadcast our commitment transaction if we've seen one confirmed (even
+               // with 1 confirmation) as it'll be rejected as duplicate/conflicting.
+               if self.funding_spend_confirmed.is_some() ||
+                       self.onchain_events_awaiting_threshold_conf.iter().find(|event| match event.event {
+                               OnchainEvent::FundingSpendConfirmation { .. } => true,
+                               _ => false,
+                       }).is_some()
+               {
+                       return false;
+               }
                // We need to consider all HTLCs which are:
                //  * in any unrevoked counterparty commitment transaction, as they could broadcast said
                //    transactions and we'd end up in a race, or
@@ -3136,25 +3159,17 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        fn is_resolving_htlc_output<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) where L::Target: Logger {
                'outer_loop: for input in &tx.input {
                        let mut payment_data = None;
-                       let witness_items = input.witness.len();
-                       let htlctype = input.witness.last().map(|w| w.len()).and_then(HTLCType::scriptlen_to_htlctype);
-                       let prev_last_witness_len = input.witness.second_to_last().map(|w| w.len()).unwrap_or(0);
-                       let revocation_sig_claim = (witness_items == 3 && htlctype == Some(HTLCType::OfferedHTLC) && prev_last_witness_len == 33)
-                               || (witness_items == 3 && htlctype == Some(HTLCType::AcceptedHTLC) && prev_last_witness_len == 33);
-                       let accepted_preimage_claim = witness_items == 5 && htlctype == Some(HTLCType::AcceptedHTLC)
-                               && input.witness.second_to_last().unwrap().len() == 32;
+                       let htlc_claim = HTLCClaim::from_witness(&input.witness);
+                       let revocation_sig_claim = htlc_claim == Some(HTLCClaim::Revocation);
+                       let accepted_preimage_claim = htlc_claim == Some(HTLCClaim::AcceptedPreimage);
                        #[cfg(not(fuzzing))]
-                       let accepted_timeout_claim = witness_items == 3 && htlctype == Some(HTLCType::AcceptedHTLC) && !revocation_sig_claim;
-                       let offered_preimage_claim = witness_items == 3 && htlctype == Some(HTLCType::OfferedHTLC) &&
-                               !revocation_sig_claim && input.witness.second_to_last().unwrap().len() == 32;
-
+                       let accepted_timeout_claim = htlc_claim == Some(HTLCClaim::AcceptedTimeout);
+                       let offered_preimage_claim = htlc_claim == Some(HTLCClaim::OfferedPreimage);
                        #[cfg(not(fuzzing))]
-                       let offered_timeout_claim = witness_items == 5 && htlctype == Some(HTLCType::OfferedHTLC);
+                       let offered_timeout_claim = htlc_claim == Some(HTLCClaim::OfferedTimeout);
 
                        let mut payment_preimage = PaymentPreimage([0; 32]);
-                       if accepted_preimage_claim {
-                               payment_preimage.0.copy_from_slice(input.witness.second_to_last().unwrap());
-                       } else if offered_preimage_claim {
+                       if offered_preimage_claim || accepted_preimage_claim {
                                payment_preimage.0.copy_from_slice(input.witness.second_to_last().unwrap());
                        }