Merge pull request #2676 from TheBlueMatt/2023-10-various-followups
[rust-lightning] / lightning / src / chain / channelmonitor.rs
index cfd29759bb5058c109e99a2b7ebd55b54b490a07..37c3383a3ad566942efcc965742bb6099c53b5c2 100644 (file)
 
 use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::transaction::{OutPoint as BitcoinOutPoint, TxOut, Transaction};
-use bitcoin::blockdata::script::{Script, Builder};
-use bitcoin::blockdata::opcodes;
+use bitcoin::blockdata::script::Script;
 
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
-use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
+use bitcoin::hash_types::{Txid, BlockHash};
 
 use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
 use bitcoin::secp256k1::{SecretKey, PublicKey};
@@ -43,7 +42,7 @@ use crate::chain;
 use crate::chain::{BestBlock, WatchedOutput};
 use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
 use crate::chain::transaction::{OutPoint, TransactionData};
-use crate::sign::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
+use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
 use crate::chain::onchaintx::{ClaimEvent, OnchainTxHandler};
 use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
 use crate::chain::Filter;
@@ -51,7 +50,7 @@ use crate::util::logger::Logger;
 use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48};
 use crate::util::byte_utils;
 use crate::events::{Event, EventHandler};
-use crate::events::bump_transaction::{ChannelDerivationParameters, AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent};
+use crate::events::bump_transaction::{AnchorDescriptor, BumpTransactionEvent};
 
 use crate::prelude::*;
 use core::{cmp, mem};
@@ -1141,8 +1140,9 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
                          best_block: BestBlock, counterparty_node_id: PublicKey) -> ChannelMonitor<Signer> {
 
                assert!(commitment_transaction_number_obscure_factor <= (1 << 48));
-               let payment_key_hash = WPubkeyHash::hash(&keys.pubkeys().payment_point.serialize());
-               let counterparty_payment_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_key_hash[..]).into_script();
+               let counterparty_payment_script = chan_utils::get_counterparty_payment_script(
+                       &channel_parameters.channel_type_features, &keys.pubkeys().payment_point
+               );
 
                let counterparty_channel_parameters = channel_parameters.counterparty_parameters.as_ref().unwrap();
                let counterparty_delayed_payment_base_key = counterparty_channel_parameters.pubkeys.delayed_payment_basepoint;
@@ -1172,9 +1172,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
                        (holder_commitment_tx, trusted_tx.commitment_number())
                };
 
-               let onchain_tx_handler =
-                       OnchainTxHandler::new(destination_script.clone(), keys,
-                       channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx);
+               let onchain_tx_handler = OnchainTxHandler::new(
+                       channel_value_satoshis, channel_keys_id, destination_script.clone(), keys,
+                       channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx
+               );
 
                let mut outputs_to_watch = HashMap::new();
                outputs_to_watch.insert(funding_info.0.txid, vec![(funding_info.0.index as u32, funding_info.1.clone())]);
@@ -1311,7 +1312,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
                &self,
                updates: &ChannelMonitorUpdate,
                broadcaster: &B,
-               fee_estimator: F,
+               fee_estimator: &F,
                logger: &L,
        ) -> Result<(), ()>
        where
@@ -1702,6 +1703,16 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
                });
                spendable_outputs
        }
+
+       #[cfg(test)]
+       pub fn get_counterparty_payment_script(&self) -> Script{
+               self.inner.lock().unwrap().counterparty_payment_script.clone()
+       }
+
+       #[cfg(test)]
+       pub fn set_counterparty_payment_script(&self, script: Script) {
+               self.inner.lock().unwrap().counterparty_payment_script = script;
+       }
 }
 
 impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
@@ -1741,7 +1752,19 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                },
                                OnchainEvent::MaturingOutput {
                                        descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(ref descriptor) }
-                               if descriptor.outpoint.index as u32 == htlc_commitment_tx_output_idx => {
+                               if event.transaction.as_ref().map(|tx| tx.input.iter().enumerate()
+                                       .any(|(input_idx, inp)|
+                                                Some(inp.previous_output.txid) == confirmed_txid &&
+                                                       inp.previous_output.vout == htlc_commitment_tx_output_idx &&
+                                                               // A maturing output for an HTLC claim will always be at the same
+                                                               // index as the HTLC input. This is true pre-anchors, as there's
+                                                               // only 1 input and 1 output. This is also true post-anchors,
+                                                               // because we have a SIGHASH_SINGLE|ANYONECANPAY signature from our
+                                                               // channel counterparty.
+                                                               descriptor.outpoint.index as usize == input_idx
+                                       ))
+                                       .unwrap_or(false)
+                               => {
                                        debug_assert!(holder_delayed_output_pending.is_none());
                                        holder_delayed_output_pending = Some(event.confirmation_threshold());
                                },
@@ -1882,8 +1905,7 @@ impl<Signer: WriteableEcdsaChannelSigner> 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.111, balances may not be fully captured if our counterparty broadcasted
-       /// a revoked state.
+       /// LDK prior to 0.0.111, not all or excess balances may be included.
        ///
        /// See [`Balance`] for additional details on the types of claimable balances which
        /// may be returned here and their meanings.
@@ -2269,6 +2291,7 @@ macro_rules! fail_unbroadcast_htlcs {
 
 #[cfg(test)]
 pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec<u8> {
+       use bitcoin::blockdata::opcodes;
        let mut ret = [opcodes::all::OP_NOP.to_u8(); 136];
        ret[131] = opcodes::all::OP_DROP.to_u8();
        ret[132] = opcodes::all::OP_DROP.to_u8();
@@ -2509,6 +2532,18 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
        {
                self.payment_preimages.insert(payment_hash.clone(), payment_preimage.clone());
 
+               let confirmed_spend_txid = self.funding_spend_confirmed.or_else(|| {
+                       self.onchain_events_awaiting_threshold_conf.iter().find_map(|event| match event.event {
+                               OnchainEvent::FundingSpendConfirmation { .. } => Some(event.txid),
+                               _ => None,
+                       })
+               });
+               let confirmed_spend_txid = if let Some(txid) = confirmed_spend_txid {
+                       txid
+               } else {
+                       return;
+               };
+
                // If the channel is force closed, try to claim the output from this preimage.
                // First check if a counterparty commitment transaction has been broadcasted:
                macro_rules! claim_htlcs {
@@ -2518,14 +2553,24 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                        }
                }
                if let Some(txid) = self.current_counterparty_commitment_txid {
-                       if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
-                               claim_htlcs!(*commitment_number, txid);
+                       if txid == confirmed_spend_txid {
+                               if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
+                                       claim_htlcs!(*commitment_number, txid);
+                               } else {
+                                       debug_assert!(false);
+                                       log_error!(logger, "Detected counterparty commitment tx on-chain without tracking commitment number");
+                               }
                                return;
                        }
                }
                if let Some(txid) = self.prev_counterparty_commitment_txid {
-                       if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
-                               claim_htlcs!(*commitment_number, txid);
+                       if txid == confirmed_spend_txid {
+                               if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) {
+                                       claim_htlcs!(*commitment_number, txid);
+                               } else {
+                                       debug_assert!(false);
+                                       log_error!(logger, "Detected counterparty commitment tx on-chain without tracking commitment number");
+                               }
                                return;
                        }
                }
@@ -2536,13 +2581,22 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                // *we* sign a holder commitment transaction, not when e.g. a watchtower broadcasts one of our
                // holder commitment transactions.
                if self.broadcasted_holder_revokable_script.is_some() {
-                       // Assume that the broadcasted commitment transaction confirmed in the current best
-                       // block. Even if not, its a reasonable metric for the bump criteria on the HTLC
-                       // transactions.
-                       let (claim_reqs, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height());
-                       self.onchain_tx_handler.update_claims_view_from_requests(claim_reqs, self.best_block.height(), self.best_block.height(), broadcaster, fee_estimator, logger);
-                       if let Some(ref tx) = self.prev_holder_signed_commitment_tx {
-                               let (claim_reqs, _) = self.get_broadcasted_holder_claims(&tx, self.best_block.height());
+                       let holder_commitment_tx = if self.current_holder_commitment_tx.txid == confirmed_spend_txid {
+                               Some(&self.current_holder_commitment_tx)
+                       } else if let Some(prev_holder_commitment_tx) = &self.prev_holder_signed_commitment_tx {
+                               if prev_holder_commitment_tx.txid == confirmed_spend_txid {
+                                       Some(prev_holder_commitment_tx)
+                               } else {
+                                       None
+                               }
+                       } else {
+                               None
+                       };
+                       if let Some(holder_commitment_tx) = holder_commitment_tx {
+                               // Assume that the broadcasted commitment transaction confirmed in the current best
+                               // block. Even if not, its a reasonable metric for the bump criteria on the HTLC
+                               // transactions.
+                               let (claim_reqs, _) = self.get_broadcasted_holder_claims(&holder_commitment_tx, self.best_block.height());
                                self.onchain_tx_handler.update_claims_view_from_requests(claim_reqs, self.best_block.height(), self.best_block.height(), broadcaster, fee_estimator, logger);
                        }
                }
@@ -2562,7 +2616,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                self.pending_monitor_events.push(MonitorEvent::HolderForceClosed(self.funding_info.0));
        }
 
-       pub fn update_monitor<B: Deref, F: Deref, L: Deref>(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: F, logger: &L) -> Result<(), ()>
+       pub fn update_monitor<B: Deref, F: Deref, L: Deref>(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: &F, logger: &L) -> Result<(), ()>
        where B::Target: BroadcasterInterface,
                F::Target: FeeEstimator,
                L::Target: Logger,
@@ -2602,7 +2656,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                        panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!");
                }
                let mut ret = Ok(());
-               let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator);
+               let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&**fee_estimator);
                for update in updates.updates.iter() {
                        match update {
                                ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs, nondust_htlc_sources } => {
@@ -2782,6 +2836,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                                        per_commitment_point: self.onchain_tx_handler.signer.get_per_commitment_point(
                                                                htlc.per_commitment_number, &self.onchain_tx_handler.secp_ctx,
                                                        ),
+                                                       feerate_per_kw: 0,
                                                        htlc: htlc.htlc,
                                                        preimage: htlc.preimage,
                                                        counterparty_sig: htlc.counterparty_sig,
@@ -3301,7 +3356,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                                continue;
                                        }
                                } else { None };
-                               if let Some(htlc_tx) = self.onchain_tx_handler.unsafe_get_fully_signed_htlc_tx(
+                               if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(
                                        &::bitcoin::OutPoint { txid, vout }, &preimage) {
                                        holder_transactions.push(htlc_tx);
                                }
@@ -4048,6 +4103,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                        output: outp.clone(),
                                        channel_keys_id: self.channel_keys_id,
                                        channel_value_satoshis: self.channel_value_satoshis,
+                                       channel_transaction_parameters: Some(self.onchain_tx_handler.channel_transaction_parameters.clone()),
                                }));
                        }
                        if self.shutdown_script.as_ref() == Some(&outp.script_pubkey) {
@@ -4150,7 +4206,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
                        1 => { None },
                        _ => return Err(DecodeError::InvalidValue),
                };
-               let counterparty_payment_script = Readable::read(reader)?;
+               let mut counterparty_payment_script: Script = Readable::read(reader)?;
                let shutdown_script = {
                        let script = <Script as Readable>::read(reader)?;
                        if script.is_empty() { None } else { Some(script) }
@@ -4351,6 +4407,17 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
                        (17, initial_counterparty_commitment_info, option),
                });
 
+               // Monitors for anchor outputs channels opened in v0.0.116 suffered from a bug in which the
+               // wrong `counterparty_payment_script` was being tracked. Fix it now on deserialization to
+               // give them a chance to recognize the spendable output.
+               if onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() &&
+                       counterparty_payment_script.is_v0_p2wpkh()
+               {
+                       let payment_point = onchain_tx_handler.channel_transaction_parameters.holder_pubkeys.payment_point;
+                       counterparty_payment_script =
+                               chan_utils::get_to_countersignatory_with_anchors_redeemscript(&payment_point).to_v0_p2wsh();
+               }
+
                Ok((best_block.block_hash(), ChannelMonitor::from_impl(ChannelMonitorImpl {
                        latest_update_id,
                        commitment_transaction_number_obscure_factor,
@@ -4516,7 +4583,7 @@ mod tests {
 
                let broadcaster = TestBroadcaster::with_blocks(Arc::clone(&nodes[1].blocks));
                assert!(
-                       pre_update_monitor.update_monitor(&replay_update, &&broadcaster, &chanmon_cfgs[1].fee_estimator, &nodes[1].logger)
+                       pre_update_monitor.update_monitor(&replay_update, &&broadcaster, &&chanmon_cfgs[1].fee_estimator, &nodes[1].logger)
                        .is_err());
                // Even though we error'd on the first update, we should still have generated an HTLC claim
                // transaction