Merge pull request #2667 from wpaulino/random-htlc-holder-sigs-non-anchors
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Fri, 20 Oct 2023 22:55:08 +0000 (22:55 +0000)
committerGitHub <noreply@github.com>
Fri, 20 Oct 2023 22:55:08 +0000 (22:55 +0000)
Use sign_holder_htlc_transaction to sign non-anchors holder HTLCs

1  2 
lightning/src/chain/onchaintx.rs
lightning/src/ln/channel.rs
lightning/src/ln/monitor_tests.rs

index b6c643180c07cd83adeacd2eaae1602ad8e52177,e1949354079d25a1ccf41d33bfe5b562fa839fb8..5aba6593834cf3a37848fe1c9763e6b5f6de7f3a
@@@ -23,14 -23,13 +23,13 @@@ use bitcoin::secp256k1::{Secp256k1, ecd
  use bitcoin::secp256k1;
  
  use crate::chain::chaininterface::compute_feerate_sat_per_1000_weight;
- use crate::sign::{ChannelSigner, EntropySource, SignerProvider};
+ use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, ChannelSigner, EntropySource, SignerProvider, WriteableEcdsaChannelSigner};
  use crate::ln::msgs::DecodeError;
  use crate::ln::PaymentPreimage;
  use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
  use crate::chain::ClaimId;
  use crate::chain::chaininterface::{ConfirmationTarget, FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
  use crate::chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER};
- use crate::sign::WriteableEcdsaChannelSigner;
  use crate::chain::package::{PackageSolvingData, PackageTemplate};
  use crate::util::logger::Logger;
  use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable, VecWriter};
@@@ -215,14 -214,11 +214,11 @@@ pub(crate) enum OnchainClaim 
  /// do RBF bumping if possible.
  #[derive(Clone)]
  pub struct OnchainTxHandler<ChannelSigner: WriteableEcdsaChannelSigner> {
+       channel_value_satoshis: u64,
+       channel_keys_id: [u8; 32],
        destination_script: Script,
        holder_commitment: HolderCommitmentTransaction,
-       // holder_htlc_sigs and prev_holder_htlc_sigs are in the order as they appear in the commitment
-       // transaction outputs (hence the Option<>s inside the Vec). The first usize is the index in
-       // the set of HTLCs in the HolderCommitmentTransaction.
-       holder_htlc_sigs: Option<Vec<Option<(usize, Signature)>>>,
        prev_holder_commitment: Option<HolderCommitmentTransaction>,
-       prev_holder_htlc_sigs: Option<Vec<Option<(usize, Signature)>>>,
  
        pub(super) signer: ChannelSigner,
        pub(crate) channel_transaction_parameters: ChannelTransactionParameters,
  impl<ChannelSigner: WriteableEcdsaChannelSigner> PartialEq for OnchainTxHandler<ChannelSigner> {
        fn eq(&self, other: &Self) -> bool {
                // `signer`, `secp_ctx`, and `pending_claim_events` are excluded on purpose.
-               self.destination_script == other.destination_script &&
+               self.channel_value_satoshis == other.channel_value_satoshis &&
+                       self.channel_keys_id == other.channel_keys_id &&
+                       self.destination_script == other.destination_script &&
                        self.holder_commitment == other.holder_commitment &&
-                       self.holder_htlc_sigs == other.holder_htlc_sigs &&
                        self.prev_holder_commitment == other.prev_holder_commitment &&
-                       self.prev_holder_htlc_sigs == other.prev_holder_htlc_sigs &&
                        self.channel_transaction_parameters == other.channel_transaction_parameters &&
                        self.pending_claim_requests == other.pending_claim_requests &&
                        self.claimable_outpoints == other.claimable_outpoints &&
@@@ -298,9 -294,9 +294,9 @@@ impl<ChannelSigner: WriteableEcdsaChann
  
                self.destination_script.write(writer)?;
                self.holder_commitment.write(writer)?;
-               self.holder_htlc_sigs.write(writer)?;
+               None::<Option<Vec<Option<(usize, Signature)>>>>.write(writer)?; // holder_htlc_sigs
                self.prev_holder_commitment.write(writer)?;
-               self.prev_holder_htlc_sigs.write(writer)?;
+               None::<Option<Vec<Option<(usize, Signature)>>>>.write(writer)?; // prev_holder_htlc_sigs
  
                self.channel_transaction_parameters.write(writer)?;
  
@@@ -355,9 -351,9 +351,9 @@@ impl<'a, 'b, ES: EntropySource, SP: Sig
                let destination_script = Readable::read(reader)?;
  
                let holder_commitment = Readable::read(reader)?;
-               let holder_htlc_sigs = Readable::read(reader)?;
+               let _holder_htlc_sigs: Option<Vec<Option<(usize, Signature)>>> = Readable::read(reader)?;
                let prev_holder_commitment = Readable::read(reader)?;
-               let prev_holder_htlc_sigs = Readable::read(reader)?;
+               let _prev_holder_htlc_sigs: Option<Vec<Option<(usize, Signature)>>> = Readable::read(reader)?;
  
                let channel_parameters = Readable::read(reader)?;
  
                secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
  
                Ok(OnchainTxHandler {
+                       channel_value_satoshis,
+                       channel_keys_id,
                        destination_script,
                        holder_commitment,
-                       holder_htlc_sigs,
                        prev_holder_commitment,
-                       prev_holder_htlc_sigs,
                        signer,
                        channel_transaction_parameters: channel_parameters,
                        claimable_outpoints,
  }
  
  impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
-       pub(crate) fn new(destination_script: Script, signer: ChannelSigner, channel_parameters: ChannelTransactionParameters, holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>) -> Self {
+       pub(crate) fn new(
+               channel_value_satoshis: u64, channel_keys_id: [u8; 32], destination_script: Script,
+               signer: ChannelSigner, channel_parameters: ChannelTransactionParameters,
+               holder_commitment: HolderCommitmentTransaction, secp_ctx: Secp256k1<secp256k1::All>
+       ) -> Self {
                OnchainTxHandler {
+                       channel_value_satoshis,
+                       channel_keys_id,
                        destination_script,
                        holder_commitment,
-                       holder_htlc_sigs: None,
                        prev_holder_commitment: None,
-                       prev_holder_htlc_sigs: None,
                        signer,
                        channel_transaction_parameters: channel_parameters,
                        pending_claim_requests: HashMap::new(),
                if cached_request.is_malleable() {
                        if cached_request.requires_external_funding() {
                                let target_feerate_sat_per_1000_weight = cached_request.compute_package_feerate(
 -                                      fee_estimator, ConfirmationTarget::HighPriority, force_feerate_bump
 +                                      fee_estimator, ConfirmationTarget::OnChainSweep, force_feerate_bump
                                );
                                if let Some(htlcs) = cached_request.construct_malleable_package_with_external_funding(self) {
                                        return Some((
                                        debug_assert_eq!(tx.txid(), self.holder_commitment.trust().txid(),
                                                "Holder commitment transaction mismatch");
  
 -                                      let conf_target = ConfirmationTarget::HighPriority;
 +                                      let conf_target = ConfirmationTarget::OnChainSweep;
                                        let package_target_feerate_sat_per_1000_weight = cached_request
                                                .compute_package_feerate(fee_estimator, conf_target, force_feerate_bump);
                                        if let Some(input_amount_sat) = output.funding_amount {
  
        pub(crate) fn provide_latest_holder_tx(&mut self, tx: HolderCommitmentTransaction) {
                self.prev_holder_commitment = Some(replace(&mut self.holder_commitment, tx));
-               self.holder_htlc_sigs = None;
-       }
-       // Normally holder HTLCs are signed at the same time as the holder commitment tx.  However,
-       // in some configurations, the holder commitment tx has been signed and broadcast by a
-       // ChannelMonitor replica, so we handle that case here.
-       fn sign_latest_holder_htlcs(&mut self) {
-               if self.holder_htlc_sigs.is_none() {
-                       let (_sig, sigs) = self.signer.sign_holder_commitment_and_htlcs(&self.holder_commitment, &self.secp_ctx).expect("sign holder commitment");
-                       self.holder_htlc_sigs = Some(Self::extract_holder_sigs(&self.holder_commitment, sigs));
-               }
-       }
-       // Normally only the latest commitment tx and HTLCs need to be signed.  However, in some
-       // configurations we may have updated our holder commitment but a replica of the ChannelMonitor
-       // broadcast the previous one before we sync with it.  We handle that case here.
-       fn sign_prev_holder_htlcs(&mut self) {
-               if self.prev_holder_htlc_sigs.is_none() {
-                       if let Some(ref holder_commitment) = self.prev_holder_commitment {
-                               let (_sig, sigs) = self.signer.sign_holder_commitment_and_htlcs(holder_commitment, &self.secp_ctx).expect("sign previous holder commitment");
-                               self.prev_holder_htlc_sigs = Some(Self::extract_holder_sigs(holder_commitment, sigs));
-                       }
-               }
-       }
-       fn extract_holder_sigs(holder_commitment: &HolderCommitmentTransaction, sigs: Vec<Signature>) -> Vec<Option<(usize, Signature)>> {
-               let mut ret = Vec::new();
-               for (htlc_idx, (holder_sig, htlc)) in sigs.iter().zip(holder_commitment.htlcs().iter()).enumerate() {
-                       let tx_idx = htlc.transaction_output_index.unwrap();
-                       if ret.len() <= tx_idx as usize { ret.resize(tx_idx as usize + 1, None); }
-                       ret[tx_idx as usize] = Some((htlc_idx, holder_sig.clone()));
-               }
-               ret
        }
  
        pub(crate) fn get_unsigned_holder_commitment_tx(&self) -> &Transaction {
        // before providing a initial commitment transaction. For outbound channel, init ChannelMonitor at Channel::funding_signed, there is nothing
        // to monitor before.
        pub(crate) fn get_fully_signed_holder_tx(&mut self, funding_redeemscript: &Script) -> Transaction {
-               let (sig, htlc_sigs) = self.signer.sign_holder_commitment_and_htlcs(&self.holder_commitment, &self.secp_ctx).expect("signing holder commitment");
-               self.holder_htlc_sigs = Some(Self::extract_holder_sigs(&self.holder_commitment, htlc_sigs));
+               let sig = self.signer.sign_holder_commitment(&self.holder_commitment, &self.secp_ctx).expect("signing holder commitment");
                self.holder_commitment.add_holder_sig(funding_redeemscript, sig)
        }
  
        #[cfg(any(test, feature="unsafe_revoked_tx_signing"))]
        pub(crate) fn get_fully_signed_copy_holder_tx(&mut self, funding_redeemscript: &Script) -> Transaction {
-               let (sig, htlc_sigs) = self.signer.unsafe_sign_holder_commitment_and_htlcs(&self.holder_commitment, &self.secp_ctx).expect("sign holder commitment");
-               self.holder_htlc_sigs = Some(Self::extract_holder_sigs(&self.holder_commitment, htlc_sigs));
+               let sig = self.signer.unsafe_sign_holder_commitment(&self.holder_commitment, &self.secp_ctx).expect("sign holder commitment");
                self.holder_commitment.add_holder_sig(funding_redeemscript, sig)
        }
  
        pub(crate) fn get_fully_signed_htlc_tx(&mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>) -> Option<Transaction> {
-               let mut htlc_tx = None;
-               let commitment_txid = self.holder_commitment.trust().txid();
-               // Check if the HTLC spends from the current holder commitment
-               if commitment_txid == outp.txid {
-                       self.sign_latest_holder_htlcs();
-                       if let &Some(ref htlc_sigs) = &self.holder_htlc_sigs {
-                               let &(ref htlc_idx, ref htlc_sig) = htlc_sigs[outp.vout as usize].as_ref().unwrap();
-                               let trusted_tx = self.holder_commitment.trust();
-                               let counterparty_htlc_sig = self.holder_commitment.counterparty_htlc_sigs[*htlc_idx];
-                               htlc_tx = Some(trusted_tx
-                                       .get_signed_htlc_tx(&self.channel_transaction_parameters.as_holder_broadcastable(), *htlc_idx, &counterparty_htlc_sig, htlc_sig, preimage));
-                       }
-               }
-               // If the HTLC doesn't spend the current holder commitment, check if it spends the previous one
-               if htlc_tx.is_none() && self.prev_holder_commitment.is_some() {
-                       let commitment_txid = self.prev_holder_commitment.as_ref().unwrap().trust().txid();
-                       if commitment_txid == outp.txid {
-                               self.sign_prev_holder_htlcs();
-                               if let &Some(ref htlc_sigs) = &self.prev_holder_htlc_sigs {
-                                       let &(ref htlc_idx, ref htlc_sig) = htlc_sigs[outp.vout as usize].as_ref().unwrap();
-                                       let holder_commitment = self.prev_holder_commitment.as_ref().unwrap();
-                                       let trusted_tx = holder_commitment.trust();
-                                       let counterparty_htlc_sig = holder_commitment.counterparty_htlc_sigs[*htlc_idx];
-                                       htlc_tx = Some(trusted_tx
-                                               .get_signed_htlc_tx(&self.channel_transaction_parameters.as_holder_broadcastable(), *htlc_idx, &counterparty_htlc_sig, htlc_sig, preimage));
-                               }
+               let get_signed_htlc_tx = |holder_commitment: &HolderCommitmentTransaction| {
+                       let trusted_tx = holder_commitment.trust();
+                       if trusted_tx.txid() != outp.txid {
+                               return None;
                        }
-               }
-               htlc_tx
+                       let (htlc_idx, htlc) = trusted_tx.htlcs().iter().enumerate()
+                               .find(|(_, htlc)| htlc.transaction_output_index.unwrap() == outp.vout)
+                               .unwrap();
+                       let counterparty_htlc_sig = holder_commitment.counterparty_htlc_sigs[htlc_idx];
+                       let mut htlc_tx = trusted_tx.build_unsigned_htlc_tx(
+                               &self.channel_transaction_parameters.as_holder_broadcastable(), htlc_idx, preimage,
+                       );
+                       let htlc_descriptor = HTLCDescriptor {
+                               channel_derivation_parameters: ChannelDerivationParameters {
+                                       value_satoshis: self.channel_value_satoshis,
+                                       keys_id: self.channel_keys_id,
+                                       transaction_parameters: self.channel_transaction_parameters.clone(),
+                               },
+                               commitment_txid: trusted_tx.txid(),
+                               per_commitment_number: trusted_tx.commitment_number(),
+                               per_commitment_point: trusted_tx.per_commitment_point(),
+                               feerate_per_kw: trusted_tx.feerate_per_kw(),
+                               htlc: htlc.clone(),
+                               preimage: preimage.clone(),
+                               counterparty_sig: counterparty_htlc_sig.clone(),
+                       };
+                       let htlc_sig = self.signer.sign_holder_htlc_transaction(&htlc_tx, 0, &htlc_descriptor, &self.secp_ctx).unwrap();
+                       htlc_tx.input[0].witness = trusted_tx.build_htlc_input_witness(
+                               htlc_idx, &counterparty_htlc_sig, &htlc_sig, preimage,
+                       );
+                       Some(htlc_tx)
+               };
+               // Check if the HTLC spends from the current holder commitment first, or the previous.
+               get_signed_htlc_tx(&self.holder_commitment)
+                       .or_else(|| self.prev_holder_commitment.as_ref().and_then(|prev_holder_commitment| get_signed_htlc_tx(prev_holder_commitment)))
        }
  
        pub(crate) fn generate_external_htlc_claim(
        pub(crate) fn channel_type_features(&self) -> &ChannelTypeFeatures {
                &self.channel_transaction_parameters.channel_type_features
        }
-       #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
-       pub(crate) fn unsafe_get_fully_signed_htlc_tx(&mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>) -> Option<Transaction> {
-               let latest_had_sigs = self.holder_htlc_sigs.is_some();
-               let prev_had_sigs = self.prev_holder_htlc_sigs.is_some();
-               let ret = self.get_fully_signed_htlc_tx(outp, preimage);
-               if !latest_had_sigs {
-                       self.holder_htlc_sigs = None;
-               }
-               if !prev_had_sigs {
-                       self.prev_holder_htlc_sigs = None;
-               }
-               ret
-       }
  }
index f3632b41b471098392bf357e3a9e7220995588ce,10ce637701ce69c71f7a6767977b0b2ce0f7b3e8..33de30a4b84da724c57dafc610eb8418fd757572
@@@ -7,7 -7,6 +7,7 @@@
  // You may not use this file except in accordance with one or both of these
  // licenses.
  
 +use bitcoin::blockdata::constants::ChainHash;
  use bitcoin::blockdata::script::{Script,Builder};
  use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType};
  use bitcoin::util::sighash;
@@@ -724,7 -723,7 +724,7 @@@ pub(super) struct ChannelContext<SP: De
  
        cur_holder_commitment_transaction_number: u64,
        cur_counterparty_commitment_transaction_number: u64,
 -      value_to_self_msat: u64, // Excluding all pending_htlcs, excluding fees
 +      value_to_self_msat: u64, // Excluding all pending_htlcs, fees, and anchor outputs
        pending_inbound_htlcs: Vec<InboundHTLCOutput>,
        pending_outbound_htlcs: Vec<OutboundHTLCOutput>,
        holding_cell_htlc_updates: Vec<HTLCUpdateAwaitingACK>,
@@@ -1169,7 -1168,7 +1169,7 @@@ impl<SP: Deref> ChannelContext<SP> wher
                match self.config.options.max_dust_htlc_exposure {
                        MaxDustHTLCExposure::FeeRateMultiplier(multiplier) => {
                                let feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight(
 -                                      ConfirmationTarget::HighPriority);
 +                                      ConfirmationTarget::OnChainSweep);
                                feerate_per_kw as u64 * multiplier
                        },
                        MaxDustHTLCExposure::FixedLimitMsat(limit) => limit,
  
                let mut available_capacity_msat = outbound_capacity_msat;
  
 +              let anchor_outputs_value_msat = if context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
 +                      ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000
 +              } else {
 +                      0
 +              };
                if context.is_outbound() {
                        // We should mind channel commit tx fee when computing how much of the available capacity
                        // can be used in the next htlc. Mirrors the logic in send_htlc.
                        }
  
                        let htlc_above_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000, HTLCInitiator::LocalOffered);
 -                      let max_reserved_commit_tx_fee_msat = FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE * context.next_local_commit_tx_fee_msat(htlc_above_dust, Some(()));
 +                      let mut max_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(htlc_above_dust, Some(()));
                        let htlc_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000 - 1, HTLCInitiator::LocalOffered);
 -                      let min_reserved_commit_tx_fee_msat = FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE * context.next_local_commit_tx_fee_msat(htlc_dust, Some(()));
 +                      let mut min_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(htlc_dust, Some(()));
 +                      if !context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
 +                              max_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
 +                              min_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
 +                      }
  
                        // We will first subtract the fee as if we were above-dust. Then, if the resulting
                        // value ends up being below dust, we have this fee available again. In that case,
                        // match the value to right-below-dust.
 -                      let mut capacity_minus_commitment_fee_msat: i64 = (available_capacity_msat as i64) - (max_reserved_commit_tx_fee_msat as i64);
 +                      let mut capacity_minus_commitment_fee_msat: i64 = available_capacity_msat as i64 -
 +                              max_reserved_commit_tx_fee_msat as i64 - anchor_outputs_value_msat as i64;
                        if capacity_minus_commitment_fee_msat < (real_dust_limit_timeout_sat as i64) * 1000 {
                                let one_htlc_difference_msat = max_reserved_commit_tx_fee_msat - min_reserved_commit_tx_fee_msat;
                                debug_assert!(one_htlc_difference_msat != 0);
                        let remote_balance_msat = (context.channel_value_satoshis * 1000 - context.value_to_self_msat)
                                .saturating_sub(inbound_stats.pending_htlcs_value_msat);
  
 -                      if remote_balance_msat < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat {
 +                      if remote_balance_msat < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat + anchor_outputs_value_msat {
                                // If another HTLC's fee would reduce the remote's balance below the reserve limit
                                // we've selected for them, we can only send dust HTLCs.
                                available_capacity_msat = cmp::min(available_capacity_msat, real_dust_limit_success_sat * 1000 - 1);
@@@ -2129,7 -2118,7 +2129,7 @@@ fn commit_tx_fee_sat(feerate_per_kw: u3
  
  // Get the fee cost in MSATS of a commitment tx with a given number of HTLC outputs.
  // Note that num_htlcs should not include dust HTLCs.
 -fn commit_tx_fee_msat(feerate_per_kw: u32, num_htlcs: usize, channel_type_features: &ChannelTypeFeatures) -> u64 {
 +pub(crate) fn commit_tx_fee_msat(feerate_per_kw: u32, num_htlcs: usize, channel_type_features: &ChannelTypeFeatures) -> u64 {
        // Note that we need to divide before multiplying to round properly,
        // since the lowest denomination of bitcoin on-chain is the satoshi.
        (commitment_tx_base_weight(channel_type_features) + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC) * feerate_per_kw as u64 / 1000 * 1000
@@@ -2166,20 -2155,28 +2166,20 @@@ impl<SP: Deref> Channel<SP> wher
                // apply to channels supporting anchor outputs since HTLC transactions are pre-signed with a
                // zero fee, so their fee is no longer considered to determine dust limits.
                if !channel_type.supports_anchors_zero_fee_htlc_tx() {
 -                      let upper_limit = cmp::max(250 * 25,
 -                              fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::HighPriority) as u64 * 10);
 +                      let upper_limit =
 +                              fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee) as u64;
                        if feerate_per_kw as u64 > upper_limit {
                                return Err(ChannelError::Close(format!("Peer's feerate much too high. Actual: {}. Our expected upper limit: {}", feerate_per_kw, upper_limit)));
                        }
                }
  
 -              // We can afford to use a lower bound with anchors than previously since we can now bump
 -              // fees when broadcasting our commitment. However, we must still make sure we meet the
 -              // minimum mempool feerate, until package relay is deployed, such that we can ensure the
 -              // commitment transaction propagates throughout node mempools on its own.
                let lower_limit_conf_target = if channel_type.supports_anchors_zero_fee_htlc_tx() {
 -                      ConfirmationTarget::MempoolMinimum
 +                      ConfirmationTarget::MinAllowedAnchorChannelRemoteFee
                } else {
 -                      ConfirmationTarget::Background
 +                      ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee
                };
                let lower_limit = fee_estimator.bounded_sat_per_1000_weight(lower_limit_conf_target);
 -              // Some fee estimators round up to the next full sat/vbyte (ie 250 sats per kw), causing
 -              // occasional issues with feerate disagreements between an initiator that wants a feerate
 -              // of 1.1 sat/vbyte and a receiver that wants 1.1 rounded up to 2. Thus, we always add 250
 -              // sat/kw before the comparison here.
 -              if feerate_per_kw + 250 < lower_limit {
 +              if feerate_per_kw < lower_limit {
                        if let Some(cur_feerate) = cur_feerate_per_kw {
                                if feerate_per_kw > cur_feerate {
                                        log_warn!(logger,
                                        return Ok(());
                                }
                        }
 -                      return Err(ChannelError::Close(format!("Peer's feerate much too low. Actual: {}. Our expected lower limit: {} (- 250)", feerate_per_kw, lower_limit)));
 +                      return Err(ChannelError::Close(format!("Peer's feerate much too low. Actual: {}. Our expected lower limit: {}", feerate_per_kw, lower_limit)));
                }
                Ok(())
        }
        /// and the channel is now usable (and public), this may generate an announcement_signatures to
        /// reply with.
        pub fn channel_ready<NS: Deref, L: Deref>(
 -              &mut self, msg: &msgs::ChannelReady, node_signer: &NS, genesis_block_hash: BlockHash,
 +              &mut self, msg: &msgs::ChannelReady, node_signer: &NS, chain_hash: ChainHash,
                user_config: &UserConfig, best_block: &BestBlock, logger: &L
        ) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError>
        where
  
                log_info!(logger, "Received channel_ready from peer for channel {}", &self.context.channel_id());
  
 -              Ok(self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger))
 +              Ok(self.get_announcement_sigs(node_signer, chain_hash, user_config, best_block.height(), logger))
        }
  
        pub fn update_add_htlc<F, FE: Deref, L: Deref>(
                if inbound_stats.pending_htlcs_value_msat + msg.amount_msat > self.context.holder_max_htlc_value_in_flight_msat {
                        return Err(ChannelError::Close(format!("Remote HTLC add would put them over our max HTLC value ({})", self.context.holder_max_htlc_value_in_flight_msat)));
                }
 +
                // Check holder_selected_channel_reserve_satoshis (we're getting paid, so they have to at least meet
                // the reserve_satoshis we told them to always have as direct payment so that they lose
                // something if we punish them for broadcasting an old state).
  
                // Check that the remote can afford to pay for this HTLC on-chain at the current
                // feerate_per_kw, while maintaining their channel reserve (as required by the spec).
 -              let remote_commit_tx_fee_msat = if self.context.is_outbound() { 0 } else {
 -                      let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
 -                      self.context.next_remote_commit_tx_fee_msat(htlc_candidate, None) // Don't include the extra fee spike buffer HTLC in calculations
 -              };
 -              if pending_remote_value_msat - msg.amount_msat < remote_commit_tx_fee_msat {
 -                      return Err(ChannelError::Close("Remote HTLC add would not leave enough to pay for fees".to_owned()));
 -              };
 -
 -              if pending_remote_value_msat - msg.amount_msat - remote_commit_tx_fee_msat < self.context.holder_selected_channel_reserve_satoshis * 1000 {
 -                      return Err(ChannelError::Close("Remote HTLC add would put them under remote reserve value".to_owned()));
 +              {
 +                      let remote_commit_tx_fee_msat = if self.context.is_outbound() { 0 } else {
 +                              let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
 +                              self.context.next_remote_commit_tx_fee_msat(htlc_candidate, None) // Don't include the extra fee spike buffer HTLC in calculations
 +                      };
 +                      let anchor_outputs_value_msat = if !self.context.is_outbound() && self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
 +                              ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000
 +                      } else {
 +                              0
 +                      };
 +                      if pending_remote_value_msat.saturating_sub(msg.amount_msat).saturating_sub(anchor_outputs_value_msat) < remote_commit_tx_fee_msat {
 +                              return Err(ChannelError::Close("Remote HTLC add would not leave enough to pay for fees".to_owned()));
 +                      };
 +                      if pending_remote_value_msat.saturating_sub(msg.amount_msat).saturating_sub(remote_commit_tx_fee_msat).saturating_sub(anchor_outputs_value_msat) < self.context.holder_selected_channel_reserve_satoshis * 1000 {
 +                              return Err(ChannelError::Close("Remote HTLC add would put them under remote reserve value".to_owned()));
 +                      }
                }
  
 +              let anchor_outputs_value_msat = if self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
 +                      ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000
 +              } else {
 +                      0
 +              };
                if !self.context.is_outbound() {
 -                      // `2 *` and `Some(())` is for the fee spike buffer we keep for the remote. This deviates from
 -                      // the spec because in the spec, the fee spike buffer requirement doesn't exist on the
 -                      // receiver's side, only on the sender's.
 -                      // Note that when we eventually remove support for fee updates and switch to anchor output
 -                      // fees, we will drop the `2 *`, since we no longer be as sensitive to fee spikes. But, keep
 -                      // the extra htlc when calculating the next remote commitment transaction fee as we should
 -                      // still be able to afford adding this HTLC plus one more future HTLC, regardless of being
 -                      // sensitive to fee spikes.
 +                      // `Some(())` is for the fee spike buffer we keep for the remote. This deviates from
 +                      // the spec because the fee spike buffer requirement doesn't exist on the receiver's
 +                      // side, only on the sender's. Note that with anchor outputs we are no longer as
 +                      // sensitive to fee spikes, so we need to account for them.
                        let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
 -                      let remote_fee_cost_incl_stuck_buffer_msat = 2 * self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(()));
 -                      if pending_remote_value_msat - msg.amount_msat - self.context.holder_selected_channel_reserve_satoshis * 1000 < remote_fee_cost_incl_stuck_buffer_msat {
 +                      let mut remote_fee_cost_incl_stuck_buffer_msat = self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(()));
 +                      if !self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
 +                              remote_fee_cost_incl_stuck_buffer_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
 +                      }
 +                      if pending_remote_value_msat.saturating_sub(msg.amount_msat).saturating_sub(self.context.holder_selected_channel_reserve_satoshis * 1000).saturating_sub(anchor_outputs_value_msat) < remote_fee_cost_incl_stuck_buffer_msat {
                                // Note that if the pending_forward_status is not updated here, then it's because we're already failing
                                // the HTLC, i.e. its status is already set to failing.
                                log_info!(logger, "Attempting to fail HTLC due to fee spike buffer violation in channel {}. Rebalancing is required.", &self.context.channel_id());
                        // Check that they won't violate our local required channel reserve by adding this HTLC.
                        let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
                        let local_commit_tx_fee_msat = self.context.next_local_commit_tx_fee_msat(htlc_candidate, None);
 -                      if self.context.value_to_self_msat < self.context.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 + local_commit_tx_fee_msat {
 +                      if self.context.value_to_self_msat < self.context.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 + local_commit_tx_fee_msat + anchor_outputs_value_msat {
                                return Err(ChannelError::Close("Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value".to_owned()));
                        }
                }
        /// successfully and we should restore normal operation. Returns messages which should be sent
        /// to the remote side.
        pub fn monitor_updating_restored<L: Deref, NS: Deref>(
 -              &mut self, logger: &L, node_signer: &NS, genesis_block_hash: BlockHash,
 +              &mut self, logger: &L, node_signer: &NS, chain_hash: ChainHash,
                user_config: &UserConfig, best_block_height: u32
        ) -> MonitorRestoreUpdates
        where
                        })
                } else { None };
  
 -              let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block_height, logger);
 +              let announcement_sigs = self.get_announcement_sigs(node_signer, chain_hash, user_config, best_block_height, logger);
  
                let mut accepted_htlcs = Vec::new();
                mem::swap(&mut accepted_htlcs, &mut self.context.monitor_pending_forwards);
        /// [`super::channelmanager::ChannelManager::force_close_all_channels_without_broadcasting_txn`].
        pub fn channel_reestablish<L: Deref, NS: Deref>(
                &mut self, msg: &msgs::ChannelReestablish, logger: &L, node_signer: &NS,
 -              genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock
 +              chain_hash: ChainHash, user_config: &UserConfig, best_block: &BestBlock
        ) -> Result<ReestablishResponses, ChannelError>
        where
                L::Target: Logger,
  
                if msg.next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg.next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER ||
                        msg.next_local_commitment_number == 0 {
 -                      return Err(ChannelError::Close("Peer sent a garbage channel_reestablish (usually an lnd node with lost state asking us to force-close for them)".to_owned()));
 +                      return Err(ChannelError::Close("Peer sent an invalid channel_reestablish to force close in a non-standard way".to_owned()));
                }
  
                if msg.next_remote_commitment_number > 0 {
  
                let shutdown_msg = self.get_outbound_shutdown();
  
 -              let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger);
 +              let announcement_sigs = self.get_announcement_sigs(node_signer, chain_hash, user_config, best_block.height(), logger);
  
                if self.context.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 {
                        // If we're waiting on a monitor update, we shouldn't re-send any channel_ready's.
                // Propose a range from our current Background feerate to our Normal feerate plus our
                // force_close_avoidance_max_fee_satoshis.
                // If we fail to come to consensus, we'll have to force-close.
 -              let mut proposed_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Background);
 -              let normal_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal);
 +              let mut proposed_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::ChannelCloseMinimum);
 +              // Use NonAnchorChannelFee because this should be an estimate for a channel close
 +              // that we don't expect to need fee bumping
 +              let normal_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee);
                let mut proposed_max_feerate = if self.context.is_outbound() { normal_feerate } else { u32::max_value() };
  
                // The spec requires that (when the channel does not have anchors) we only send absolute
        /// In the second, we simply return an Err indicating we need to be force-closed now.
        pub fn transactions_confirmed<NS: Deref, L: Deref>(
                &mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData,
 -              genesis_block_hash: BlockHash, node_signer: &NS, user_config: &UserConfig, logger: &L
 +              chain_hash: ChainHash, node_signer: &NS, user_config: &UserConfig, logger: &L
        ) -> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason>
        where
                NS::Target: NodeSigner,
                                        // may have already happened for this block).
                                        if let Some(channel_ready) = self.check_get_channel_ready(height) {
                                                log_info!(logger, "Sending a channel_ready to our peer for channel {}", &self.context.channel_id);
 -                                              let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger);
 +                                              let announcement_sigs = self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger);
                                                msgs = (Some(channel_ready), announcement_sigs);
                                        }
                                }
        /// May return some HTLCs (and their payment_hash) which have timed out and should be failed
        /// back.
        pub fn best_block_updated<NS: Deref, L: Deref>(
 -              &mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash,
 +              &mut self, height: u32, highest_header_time: u32, chain_hash: ChainHash,
                node_signer: &NS, user_config: &UserConfig, logger: &L
        ) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>
        where
                NS::Target: NodeSigner,
                L::Target: Logger
        {
 -              self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_signer, user_config)), logger)
 +              self.do_best_block_updated(height, highest_header_time, Some((chain_hash, node_signer, user_config)), logger)
        }
  
        fn do_best_block_updated<NS: Deref, L: Deref>(
                &mut self, height: u32, highest_header_time: u32,
 -              genesis_node_signer: Option<(BlockHash, &NS, &UserConfig)>, logger: &L
 +              chain_node_signer: Option<(ChainHash, &NS, &UserConfig)>, logger: &L
        ) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>
        where
                NS::Target: NodeSigner,
                self.context.update_time_counter = cmp::max(self.context.update_time_counter, highest_header_time);
  
                if let Some(channel_ready) = self.check_get_channel_ready(height) {
 -                      let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer {
 -                              self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger)
 +                      let announcement_sigs = if let Some((chain_hash, node_signer, user_config)) = chain_node_signer {
 +                              self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger)
                        } else { None };
                        log_info!(logger, "Sending a channel_ready to our peer for channel {}", &self.context.channel_id);
                        return Ok((Some(channel_ready), timed_out_htlcs, announcement_sigs));
                        return Err(ClosureReason::FundingTimedOut);
                }
  
 -              let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer {
 -                      self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger)
 +              let announcement_sigs = if let Some((chain_hash, node_signer, user_config)) = chain_node_signer {
 +                      self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger)
                } else { None };
                Ok((None, timed_out_htlcs, announcement_sigs))
        }
                        // larger. If we don't know that time has moved forward, we can just set it to the last
                        // time we saw and it will be ignored.
                        let best_time = self.context.update_time_counter;
 -                      match self.do_best_block_updated(reorg_height, best_time, None::<(BlockHash, &&NodeSigner, &UserConfig)>, logger) {
 +                      match self.do_best_block_updated(reorg_height, best_time, None::<(ChainHash, &&NodeSigner, &UserConfig)>, logger) {
                                Ok((channel_ready, timed_out_htlcs, announcement_sigs)) => {
                                        assert!(channel_ready.is_none(), "We can't generate a funding with 0 confirmations?");
                                        assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?");
        ///
        /// [`ChannelReady`]: crate::ln::msgs::ChannelReady
        fn get_channel_announcement<NS: Deref>(
 -              &self, node_signer: &NS, chain_hash: BlockHash, user_config: &UserConfig,
 +              &self, node_signer: &NS, chain_hash: ChainHash, user_config: &UserConfig,
        ) -> Result<msgs::UnsignedChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
                if !self.context.config.announced_channel {
                        return Err(ChannelError::Ignore("Channel is not available for public announcements".to_owned()));
        }
  
        fn get_announcement_sigs<NS: Deref, L: Deref>(
 -              &mut self, node_signer: &NS, genesis_block_hash: BlockHash, user_config: &UserConfig,
 +              &mut self, node_signer: &NS, chain_hash: ChainHash, user_config: &UserConfig,
                best_block_height: u32, logger: &L
        ) -> Option<msgs::AnnouncementSignatures>
        where
                }
  
                log_trace!(logger, "Creating an announcement_signatures message for channel {}", &self.context.channel_id());
 -              let announcement = match self.get_channel_announcement(node_signer, genesis_block_hash, user_config) {
 +              let announcement = match self.get_channel_announcement(node_signer, chain_hash, user_config) {
                        Ok(a) => a,
                        Err(e) => {
                                log_trace!(logger, "{:?}", e);
        /// channel_announcement message which we can broadcast and storing our counterparty's
        /// signatures for later reconstruction/rebroadcast of the channel_announcement.
        pub fn announcement_signatures<NS: Deref>(
 -              &mut self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32,
 +              &mut self, node_signer: &NS, chain_hash: ChainHash, best_block_height: u32,
                msg: &msgs::AnnouncementSignatures, user_config: &UserConfig
        ) -> Result<msgs::ChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
                let announcement = self.get_channel_announcement(node_signer, chain_hash, user_config)?;
        /// Gets a signed channel_announcement for this channel, if we previously received an
        /// announcement_signatures from our counterparty.
        pub fn get_signed_channel_announcement<NS: Deref>(
 -              &self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32, user_config: &UserConfig
 +              &self, node_signer: &NS, chain_hash: ChainHash, best_block_height: u32, user_config: &UserConfig
        ) -> Option<msgs::ChannelAnnouncement> where NS::Target: NodeSigner {
                if self.context.funding_tx_confirmation_height == 0 || self.context.funding_tx_confirmation_height + 5 > best_block_height {
                        return None;
@@@ -5742,16 -5726,16 +5742,16 @@@ impl<SP: Deref> OutboundV1Channel<SP> w
                let channel_type = Self::get_initial_channel_type(&config, their_features);
                debug_assert!(channel_type.is_subset(&channelmanager::provided_channel_type_features(&config)));
  
 -              let commitment_conf_target = if channel_type.supports_anchors_zero_fee_htlc_tx() {
 -                      ConfirmationTarget::MempoolMinimum
 +              let (commitment_conf_target, anchor_outputs_value_msat)  = if channel_type.supports_anchors_zero_fee_htlc_tx() {
 +                      (ConfirmationTarget::AnchorChannelFee, ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000)
                } else {
 -                      ConfirmationTarget::Normal
 +                      (ConfirmationTarget::NonAnchorChannelFee, 0)
                };
                let commitment_feerate = fee_estimator.bounded_sat_per_1000_weight(commitment_conf_target);
  
                let value_to_self_msat = channel_value_satoshis * 1000 - push_msat;
                let commitment_tx_fee = commit_tx_fee_msat(commitment_feerate, MIN_AFFORDABLE_HTLC_COUNT, &channel_type);
 -              if value_to_self_msat < commitment_tx_fee {
 +              if value_to_self_msat.saturating_sub(anchor_outputs_value_msat) < commitment_tx_fee {
                        return Err(APIError::APIMisuseError{ err: format!("Funding amount ({}) can't even pay fee for initial commitment transaction fee of {}.", value_to_self_msat / 1000, commitment_tx_fee / 1000) });
                }
  
        /// not of our ability to open any channel at all. Thus, on error, we should first call this
        /// and see if we get a new `OpenChannel` message, otherwise the channel is failed.
        pub(crate) fn maybe_handle_error_without_close<F: Deref>(
 -              &mut self, chain_hash: BlockHash, fee_estimator: &LowerBoundedFeeEstimator<F>
 +              &mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>
        ) -> Result<msgs::OpenChannel, ()>
        where
                F::Target: FeeEstimator
                // whatever reason.
                if self.context.channel_type.supports_anchors_zero_fee_htlc_tx() {
                        self.context.channel_type.clear_anchors_zero_fee_htlc_tx();
 -                      self.context.feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal);
 +                      self.context.feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee);
                        assert!(!self.context.channel_transaction_parameters.channel_type_features.supports_anchors_nonzero_fee_htlc_tx());
                } else if self.context.channel_type.supports_scid_privacy() {
                        self.context.channel_type.clear_scid_privacy();
                Ok(self.get_open_channel(chain_hash))
        }
  
 -      pub fn get_open_channel(&self, chain_hash: BlockHash) -> msgs::OpenChannel {
 +      pub fn get_open_channel(&self, chain_hash: ChainHash) -> msgs::OpenChannel {
                if !self.context.is_outbound() {
                        panic!("Tried to open a channel for an inbound channel?");
                }
@@@ -6368,18 -6352,13 +6368,18 @@@ impl<SP: Deref> InboundV1Channel<SP> wh
  
                // check if the funder's amount for the initial commitment tx is sufficient
                // for full fee payment plus a few HTLCs to ensure the channel will be useful.
 +              let anchor_outputs_value = if channel_type.supports_anchors_zero_fee_htlc_tx() {
 +                      ANCHOR_OUTPUT_VALUE_SATOSHI * 2
 +              } else {
 +                      0
 +              };
                let funders_amount_msat = msg.funding_satoshis * 1000 - msg.push_msat;
                let commitment_tx_fee = commit_tx_fee_msat(msg.feerate_per_kw, MIN_AFFORDABLE_HTLC_COUNT, &channel_type) / 1000;
 -              if funders_amount_msat / 1000 < commitment_tx_fee {
 -                      return Err(ChannelError::Close(format!("Funding amount ({} sats) can't even pay fee for initial commitment transaction fee of {} sats.", funders_amount_msat / 1000, commitment_tx_fee)));
 +              if (funders_amount_msat / 1000).saturating_sub(anchor_outputs_value) < commitment_tx_fee {
 +                      return Err(ChannelError::Close(format!("Funding amount ({} sats) can't even pay fee for initial commitment transaction fee of {} sats.", (funders_amount_msat / 1000).saturating_sub(anchor_outputs_value), commitment_tx_fee)));
                }
  
 -              let to_remote_satoshis = funders_amount_msat / 1000 - commitment_tx_fee;
 +              let to_remote_satoshis = funders_amount_msat / 1000 - commitment_tx_fee - anchor_outputs_value;
                // While it's reasonable for us to not meet the channel reserve initially (if they don't
                // want to push much to us), our counterparty should always have more than our reserve.
                if to_remote_satoshis < holder_selected_channel_reserve_satoshis {
@@@ -7654,9 -7633,9 +7654,9 @@@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> 
  #[cfg(test)]
  mod tests {
        use std::cmp;
 +      use bitcoin::blockdata::constants::ChainHash;
        use bitcoin::blockdata::script::{Script, Builder};
        use bitcoin::blockdata::transaction::{Transaction, TxOut};
 -      use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::blockdata::opcodes;
        use bitcoin::network::constants::Network;
        use hex;
                // Now change the fee so we can check that the fee in the open_channel message is the
                // same as the old fee.
                fee_est.fee_est = 500;
 -              let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
 +              let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
                assert_eq!(open_channel_msg.feerate_per_kw, original_fee);
        }
  
  
                // Create Node B's channel by receiving Node A's open_channel message
                // Make sure A's dust limit is as we expect.
 -              let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
 +              let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
                let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false).unwrap();
  
                let seed = [42; 32];
                let network = Network::Testnet;
                let best_block = BestBlock::from_network(network);
 -              let chain_hash = best_block.block_hash();
 +              let chain_hash = ChainHash::using_genesis_block(network);
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
  
                // Go through the flow of opening a channel between two nodes.
                let chan_2_value_msat = chan_2.context.channel_value_satoshis * 1000;
                assert_eq!(chan_2.context.holder_max_htlc_value_in_flight_msat, (chan_2_value_msat as f64 * 0.99) as u64);
  
 -              let chan_1_open_channel_msg = chan_1.get_open_channel(genesis_block(network).header.block_hash());
 +              let chan_1_open_channel_msg = chan_1.get_open_channel(ChainHash::using_genesis_block(network));
  
                // Test that `InboundV1Channel::new` creates a channel with the correct value for
                // `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
                let expected_outbound_selected_chan_reserve = cmp::max(MIN_THEIR_CHAN_RESERVE_SATOSHIS, (chan.context.channel_value_satoshis as f64 * outbound_selected_channel_reserve_perc) as u64);
                assert_eq!(chan.context.holder_selected_channel_reserve_satoshis, expected_outbound_selected_chan_reserve);
  
 -              let chan_open_channel_msg = chan.get_open_channel(genesis_block(network).header.block_hash());
 +              let chan_open_channel_msg = chan.get_open_channel(ChainHash::using_genesis_block(network));
                let mut inbound_node_config = UserConfig::default();
                inbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (inbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
  
                let seed = [42; 32];
                let network = Network::Testnet;
                let best_block = BestBlock::from_network(network);
 -              let chain_hash = genesis_block(network).header.block_hash();
 +              let chain_hash = ChainHash::using_genesis_block(network);
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
  
                // Create Node A's channel pointing to Node B's pubkey
  
                // Create Node B's channel by receiving Node A's open_channel message
                // Make sure A's dust limit is as we expect.
 -              let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
 +              let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
                let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false).unwrap();
  
                use bitcoin::hashes::hex::FromHex;
                use bitcoin::hash_types::Txid;
                use bitcoin::secp256k1::Message;
-               use crate::sign::EcdsaChannelSigner;
+               use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, EcdsaChannelSigner};
                use crate::ln::PaymentPreimage;
                use crate::ln::channel::{HTLCOutputInCommitment ,TxCreationKeys};
                use crate::ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
                                        &chan.context.holder_signer.as_ref().pubkeys().funding_pubkey,
                                        chan.context.counterparty_funding_pubkey()
                                );
-                               let (holder_sig, htlc_sigs) = signer.sign_holder_commitment_and_htlcs(&holder_commitment_tx, &secp_ctx).unwrap();
+                               let holder_sig = signer.sign_holder_commitment(&holder_commitment_tx, &secp_ctx).unwrap();
                                assert_eq!(Signature::from_der(&hex::decode($sig_hex).unwrap()[..]).unwrap(), holder_sig, "holder_sig");
  
                                let funding_redeemscript = chan.context.get_funding_redeemscript();
                                assert_eq!(serialize(&tx)[..], hex::decode($tx_hex).unwrap()[..], "tx");
  
                                // ((htlc, counterparty_sig), (index, holder_sig))
-                               let mut htlc_sig_iter = holder_commitment_tx.htlcs().iter().zip(&holder_commitment_tx.counterparty_htlc_sigs).zip(htlc_sigs.iter().enumerate());
+                               let mut htlc_counterparty_sig_iter = holder_commitment_tx.counterparty_htlc_sigs.iter();
  
                                $({
                                        log_trace!(logger, "verifying htlc {}", $htlc_idx);
                                        let remote_signature = Signature::from_der(&hex::decode($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
  
                                        let ref htlc = htlcs[$htlc_idx];
-                                       let htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, chan.context.feerate_per_kw,
+                                       let mut htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, chan.context.feerate_per_kw,
                                                chan.context.get_counterparty_selected_contest_delay().unwrap(),
                                                &htlc, $opt_anchors, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
                                        let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, $opt_anchors, &keys);
                                                assert!(preimage.is_some());
                                        }
  
-                                       let htlc_sig = htlc_sig_iter.next().unwrap();
+                                       let htlc_counterparty_sig = htlc_counterparty_sig_iter.next().unwrap();
+                                       let htlc_holder_sig = signer.sign_holder_htlc_transaction(&htlc_tx, 0, &HTLCDescriptor {
+                                               channel_derivation_parameters: ChannelDerivationParameters {
+                                                       value_satoshis: chan.context.channel_value_satoshis,
+                                                       keys_id: chan.context.channel_keys_id,
+                                                       transaction_parameters: chan.context.channel_transaction_parameters.clone(),
+                                               },
+                                               commitment_txid: trusted_tx.txid(),
+                                               per_commitment_number: trusted_tx.commitment_number(),
+                                               per_commitment_point: trusted_tx.per_commitment_point(),
+                                               feerate_per_kw: trusted_tx.feerate_per_kw(),
+                                               htlc: htlc.clone(),
+                                               preimage: preimage.clone(),
+                                               counterparty_sig: *htlc_counterparty_sig,
+                                       }, &secp_ctx).unwrap();
                                        let num_anchors = if $opt_anchors.supports_anchors_zero_fee_htlc_tx() { 2 } else { 0 };
-                                       assert_eq!((htlc_sig.0).0.transaction_output_index, Some($htlc_idx + num_anchors), "output index");
+                                       assert_eq!(htlc.transaction_output_index, Some($htlc_idx + num_anchors), "output index");
  
                                        let signature = Signature::from_der(&hex::decode($htlc_sig_hex).unwrap()[..]).unwrap();
-                                       assert_eq!(signature, *(htlc_sig.1).1, "htlc sig");
-                                       let index = (htlc_sig.1).0;
-                                       let channel_parameters = chan.context.channel_transaction_parameters.as_holder_broadcastable();
+                                       assert_eq!(signature, htlc_holder_sig, "htlc sig");
                                        let trusted_tx = holder_commitment_tx.trust();
-                                       log_trace!(logger, "htlc_tx = {}", hex::encode(serialize(&trusted_tx.get_signed_htlc_tx(&channel_parameters, index, &(htlc_sig.0).1, (htlc_sig.1).1, &preimage))));
-                                       assert_eq!(serialize(&trusted_tx.get_signed_htlc_tx(&channel_parameters, index, &(htlc_sig.0).1, (htlc_sig.1).1, &preimage))[..],
-                                                       hex::decode($htlc_tx_hex).unwrap()[..], "htlc tx");
+                                       htlc_tx.input[0].witness = trusted_tx.build_htlc_input_witness($htlc_idx, htlc_counterparty_sig, &htlc_holder_sig, &preimage);
+                                       log_trace!(logger, "htlc_tx = {}", hex::encode(serialize(&htlc_tx)));
+                                       assert_eq!(serialize(&htlc_tx)[..], hex::decode($htlc_tx_hex).unwrap()[..], "htlc tx");
                                })*
-                               assert!(htlc_sig_iter.next().is_none());
+                               assert!(htlc_counterparty_sig_iter.next().is_none());
                        } }
                }
  
                let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key();
                channel_type_features.set_zero_conf_required();
  
 -              let mut open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
 +              let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
                open_channel_msg.channel_type = Some(channel_type_features);
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
                let res = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
                        &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
                ).unwrap();
  
 -              let open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
 +              let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
                let channel_b = InboundV1Channel::<&TestKeysInterface>::new(
                        &fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
                        &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config),
                ).unwrap();
  
                // Set `channel_type` to `None` to force the implicit feature negotiation.
 -              let mut open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
 +              let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
                open_channel_msg.channel_type = None;
  
                // Since A supports both `static_remote_key` and `option_anchors`, but B only accepts
                        &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42
                ).unwrap();
  
 -              let mut open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
 +              let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
                open_channel_msg.channel_type = Some(simple_anchors_channel_type.clone());
  
                let res = InboundV1Channel::<&TestKeysInterface>::new(
                        10000000, 100000, 42, &config, 0, 42
                ).unwrap();
  
 -              let open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash());
 +              let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
  
                let channel_b = InboundV1Channel::<&TestKeysInterface>::new(
                        &fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
                let seed = [42; 32];
                let network = Network::Testnet;
                let best_block = BestBlock::from_network(network);
 -              let chain_hash = genesis_block(network).header.block_hash();
 +              let chain_hash = ChainHash::using_genesis_block(network);
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
  
                let mut config = UserConfig::default();
                        42,
                ).unwrap();
  
 -              let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
 +              let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
                let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(
                        &feeest,
index dcc0d57409bbd7abc4a5abae8a4970f8ea1c0de7,37fdc647a4cc8f3373e80e0cc330e93ffaa1fa34..60caed4dbdc8c0fe4974137a233bc733e8886603
@@@ -1400,7 -1400,7 +1400,7 @@@ fn do_test_revoked_counterparty_htlc_tx
  
        // Create some initial channels
        let (_, _, chan_id, funding_tx) =
 -              create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 11_000_000);
 +              create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 12_000_000);
        let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
        assert_eq!(funding_outpoint.to_channel_id(), chan_id);
  
        assert_eq!(revoked_local_txn[0].input.len(), 1);
        assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, funding_tx.txid());
        if anchors {
 -              assert_eq!(revoked_local_txn[0].output[4].value, 10000); // to_self output
 +              assert_eq!(revoked_local_txn[0].output[4].value, 11000); // to_self output
        } else {
 -              assert_eq!(revoked_local_txn[0].output[2].value, 10000); // to_self output
 +              assert_eq!(revoked_local_txn[0].output[2].value, 11000); // to_self output
        }
  
        // The to-be-revoked commitment tx should have two HTLCs, an output for each side, and an
        let anchor_outputs_value = if anchors { channel::ANCHOR_OUTPUT_VALUE_SATOSHI * 2 } else { 0 };
        let as_balances = sorted_vec(vec![Balance::ClaimableAwaitingConfirmations {
                        // to_remote output in B's revoked commitment
 -                      amount_satoshis: 1_000_000 - 11_000 - 3_000 - commitment_tx_fee - anchor_outputs_value,
 +                      amount_satoshis: 1_000_000 - 12_000 - 3_000 - commitment_tx_fee - anchor_outputs_value,
                        confirmation_height: to_remote_conf_height,
                }, Balance::CounterpartyRevokedOutputClaimable {
                        // to_self output in B's revoked commitment
 -                      amount_satoshis: 10_000,
 +                      amount_satoshis: 11_000,
                }, Balance::CounterpartyRevokedOutputClaimable { // HTLC 1
                        amount_satoshis: 3_000,
                }, Balance::CounterpartyRevokedOutputClaimable { // HTLC 2
        mine_transaction(&nodes[0], &as_htlc_claim_tx[0]);
        assert_eq!(sorted_vec(vec![Balance::ClaimableAwaitingConfirmations {
                        // to_remote output in B's revoked commitment
 -                      amount_satoshis: 1_000_000 - 11_000 - 3_000 - commitment_tx_fee - anchor_outputs_value,
 +                      amount_satoshis: 1_000_000 - 12_000 - 3_000 - commitment_tx_fee - anchor_outputs_value,
                        confirmation_height: to_remote_conf_height,
                }, Balance::CounterpartyRevokedOutputClaimable {
                        // to_self output in B's revoked commitment
 -                      amount_satoshis: 10_000,
 +                      amount_satoshis: 11_000,
                }, Balance::CounterpartyRevokedOutputClaimable { // HTLC 2
                        amount_satoshis: 1_000,
                }, Balance::ClaimableAwaitingConfirmations {
        test_spendable_output(&nodes[0], &revoked_local_txn[0], false);
        assert_eq!(sorted_vec(vec![Balance::CounterpartyRevokedOutputClaimable {
                        // to_self output to B
 -                      amount_satoshis: 10_000,
 +                      amount_satoshis: 11_000,
                }, Balance::CounterpartyRevokedOutputClaimable { // HTLC 2
                        amount_satoshis: 1_000,
                }, Balance::ClaimableAwaitingConfirmations {
        test_spendable_output(&nodes[0], &as_htlc_claim_tx[0], false);
        assert_eq!(sorted_vec(vec![Balance::CounterpartyRevokedOutputClaimable {
                        // to_self output in B's revoked commitment
 -                      amount_satoshis: 10_000,
 +                      amount_satoshis: 11_000,
                }, Balance::CounterpartyRevokedOutputClaimable { // HTLC 2
                        amount_satoshis: 1_000,
                }]),
        connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
        assert_eq!(sorted_vec(vec![Balance::CounterpartyRevokedOutputClaimable {
                        // to_self output in B's revoked commitment
 -                      amount_satoshis: 10_000,
 +                      amount_satoshis: 11_000,
                }, Balance::CounterpartyRevokedOutputClaimable { // HTLC 2
                        amount_satoshis: 1_000,
                }]),
        mine_transaction(&nodes[0], &revoked_htlc_timeout_claim);
        assert_eq!(sorted_vec(vec![Balance::CounterpartyRevokedOutputClaimable {
                        // to_self output in B's revoked commitment
 -                      amount_satoshis: 10_000,
 +                      amount_satoshis: 11_000,
                }, Balance::ClaimableAwaitingConfirmations {
                        amount_satoshis: revoked_htlc_timeout_claim.output[0].value,
                        confirmation_height: nodes[0].best_block_info().1 + ANTI_REORG_DELAY - 1,
@@@ -1680,7 -1680,7 +1680,7 @@@ fn do_test_revoked_counterparty_aggrega
        // secret to the counterparty. However, because we always immediately take the revocation
        // secret from the keys_manager, we would panic at broadcast as we're trying to sign a
        // transaction which, from the point of view of our keys_manager, is revoked.
-       chanmon_cfgs[1].keys_manager.disable_revocation_policy_check = true;
+       chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true;
        let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
        let mut user_config = test_default_channel_config();
        if anchors {
@@@ -2715,3 -2715,113 +2715,113 @@@ fn test_anchors_monitor_fixes_counterpa
        do_test_anchors_monitor_fixes_counterparty_payment_script_on_reload(false);
        do_test_anchors_monitor_fixes_counterparty_payment_script_on_reload(true);
  }
+ #[cfg(not(feature = "_test_vectors"))]
+ fn do_test_monitor_claims_with_random_signatures(anchors: bool, confirm_counterparty_commitment: bool) {
+       // Tests that our monitor claims will always use fresh random signatures (ensuring a unique
+       // wtxid) to prevent certain classes of transaction replacement at the bitcoin P2P layer.
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let mut user_config = test_default_channel_config();
+       if anchors {
+               user_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
+               user_config.manually_accept_inbound_channels = true;
+       }
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(user_config), Some(user_config)]);
+       let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+       let coinbase_tx = Transaction {
+               version: 2,
+               lock_time: PackedLockTime::ZERO,
+               input: vec![TxIn { ..Default::default() }],
+               output: vec![
+                       TxOut {
+                               value: Amount::ONE_BTC.to_sat(),
+                               script_pubkey: nodes[0].wallet_source.get_change_script().unwrap(),
+                       },
+               ],
+       };
+       if anchors {
+               nodes[0].wallet_source.add_utxo(bitcoin::OutPoint { txid: coinbase_tx.txid(), vout: 0 }, coinbase_tx.output[0].value);
+       }
+       // Open a channel and route a payment. We'll let it timeout to claim it.
+       let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
+       route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
+       let (closing_node, other_node) = if confirm_counterparty_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();
+       // The commitment transaction comes first.
+       let commitment_tx = {
+               let mut txn = closing_node.tx_broadcaster.unique_txn_broadcast();
+               assert_eq!(txn.len(), 1);
+               check_spends!(txn[0], funding_tx);
+               txn.pop().unwrap()
+       };
+       mine_transaction(closing_node, &commitment_tx);
+       check_added_monitors!(closing_node, 1);
+       check_closed_broadcast!(closing_node, true);
+       check_closed_event!(closing_node, 1, ClosureReason::HolderForceClosed, [other_node.node.get_our_node_id()], 1_000_000);
+       mine_transaction(other_node, &commitment_tx);
+       check_added_monitors!(other_node, 1);
+       check_closed_broadcast!(other_node, true);
+       check_closed_event!(other_node, 1, ClosureReason::CommitmentTxConfirmed, [closing_node.node.get_our_node_id()], 1_000_000);
+       // If we update the best block to the new height before providing the confirmed transactions,
+       // we'll see another broadcast of the commitment transaction.
+       if anchors && !confirm_counterparty_commitment && nodes[0].connect_style.borrow().updates_best_block_first() {
+               let _ = nodes[0].tx_broadcaster.txn_broadcast();
+       }
+       // Then comes the HTLC timeout transaction.
+       if confirm_counterparty_commitment {
+               connect_blocks(&nodes[0], 5);
+               test_spendable_output(&nodes[0], &commitment_tx, false);
+               connect_blocks(&nodes[0], TEST_FINAL_CLTV - 5);
+       } else {
+               connect_blocks(&nodes[0], TEST_FINAL_CLTV);
+       }
+       if anchors && !confirm_counterparty_commitment {
+               handle_bump_htlc_event(&nodes[0], 1);
+       }
+       let htlc_timeout_tx = {
+               let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
+               assert_eq!(txn.len(), 1);
+               let tx = if txn[0].input[0].previous_output.txid == commitment_tx.txid() {
+                       txn[0].clone()
+               } else {
+                       txn[1].clone()
+               };
+               check_spends!(tx, commitment_tx, coinbase_tx);
+               tx
+       };
+       // Check we rebroadcast it with a different wtxid.
+       nodes[0].chain_monitor.chain_monitor.rebroadcast_pending_claims();
+       if anchors && !confirm_counterparty_commitment {
+               handle_bump_htlc_event(&nodes[0], 1);
+       }
+       {
+               let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
+               assert_eq!(txn.len(), 1);
+               assert_eq!(txn[0].txid(), htlc_timeout_tx.txid());
+               assert_ne!(txn[0].wtxid(), htlc_timeout_tx.wtxid());
+       }
+ }
+ #[cfg(not(feature = "_test_vectors"))]
+ #[test]
+ fn test_monitor_claims_with_random_signatures() {
+       do_test_monitor_claims_with_random_signatures(false, false);
+       do_test_monitor_claims_with_random_signatures(false, true);
+       do_test_monitor_claims_with_random_signatures(true, false);
+       do_test_monitor_claims_with_random_signatures(true, true);
+ }