Support future removal of redundant per-HTLC data in `ChanMonUpd`s
[rust-lightning] / lightning / src / chain / channelmonitor.rs
index cc88a0119fc95cf972680e7fcb4e5eb63495130c..66ab16911146e1e2c7cd09a8c0b3f3b0b6ac4664 100644 (file)
@@ -37,30 +37,30 @@ use crate::ln::{PaymentHash, PaymentPreimage};
 use crate::ln::msgs::DecodeError;
 use crate::ln::chan_utils;
 use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction};
-use crate::ln::channelmanager::HTLCSource;
+use crate::ln::channelmanager::{HTLCSource, SentHTLCId};
 use crate::chain;
 use crate::chain::{BestBlock, WatchedOutput};
 use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
 use crate::chain::transaction::{OutPoint, TransactionData};
-use crate::chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, Sign, KeysInterface};
+use crate::chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
 #[cfg(anchors)]
 use crate::chain::onchaintx::ClaimEvent;
 use crate::chain::onchaintx::OnchainTxHandler;
 use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
 use crate::chain::Filter;
 use crate::util::logger::Logger;
-use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48, OptionDeserWrapper};
+use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48};
 use crate::util::byte_utils;
 use crate::util::events::Event;
 #[cfg(anchors)]
-use crate::util::events::{AnchorDescriptor, BumpTransactionEvent};
+use crate::util::events::{AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent};
 
 use crate::prelude::*;
 use core::{cmp, mem};
 use crate::io::{self, Error};
 use core::convert::TryInto;
 use core::ops::Deref;
-use crate::sync::Mutex;
+use crate::sync::{Mutex, LockTestExt};
 
 /// An update generated by the underlying channel itself which contains some new information the
 /// [`ChannelMonitor`] should be made aware of.
@@ -291,7 +291,7 @@ struct CounterpartyCommitmentParameters {
 
 impl Writeable for CounterpartyCommitmentParameters {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               w.write_all(&byte_utils::be64_to_array(0))?;
+               w.write_all(&(0 as u64).to_be_bytes())?;
                write_tlv_fields!(w, {
                        (0, self.counterparty_delayed_payment_base_key, required),
                        (2, self.counterparty_htlc_base_key, required),
@@ -314,8 +314,8 @@ impl Readable for CounterpartyCommitmentParameters {
                                }
                        }
 
-                       let mut counterparty_delayed_payment_base_key = OptionDeserWrapper(None);
-                       let mut counterparty_htlc_base_key = OptionDeserWrapper(None);
+                       let mut counterparty_delayed_payment_base_key = RequiredWrapper(None);
+                       let mut counterparty_htlc_base_key = RequiredWrapper(None);
                        let mut on_counterparty_tx_csv: u16 = 0;
                        read_tlv_fields!(r, {
                                (0, counterparty_delayed_payment_base_key, required),
@@ -454,19 +454,15 @@ impl MaybeReadable for OnchainEventEntry {
                let mut transaction = None;
                let mut block_hash = None;
                let mut height = 0;
-               let mut event = None;
+               let mut event = UpgradableRequired(None);
                read_tlv_fields!(reader, {
                        (0, txid, required),
                        (1, transaction, option),
                        (2, height, required),
                        (3, block_hash, option),
-                       (4, event, ignorable),
+                       (4, event, upgradable_required),
                });
-               if let Some(ev) = event {
-                       Ok(Some(Self { txid, transaction, height, block_hash, event: ev }))
-               } else {
-                       Ok(None)
-               }
+               Ok(Some(Self { txid, transaction, height, block_hash, event: _init_tlv_based_struct_field!(event, upgradable_required) }))
        }
 }
 
@@ -497,7 +493,12 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
 pub(crate) enum ChannelMonitorUpdateStep {
        LatestHolderCommitmentTXInfo {
                commitment_tx: HolderCommitmentTransaction,
+               /// Note that LDK after 0.0.115 supports this only containing dust HTLCs (implying the
+               /// `Signature` field is never filled in). At that point, non-dust HTLCs are implied by the
+               /// HTLC fields in `commitment_tx` and the sources passed via `nondust_htlc_sources`.
                htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
+               claimed_htlcs: Vec<(SentHTLCId, PaymentPreimage)>,
+               nondust_htlc_sources: Vec<HTLCSource>,
        },
        LatestCounterpartyCommitmentTXInfo {
                commitment_txid: Txid,
@@ -540,7 +541,9 @@ impl ChannelMonitorUpdateStep {
 impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
        (0, LatestHolderCommitmentTXInfo) => {
                (0, commitment_tx, required),
+               (1, claimed_htlcs, vec_type),
                (2, htlc_outputs, vec_type),
+               (4, nondust_htlc_sources, optional_vec),
        },
        (1, LatestCounterpartyCommitmentTXInfo) => {
                (0, commitment_txid, required),
@@ -647,6 +650,7 @@ struct IrrevocablyResolvedHTLC {
        /// was not present in the confirmed commitment transaction), HTLC-Success, or HTLC-Timeout
        /// transaction.
        resolving_txid: Option<Txid>, // Added as optional, but always filled in, in 0.0.110
+       resolving_tx: Option<Transaction>,
        /// Only set if the HTLC claim was ours using a payment preimage
        payment_preimage: Option<PaymentPreimage>,
 }
@@ -662,6 +666,7 @@ impl Writeable for IrrevocablyResolvedHTLC {
                        (0, mapped_commitment_tx_output_idx, required),
                        (1, self.resolving_txid, option),
                        (2, self.payment_preimage, option),
+                       (3, self.resolving_tx, option),
                });
                Ok(())
        }
@@ -672,15 +677,18 @@ impl Readable for IrrevocablyResolvedHTLC {
                let mut mapped_commitment_tx_output_idx = 0;
                let mut resolving_txid = None;
                let mut payment_preimage = None;
+               let mut resolving_tx = None;
                read_tlv_fields!(reader, {
                        (0, mapped_commitment_tx_output_idx, required),
                        (1, resolving_txid, option),
                        (2, payment_preimage, option),
+                       (3, resolving_tx, option),
                });
                Ok(Self {
                        commitment_tx_output_idx: if mapped_commitment_tx_output_idx == u32::max_value() { None } else { Some(mapped_commitment_tx_output_idx) },
                        resolving_txid,
                        payment_preimage,
+                       resolving_tx,
                })
        }
 }
@@ -701,14 +709,15 @@ impl Readable for IrrevocablyResolvedHTLC {
 /// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
 /// returned block hash and the the current chain and then reconnecting blocks to get to the
 /// best chain) upon deserializing the object!
-pub struct ChannelMonitor<Signer: Sign> {
+pub struct ChannelMonitor<Signer: WriteableEcdsaChannelSigner> {
        #[cfg(test)]
        pub(crate) inner: Mutex<ChannelMonitorImpl<Signer>>,
        #[cfg(not(test))]
        inner: Mutex<ChannelMonitorImpl<Signer>>,
 }
 
-pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
+#[derive(PartialEq)]
+pub(crate) struct ChannelMonitorImpl<Signer: WriteableEcdsaChannelSigner> {
        latest_update_id: u64,
        commitment_transaction_number_obscure_factor: u64,
 
@@ -748,6 +757,8 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
        /// Serialized to disk but should generally not be sent to Watchtowers.
        counterparty_hash_commitment_number: HashMap<PaymentHash, u64>,
 
+       counterparty_fulfilled_htlcs: HashMap<SentHTLCId, PaymentPreimage>,
+
        // We store two holder commitment transactions to avoid any race conditions where we may update
        // some monitors (potentially on watchtowers) but then fail to update others, resulting in the
        // various monitors for one channel being out of sync, and us broadcasting a holder
@@ -842,72 +853,24 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
 
        /// The node_id of our counterparty
        counterparty_node_id: Option<PublicKey>,
-
-       secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
 }
 
 /// Transaction outputs to watch for on-chain spends.
 pub type TransactionOutputs = (Txid, Vec<(u32, TxOut)>);
 
-#[cfg(any(test, fuzzing, feature = "_test_utils"))]
-/// Used only in testing and fuzzing to check serialization roundtrips don't change the underlying
-/// object
-impl<Signer: Sign> PartialEq for ChannelMonitor<Signer> {
-       fn eq(&self, other: &Self) -> bool {
-               let inner = self.inner.lock().unwrap();
-               let other = other.inner.lock().unwrap();
-               inner.eq(&other)
-       }
-}
-
-#[cfg(any(test, fuzzing, feature = "_test_utils"))]
-/// Used only in testing and fuzzing to check serialization roundtrips don't change the underlying
-/// object
-impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> PartialEq for ChannelMonitor<Signer> where Signer: PartialEq {
        fn eq(&self, other: &Self) -> bool {
-               if self.latest_update_id != other.latest_update_id ||
-                       self.commitment_transaction_number_obscure_factor != other.commitment_transaction_number_obscure_factor ||
-                       self.destination_script != other.destination_script ||
-                       self.broadcasted_holder_revokable_script != other.broadcasted_holder_revokable_script ||
-                       self.counterparty_payment_script != other.counterparty_payment_script ||
-                       self.channel_keys_id != other.channel_keys_id ||
-                       self.holder_revocation_basepoint != other.holder_revocation_basepoint ||
-                       self.funding_info != other.funding_info ||
-                       self.current_counterparty_commitment_txid != other.current_counterparty_commitment_txid ||
-                       self.prev_counterparty_commitment_txid != other.prev_counterparty_commitment_txid ||
-                       self.counterparty_commitment_params != other.counterparty_commitment_params ||
-                       self.funding_redeemscript != other.funding_redeemscript ||
-                       self.channel_value_satoshis != other.channel_value_satoshis ||
-                       self.their_cur_per_commitment_points != other.their_cur_per_commitment_points ||
-                       self.on_holder_tx_csv != other.on_holder_tx_csv ||
-                       self.commitment_secrets != other.commitment_secrets ||
-                       self.counterparty_claimable_outpoints != other.counterparty_claimable_outpoints ||
-                       self.counterparty_commitment_txn_on_chain != other.counterparty_commitment_txn_on_chain ||
-                       self.counterparty_hash_commitment_number != other.counterparty_hash_commitment_number ||
-                       self.prev_holder_signed_commitment_tx != other.prev_holder_signed_commitment_tx ||
-                       self.current_counterparty_commitment_number != other.current_counterparty_commitment_number ||
-                       self.current_holder_commitment_number != other.current_holder_commitment_number ||
-                       self.current_holder_commitment_tx != other.current_holder_commitment_tx ||
-                       self.payment_preimages != other.payment_preimages ||
-                       self.pending_monitor_events != other.pending_monitor_events ||
-                       self.pending_events.len() != other.pending_events.len() || // We trust events to round-trip properly
-                       self.onchain_events_awaiting_threshold_conf != other.onchain_events_awaiting_threshold_conf ||
-                       self.outputs_to_watch != other.outputs_to_watch ||
-                       self.lockdown_from_offchain != other.lockdown_from_offchain ||
-                       self.holder_tx_signed != other.holder_tx_signed ||
-                       self.funding_spend_seen != other.funding_spend_seen ||
-                       self.funding_spend_confirmed != other.funding_spend_confirmed ||
-                       self.confirmed_commitment_tx_counterparty_output != other.confirmed_commitment_tx_counterparty_output ||
-                       self.htlcs_resolved_on_chain != other.htlcs_resolved_on_chain
-               {
-                       false
-               } else {
-                       true
-               }
+               // We need some kind of total lockorder. Absent a better idea, we sort by position in
+               // memory and take locks in that order (assuming that we can't move within memory while a
+               // lock is held).
+               let ord = ((self as *const _) as usize) < ((other as *const _) as usize);
+               let a = if ord { self.inner.unsafe_well_ordered_double_lock_self() } else { other.inner.unsafe_well_ordered_double_lock_self() };
+               let b = if ord { other.inner.unsafe_well_ordered_double_lock_self() } else { self.inner.unsafe_well_ordered_double_lock_self() };
+               a.eq(&b)
        }
 }
 
-impl<Signer: Sign> Writeable for ChannelMonitor<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitor<Signer> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
                self.inner.lock().unwrap().write(writer)
        }
@@ -917,7 +880,7 @@ impl<Signer: Sign> Writeable for ChannelMonitor<Signer> {
 const SERIALIZATION_VERSION: u8 = 1;
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
-impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
                write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
 
@@ -945,7 +908,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                self.channel_keys_id.write(writer)?;
                self.holder_revocation_basepoint.write(writer)?;
                writer.write_all(&self.funding_info.0.txid[..])?;
-               writer.write_all(&byte_utils::be16_to_array(self.funding_info.0.index))?;
+               writer.write_all(&self.funding_info.0.index.to_be_bytes())?;
                self.funding_info.1.write(writer)?;
                self.current_counterparty_commitment_txid.write(writer)?;
                self.prev_counterparty_commitment_txid.write(writer)?;
@@ -972,24 +935,24 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                        },
                }
 
-               writer.write_all(&byte_utils::be16_to_array(self.on_holder_tx_csv))?;
+               writer.write_all(&self.on_holder_tx_csv.to_be_bytes())?;
 
                self.commitment_secrets.write(writer)?;
 
                macro_rules! serialize_htlc_in_commitment {
                        ($htlc_output: expr) => {
                                writer.write_all(&[$htlc_output.offered as u8; 1])?;
-                               writer.write_all(&byte_utils::be64_to_array($htlc_output.amount_msat))?;
-                               writer.write_all(&byte_utils::be32_to_array($htlc_output.cltv_expiry))?;
+                               writer.write_all(&$htlc_output.amount_msat.to_be_bytes())?;
+                               writer.write_all(&$htlc_output.cltv_expiry.to_be_bytes())?;
                                writer.write_all(&$htlc_output.payment_hash.0[..])?;
                                $htlc_output.transaction_output_index.write(writer)?;
                        }
                }
 
-               writer.write_all(&byte_utils::be64_to_array(self.counterparty_claimable_outpoints.len() as u64))?;
+               writer.write_all(&(self.counterparty_claimable_outpoints.len() as u64).to_be_bytes())?;
                for (ref txid, ref htlc_infos) in self.counterparty_claimable_outpoints.iter() {
                        writer.write_all(&txid[..])?;
-                       writer.write_all(&byte_utils::be64_to_array(htlc_infos.len() as u64))?;
+                       writer.write_all(&(htlc_infos.len() as u64).to_be_bytes())?;
                        for &(ref htlc_output, ref htlc_source) in htlc_infos.iter() {
                                debug_assert!(htlc_source.is_none() || Some(**txid) == self.current_counterparty_commitment_txid
                                                || Some(**txid) == self.prev_counterparty_commitment_txid,
@@ -999,13 +962,13 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                        }
                }
 
-               writer.write_all(&byte_utils::be64_to_array(self.counterparty_commitment_txn_on_chain.len() as u64))?;
+               writer.write_all(&(self.counterparty_commitment_txn_on_chain.len() as u64).to_be_bytes())?;
                for (ref txid, commitment_number) in self.counterparty_commitment_txn_on_chain.iter() {
                        writer.write_all(&txid[..])?;
                        writer.write_all(&byte_utils::be48_to_array(*commitment_number))?;
                }
 
-               writer.write_all(&byte_utils::be64_to_array(self.counterparty_hash_commitment_number.len() as u64))?;
+               writer.write_all(&(self.counterparty_hash_commitment_number.len() as u64).to_be_bytes())?;
                for (ref payment_hash, commitment_number) in self.counterparty_hash_commitment_number.iter() {
                        writer.write_all(&payment_hash.0[..])?;
                        writer.write_all(&byte_utils::be48_to_array(*commitment_number))?;
@@ -1023,7 +986,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                writer.write_all(&byte_utils::be48_to_array(self.current_counterparty_commitment_number))?;
                writer.write_all(&byte_utils::be48_to_array(self.current_holder_commitment_number))?;
 
-               writer.write_all(&byte_utils::be64_to_array(self.payment_preimages.len() as u64))?;
+               writer.write_all(&(self.payment_preimages.len() as u64).to_be_bytes())?;
                for payment_preimage in self.payment_preimages.values() {
                        writer.write_all(&payment_preimage.0[..])?;
                }
@@ -1044,15 +1007,15 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                        }
                }
 
-               writer.write_all(&byte_utils::be64_to_array(self.pending_events.len() as u64))?;
+               writer.write_all(&(self.pending_events.len() as u64).to_be_bytes())?;
                for event in self.pending_events.iter() {
                        event.write(writer)?;
                }
 
                self.best_block.block_hash().write(writer)?;
-               writer.write_all(&byte_utils::be32_to_array(self.best_block.height()))?;
+               writer.write_all(&self.best_block.height().to_be_bytes())?;
 
-               writer.write_all(&byte_utils::be64_to_array(self.onchain_events_awaiting_threshold_conf.len() as u64))?;
+               writer.write_all(&(self.onchain_events_awaiting_threshold_conf.len() as u64).to_be_bytes())?;
                for ref entry in self.onchain_events_awaiting_threshold_conf.iter() {
                        entry.write(writer)?;
                }
@@ -1079,13 +1042,14 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                        (9, self.counterparty_node_id, option),
                        (11, self.confirmed_commitment_tx_counterparty_output, option),
                        (13, self.spendable_txids_confirmed, vec_type),
+                       (15, self.counterparty_fulfilled_htlcs, required),
                });
 
                Ok(())
        }
 }
 
-impl<Signer: Sign> ChannelMonitor<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
        /// For lockorder enforcement purposes, we need to have a single site which constructs the
        /// `inner` mutex, otherwise cases where we lock two monitors at the same time (eg in our
        /// PartialEq implementation) we may decide a lockorder violation has occurred.
@@ -1135,7 +1099,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
 
                let onchain_tx_handler =
                        OnchainTxHandler::new(destination_script.clone(), keys,
-                       channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx.clone());
+                       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())]);
@@ -1166,6 +1130,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                        counterparty_claimable_outpoints: HashMap::new(),
                        counterparty_commitment_txn_on_chain: HashMap::new(),
                        counterparty_hash_commitment_number: HashMap::new(),
+                       counterparty_fulfilled_htlcs: HashMap::new(),
 
                        prev_holder_signed_commitment_tx: None,
                        current_holder_commitment_tx: holder_commitment_tx,
@@ -1191,8 +1156,6 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
 
                        best_block,
                        counterparty_node_id: Some(counterparty_node_id),
-
-                       secp_ctx,
                })
        }
 
@@ -1222,7 +1185,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                &self, holder_commitment_tx: HolderCommitmentTransaction,
                htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
        ) -> Result<(), ()> {
-               self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs).map_err(|_| ())
+               self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs, &Vec::new(), Vec::new()).map_err(|_| ())
        }
 
        /// This is used to provide payment preimage(s) out-of-band during startup without updating the
@@ -1516,7 +1479,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
        }
 }
 
-impl<Signer: Sign> ChannelMonitorImpl<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
        /// Helper for get_claimable_balances which does the work for an individual HTLC, generating up
        /// to one `Balance` for the HTLC.
        fn get_htlc_balance(&self, htlc: &HTLCOutputInCommitment, holder_commitment: bool,
@@ -1526,6 +1489,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        if let Some(v) = htlc.transaction_output_index { v } else { return None; };
 
                let mut htlc_spend_txid_opt = None;
+               let mut htlc_spend_tx_opt = None;
                let mut holder_timeout_spend_pending = None;
                let mut htlc_spend_pending = None;
                let mut holder_delayed_output_pending = None;
@@ -1534,7 +1498,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                OnchainEvent::HTLCUpdate { commitment_tx_output_idx, htlc_value_satoshis, .. }
                                if commitment_tx_output_idx == Some(htlc_commitment_tx_output_idx) => {
                                        debug_assert!(htlc_spend_txid_opt.is_none());
-                                       htlc_spend_txid_opt = event.transaction.as_ref().map(|tx| tx.txid());
+                                       htlc_spend_txid_opt = Some(&event.txid);
+                                       debug_assert!(htlc_spend_tx_opt.is_none());
+                                       htlc_spend_tx_opt = event.transaction.as_ref();
                                        debug_assert!(holder_timeout_spend_pending.is_none());
                                        debug_assert_eq!(htlc_value_satoshis.unwrap(), htlc.amount_msat / 1000);
                                        holder_timeout_spend_pending = Some(event.confirmation_threshold());
@@ -1542,7 +1508,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. }
                                if commitment_tx_output_idx == htlc_commitment_tx_output_idx => {
                                        debug_assert!(htlc_spend_txid_opt.is_none());
-                                       htlc_spend_txid_opt = event.transaction.as_ref().map(|tx| tx.txid());
+                                       htlc_spend_txid_opt = Some(&event.txid);
+                                       debug_assert!(htlc_spend_tx_opt.is_none());
+                                       htlc_spend_tx_opt = event.transaction.as_ref();
                                        debug_assert!(htlc_spend_pending.is_none());
                                        htlc_spend_pending = Some((event.confirmation_threshold(), preimage.is_some()));
                                },
@@ -1558,19 +1526,32 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                let htlc_resolved = self.htlcs_resolved_on_chain.iter()
                        .find(|v| if v.commitment_tx_output_idx == Some(htlc_commitment_tx_output_idx) {
                                debug_assert!(htlc_spend_txid_opt.is_none());
-                               htlc_spend_txid_opt = v.resolving_txid;
+                               htlc_spend_txid_opt = v.resolving_txid.as_ref();
+                               debug_assert!(htlc_spend_tx_opt.is_none());
+                               htlc_spend_tx_opt = v.resolving_tx.as_ref();
                                true
                        } else { false });
                debug_assert!(holder_timeout_spend_pending.is_some() as u8 + htlc_spend_pending.is_some() as u8 + htlc_resolved.is_some() as u8 <= 1);
 
+               let htlc_commitment_outpoint = BitcoinOutPoint::new(confirmed_txid.unwrap(), htlc_commitment_tx_output_idx);
                let htlc_output_to_spend =
                        if let Some(txid) = htlc_spend_txid_opt {
-                               debug_assert!(
-                                       self.onchain_tx_handler.channel_transaction_parameters.opt_anchors.is_none(),
-                                       "This code needs updating for anchors");
-                               BitcoinOutPoint::new(txid, 0)
+                               // Because HTLC transactions either only have 1 input and 1 output (pre-anchors) or
+                               // are signed with SIGHASH_SINGLE|ANYONECANPAY under BIP-0143 (post-anchors), we can
+                               // locate the correct output by ensuring its adjacent input spends the HTLC output
+                               // in the commitment.
+                               if let Some(ref tx) = htlc_spend_tx_opt {
+                                       let htlc_input_idx_opt = tx.input.iter().enumerate()
+                                               .find(|(_, input)| input.previous_output == htlc_commitment_outpoint)
+                                               .map(|(idx, _)| idx as u32);
+                                       debug_assert!(htlc_input_idx_opt.is_some());
+                                       BitcoinOutPoint::new(*txid, htlc_input_idx_opt.unwrap_or(0))
+                               } else {
+                                       debug_assert!(!self.onchain_tx_handler.opt_anchors());
+                                       BitcoinOutPoint::new(*txid, 0)
+                               }
                        } else {
-                               BitcoinOutPoint::new(confirmed_txid.unwrap(), htlc_commitment_tx_output_idx)
+                               htlc_commitment_outpoint
                        };
                let htlc_output_spend_pending = self.onchain_tx_handler.is_output_spend_pending(&htlc_output_to_spend);
 
@@ -1594,8 +1575,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                } = &event.event {
                                        if event.transaction.as_ref().map(|tx| tx.input.iter().any(|inp| {
                                                if let Some(htlc_spend_txid) = htlc_spend_txid_opt {
-                                                       Some(tx.txid()) == htlc_spend_txid_opt ||
-                                                               inp.previous_output.txid == htlc_spend_txid
+                                                       tx.txid() == *htlc_spend_txid || inp.previous_output.txid == *htlc_spend_txid
                                                } else {
                                                        Some(inp.previous_output.txid) == confirmed_txid &&
                                                                inp.previous_output.vout == htlc_commitment_tx_output_idx
@@ -1662,7 +1642,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        }
 }
 
-impl<Signer: Sign> ChannelMonitor<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
        /// Gets the balances in this channel which are either claimable by us if we were to
        /// force-close the channel now or which are claimable on-chain (possibly awaiting
        /// confirmation).
@@ -1837,12 +1817,67 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                res
        }
 
-       /// Gets the set of outbound HTLCs which are pending resolution in this channel.
-       /// This is used to reconstruct pending outbound payments on restart in the ChannelManager.
-       pub(crate) fn get_pending_outbound_htlcs(&self) -> HashMap<HTLCSource, HTLCOutputInCommitment> {
+       /// Gets the set of outbound HTLCs which can be (or have been) resolved by this
+       /// `ChannelMonitor`. This is used to determine if an HTLC was removed from the channel prior
+       /// to the `ChannelManager` having been persisted.
+       ///
+       /// This is similar to [`Self::get_pending_or_resolved_outbound_htlcs`] except it includes
+       /// HTLCs which were resolved on-chain (i.e. where the final HTLC resolution was done by an
+       /// event from this `ChannelMonitor`).
+       pub(crate) fn get_all_current_outbound_htlcs(&self) -> HashMap<HTLCSource, (HTLCOutputInCommitment, Option<PaymentPreimage>)> {
                let mut res = HashMap::new();
+               // Just examine the available counterparty commitment transactions. See docs on
+               // `fail_unbroadcast_htlcs`, below, for justification.
                let us = self.inner.lock().unwrap();
+               macro_rules! walk_counterparty_commitment {
+                       ($txid: expr) => {
+                               if let Some(ref latest_outpoints) = us.counterparty_claimable_outpoints.get($txid) {
+                                       for &(ref htlc, ref source_option) in latest_outpoints.iter() {
+                                               if let &Some(ref source) = source_option {
+                                                       res.insert((**source).clone(), (htlc.clone(),
+                                                               us.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).cloned()));
+                                               }
+                                       }
+                               }
+                       }
+               }
+               if let Some(ref txid) = us.current_counterparty_commitment_txid {
+                       walk_counterparty_commitment!(txid);
+               }
+               if let Some(ref txid) = us.prev_counterparty_commitment_txid {
+                       walk_counterparty_commitment!(txid);
+               }
+               res
+       }
 
+       /// Gets the set of outbound HTLCs which are pending resolution in this channel or which were
+       /// resolved with a preimage from our counterparty.
+       ///
+       /// This is used to reconstruct pending outbound payments on restart in the ChannelManager.
+       ///
+       /// Currently, the preimage is unused, however if it is present in the relevant internal state
+       /// an HTLC is always included even if it has been resolved.
+       pub(crate) fn get_pending_or_resolved_outbound_htlcs(&self) -> HashMap<HTLCSource, (HTLCOutputInCommitment, Option<PaymentPreimage>)> {
+               let us = self.inner.lock().unwrap();
+               // We're only concerned with the confirmation count of HTLC transactions, and don't
+               // actually care how many confirmations a commitment transaction may or may not have. Thus,
+               // we look for either a FundingSpendConfirmation event or a funding_spend_confirmed.
+               let confirmed_txid = us.funding_spend_confirmed.or_else(|| {
+                       us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
+                               if let OnchainEvent::FundingSpendConfirmation { .. } = event.event {
+                                       Some(event.txid)
+                               } else { None }
+                       })
+               });
+
+               if confirmed_txid.is_none() {
+                       // If we have not seen a commitment transaction on-chain (ie the channel is not yet
+                       // closed), just get the full set.
+                       mem::drop(us);
+                       return self.get_all_current_outbound_htlcs();
+               }
+
+               let mut res = HashMap::new();
                macro_rules! walk_htlcs {
                        ($holder_commitment: expr, $htlc_iter: expr) => {
                                for (htlc, source) in $htlc_iter {
@@ -1870,62 +1905,32 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                                                                Some(commitment_tx_output_idx) == htlc.transaction_output_index
                                                        } else { false }
                                                });
-                                               if !htlc_update_confd {
-                                                       res.insert(source.clone(), htlc.clone());
+                                               let counterparty_resolved_preimage_opt =
+                                                       us.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).cloned();
+                                               if !htlc_update_confd || counterparty_resolved_preimage_opt.is_some() {
+                                                       res.insert(source.clone(), (htlc.clone(), counterparty_resolved_preimage_opt));
                                                }
                                        }
                                }
                        }
                }
 
-               // We're only concerned with the confirmation count of HTLC transactions, and don't
-               // actually care how many confirmations a commitment transaction may or may not have. Thus,
-               // we look for either a FundingSpendConfirmation event or a funding_spend_confirmed.
-               let confirmed_txid = us.funding_spend_confirmed.or_else(|| {
-                       us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
-                               if let OnchainEvent::FundingSpendConfirmation { .. } = event.event {
-                                       Some(event.txid)
+               let txid = confirmed_txid.unwrap();
+               if Some(txid) == us.current_counterparty_commitment_txid || Some(txid) == us.prev_counterparty_commitment_txid {
+                       walk_htlcs!(false, us.counterparty_claimable_outpoints.get(&txid).unwrap().iter().filter_map(|(a, b)| {
+                               if let &Some(ref source) = b {
+                                       Some((a, &**source))
                                } else { None }
-                       })
-               });
-               if let Some(txid) = confirmed_txid {
-                       if Some(txid) == us.current_counterparty_commitment_txid || Some(txid) == us.prev_counterparty_commitment_txid {
-                               walk_htlcs!(false, us.counterparty_claimable_outpoints.get(&txid).unwrap().iter().filter_map(|(a, b)| {
-                                       if let &Some(ref source) = b {
-                                               Some((a, &**source))
-                                       } else { None }
-                               }));
-                       } else if txid == us.current_holder_commitment_tx.txid {
-                               walk_htlcs!(true, us.current_holder_commitment_tx.htlc_outputs.iter().filter_map(|(a, _, c)| {
+                       }));
+               } else if txid == us.current_holder_commitment_tx.txid {
+                       walk_htlcs!(true, us.current_holder_commitment_tx.htlc_outputs.iter().filter_map(|(a, _, c)| {
+                               if let Some(source) = c { Some((a, source)) } else { None }
+                       }));
+               } else if let Some(prev_commitment) = &us.prev_holder_signed_commitment_tx {
+                       if txid == prev_commitment.txid {
+                               walk_htlcs!(true, prev_commitment.htlc_outputs.iter().filter_map(|(a, _, c)| {
                                        if let Some(source) = c { Some((a, source)) } else { None }
                                }));
-                       } else if let Some(prev_commitment) = &us.prev_holder_signed_commitment_tx {
-                               if txid == prev_commitment.txid {
-                                       walk_htlcs!(true, prev_commitment.htlc_outputs.iter().filter_map(|(a, _, c)| {
-                                               if let Some(source) = c { Some((a, source)) } else { None }
-                                       }));
-                               }
-                       }
-               } else {
-                       // If we have not seen a commitment transaction on-chain (ie the channel is not yet
-                       // closed), just examine the available counterparty commitment transactions. See docs
-                       // on `fail_unbroadcast_htlcs`, below, for justification.
-                       macro_rules! walk_counterparty_commitment {
-                               ($txid: expr) => {
-                                       if let Some(ref latest_outpoints) = us.counterparty_claimable_outpoints.get($txid) {
-                                               for &(ref htlc, ref source_option) in latest_outpoints.iter() {
-                                                       if let &Some(ref source) = source_option {
-                                                               res.insert((**source).clone(), htlc.clone());
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if let Some(ref txid) = us.current_counterparty_commitment_txid {
-                               walk_counterparty_commitment!(txid);
-                       }
-                       if let Some(ref txid) = us.prev_counterparty_commitment_txid {
-                               walk_counterparty_commitment!(txid);
                        }
                }
 
@@ -1985,6 +1990,9 @@ macro_rules! fail_unbroadcast_htlcs {
                                                                }
                                                        }
                                                        if matched_htlc { continue; }
+                                                       if $self.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).is_some() {
+                                                               continue;
+                                                       }
                                                        $self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
                                                                if entry.height != $commitment_tx_conf_height { return true; }
                                                                match entry.event {
@@ -2044,7 +2052,7 @@ pub fn deliberately_bogus_accepted_htlc_witness() -> Vec<Vec<u8>> {
        vec![Vec::new(), Vec::new(), Vec::new(), Vec::new(), deliberately_bogus_accepted_htlc_witness_program().into()].into()
 }
 
-impl<Signer: Sign> ChannelMonitorImpl<Signer> {
+impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
        /// Inserts a revocation secret into this channel monitor. Prunes old preimages if neither
        /// needed by holder commitment transactions HTCLs nor by counterparty ones. Unless we haven't already seen
        /// counterparty commitment transaction's secret, they are de facto pruned (we can use revocation key).
@@ -2056,8 +2064,23 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                // Prune HTLCs from the previous counterparty commitment tx so we don't generate failure/fulfill
                // events for now-revoked/fulfilled HTLCs.
                if let Some(txid) = self.prev_counterparty_commitment_txid.take() {
-                       for &mut (_, ref mut source) in self.counterparty_claimable_outpoints.get_mut(&txid).unwrap() {
-                               *source = None;
+                       if self.current_counterparty_commitment_txid.unwrap() != txid {
+                               let cur_claimables = self.counterparty_claimable_outpoints.get(
+                                       &self.current_counterparty_commitment_txid.unwrap()).unwrap();
+                               for (_, ref source_opt) in self.counterparty_claimable_outpoints.get(&txid).unwrap() {
+                                       if let Some(source) = source_opt {
+                                               if !cur_claimables.iter()
+                                                       .any(|(_, cur_source_opt)| cur_source_opt == source_opt)
+                                               {
+                                                       self.counterparty_fulfilled_htlcs.remove(&SentHTLCId::from_source(source));
+                                               }
+                                       }
+                               }
+                               for &mut (_, ref mut source_opt) in self.counterparty_claimable_outpoints.get_mut(&txid).unwrap() {
+                                       *source_opt = None;
+                               }
+                       } else {
+                               assert!(cfg!(fuzzing), "Commitment txids are unique outside of fuzzing, where hashes can collide");
                        }
                }
 
@@ -2142,28 +2165,83 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        /// is important that any clones of this channel monitor (including remote clones) by kept
        /// up-to-date as our holder commitment transaction is updated.
        /// Panics if set_on_holder_tx_csv has never been called.
-       fn provide_latest_holder_commitment_tx(&mut self, holder_commitment_tx: HolderCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>) -> Result<(), &'static str> {
-               // block for Rust 1.34 compat
-               let mut new_holder_commitment_tx = {
-                       let trusted_tx = holder_commitment_tx.trust();
-                       let txid = trusted_tx.txid();
-                       let tx_keys = trusted_tx.keys();
-                       self.current_holder_commitment_number = trusted_tx.commitment_number();
-                       HolderSignedTx {
-                               txid,
-                               revocation_key: tx_keys.revocation_key,
-                               a_htlc_key: tx_keys.broadcaster_htlc_key,
-                               b_htlc_key: tx_keys.countersignatory_htlc_key,
-                               delayed_payment_key: tx_keys.broadcaster_delayed_payment_key,
-                               per_commitment_point: tx_keys.per_commitment_point,
-                               htlc_outputs,
-                               to_self_value_sat: holder_commitment_tx.to_broadcaster_value_sat(),
-                               feerate_per_kw: trusted_tx.feerate_per_kw(),
+       fn provide_latest_holder_commitment_tx(&mut self, holder_commitment_tx: HolderCommitmentTransaction, mut htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>, claimed_htlcs: &[(SentHTLCId, PaymentPreimage)], nondust_htlc_sources: Vec<HTLCSource>) -> Result<(), &'static str> {
+               if htlc_outputs.iter().any(|(_, s, _)| s.is_some()) {
+                       // If we have non-dust HTLCs in htlc_outputs, ensure they match the HTLCs in the
+                       // `holder_commitment_tx`. In the future, we'll no longer provide the redundant data
+                       // and just pass in source data via `nondust_htlc_sources`.
+                       debug_assert_eq!(htlc_outputs.iter().filter(|(_, s, _)| s.is_some()).count(), holder_commitment_tx.trust().htlcs().len());
+                       for (a, b) in htlc_outputs.iter().filter(|(_, s, _)| s.is_some()).map(|(h, _, _)| h).zip(holder_commitment_tx.trust().htlcs().iter()) {
+                               debug_assert_eq!(a, b);
+                       }
+                       debug_assert_eq!(htlc_outputs.iter().filter(|(_, s, _)| s.is_some()).count(), holder_commitment_tx.counterparty_htlc_sigs.len());
+                       for (a, b) in htlc_outputs.iter().filter_map(|(_, s, _)| s.as_ref()).zip(holder_commitment_tx.counterparty_htlc_sigs.iter()) {
+                               debug_assert_eq!(a, b);
+                       }
+                       debug_assert!(nondust_htlc_sources.is_empty());
+               } else {
+                       // If we don't have any non-dust HTLCs in htlc_outputs, assume they were all passed via
+                       // `nondust_htlc_sources`, building up the final htlc_outputs by combining
+                       // `nondust_htlc_sources` and the `holder_commitment_tx`
+                       #[cfg(debug_assertions)] {
+                               let mut prev = -1;
+                               for htlc in holder_commitment_tx.trust().htlcs().iter() {
+                                       assert!(htlc.transaction_output_index.unwrap() as i32 > prev);
+                                       prev = htlc.transaction_output_index.unwrap() as i32;
+                               }
+                       }
+                       debug_assert!(htlc_outputs.iter().all(|(htlc, _, _)| htlc.transaction_output_index.is_none()));
+                       debug_assert!(htlc_outputs.iter().all(|(_, sig_opt, _)| sig_opt.is_none()));
+                       debug_assert_eq!(holder_commitment_tx.trust().htlcs().len(), holder_commitment_tx.counterparty_htlc_sigs.len());
+
+                       let mut sources_iter = nondust_htlc_sources.into_iter();
+
+                       for (htlc, counterparty_sig) in holder_commitment_tx.trust().htlcs().iter()
+                               .zip(holder_commitment_tx.counterparty_htlc_sigs.iter())
+                       {
+                               if htlc.offered {
+                                       let source = sources_iter.next().expect("Non-dust HTLC sources didn't match commitment tx");
+                                       #[cfg(debug_assertions)] {
+                                               assert!(source.possibly_matches_output(htlc));
+                                       }
+                                       htlc_outputs.push((htlc.clone(), Some(counterparty_sig.clone()), Some(source)));
+                               } else {
+                                       htlc_outputs.push((htlc.clone(), Some(counterparty_sig.clone()), None));
+                               }
                        }
+                       debug_assert!(sources_iter.next().is_none());
+               }
+
+               let trusted_tx = holder_commitment_tx.trust();
+               let txid = trusted_tx.txid();
+               let tx_keys = trusted_tx.keys();
+               self.current_holder_commitment_number = trusted_tx.commitment_number();
+               let mut new_holder_commitment_tx = HolderSignedTx {
+                       txid,
+                       revocation_key: tx_keys.revocation_key,
+                       a_htlc_key: tx_keys.broadcaster_htlc_key,
+                       b_htlc_key: tx_keys.countersignatory_htlc_key,
+                       delayed_payment_key: tx_keys.broadcaster_delayed_payment_key,
+                       per_commitment_point: tx_keys.per_commitment_point,
+                       htlc_outputs,
+                       to_self_value_sat: holder_commitment_tx.to_broadcaster_value_sat(),
+                       feerate_per_kw: trusted_tx.feerate_per_kw(),
                };
                self.onchain_tx_handler.provide_latest_holder_tx(holder_commitment_tx);
                mem::swap(&mut new_holder_commitment_tx, &mut self.current_holder_commitment_tx);
                self.prev_holder_signed_commitment_tx = Some(new_holder_commitment_tx);
+               for (claimed_htlc_id, claimed_preimage) in claimed_htlcs {
+                       #[cfg(debug_assertions)] {
+                               let cur_counterparty_htlcs = self.counterparty_claimable_outpoints.get(
+                                               &self.current_counterparty_commitment_txid.unwrap()).unwrap();
+                               assert!(cur_counterparty_htlcs.iter().any(|(_, source_opt)| {
+                                       if let Some(source) = source_opt {
+                                               SentHTLCId::from_source(source) == *claimed_htlc_id
+                                       } else { false }
+                               }));
+                       }
+                       self.counterparty_fulfilled_htlcs.insert(*claimed_htlc_id, *claimed_preimage);
+               }
                if self.holder_tx_signed {
                        return Err("Latest holder commitment signed has already been signed, update is rejected");
                }
@@ -2258,10 +2336,10 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator);
                for update in updates.updates.iter() {
                        match update {
-                               ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs } => {
+                               ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs, nondust_htlc_sources } => {
                                        log_trace!(logger, "Updating ChannelMonitor with latest holder commitment transaction info");
                                        if self.lockdown_from_offchain { panic!(); }
-                                       if let Err(e) = self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone()) {
+                                       if let Err(e) = self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone(), &claimed_htlcs, nondust_htlc_sources.clone()) {
                                                log_error!(logger, "Providing latest holder commitment transaction failed/was refused:");
                                                log_error!(logger, "    {}", e);
                                                ret = Err(());
@@ -2287,6 +2365,17 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        log_trace!(logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}", should_broadcast);
                                        self.lockdown_from_offchain = true;
                                        if *should_broadcast {
+                                               // There's no need to broadcast our commitment transaction if we've seen one
+                                               // confirmed (even with 1 confirmation) as it'll be rejected as
+                                               // duplicate/conflicting.
+                                               let detected_funding_spend = self.funding_spend_confirmed.is_some() ||
+                                                       self.onchain_events_awaiting_threshold_conf.iter().find(|event| match event.event {
+                                                               OnchainEvent::FundingSpendConfirmation { .. } => true,
+                                                               _ => false,
+                                                       }).is_some();
+                                               if detected_funding_spend {
+                                                       continue;
+                                               }
                                                self.broadcast_latest_holder_commitment_txn(broadcaster, logger);
                                                // If the channel supports anchor outputs, we'll need to emit an external
                                                // event to be consumed such that a child transaction is broadcast with a
@@ -2387,6 +2476,27 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                pending_htlcs,
                                        }));
                                },
+                               ClaimEvent::BumpHTLC {
+                                       target_feerate_sat_per_1000_weight, htlcs,
+                               } => {
+                                       let mut htlc_descriptors = Vec::with_capacity(htlcs.len());
+                                       for htlc in htlcs {
+                                               htlc_descriptors.push(HTLCDescriptor {
+                                                       channel_keys_id: self.channel_keys_id,
+                                                       channel_value_satoshis: self.channel_value_satoshis,
+                                                       channel_parameters: self.onchain_tx_handler.channel_transaction_parameters.clone(),
+                                                       commitment_txid: htlc.commitment_txid,
+                                                       per_commitment_number: htlc.per_commitment_number,
+                                                       htlc: htlc.htlc,
+                                                       preimage: htlc.preimage,
+                                                       counterparty_sig: htlc.counterparty_sig,
+                                               });
+                                       }
+                                       ret.push(Event::BumpTransaction(BumpTransactionEvent::HTLCResolution {
+                                               target_feerate_sat_per_1000_weight,
+                                               htlc_descriptors,
+                                       }));
+                               }
                        }
                }
                ret
@@ -2442,9 +2552,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                if commitment_number >= self.get_min_seen_secret() {
                        let secret = self.get_secret(commitment_number).unwrap();
                        let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret));
-                       let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
-                       let revocation_pubkey = chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
-                       let delayed_key = chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
+                       let per_commitment_point = PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key);
+                       let revocation_pubkey = chan_utils::derive_public_revocation_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
+                       let delayed_key = chan_utils::derive_public_key(&self.onchain_tx_handler.secp_ctx, &PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key), &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
 
                        let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.counterparty_commitment_params.on_counterparty_tx_csv, &delayed_key);
                        let revokeable_p2wsh = revokeable_redeemscript.to_v0_p2wsh();
@@ -2557,8 +2667,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                if let Some(transaction) = tx {
                        let revocation_pubkey = chan_utils::derive_public_revocation_key(
-                               &self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
-                       let delayed_key = chan_utils::derive_public_key(&self.secp_ctx,
+                               &self.onchain_tx_handler.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint);
+                       let delayed_key = chan_utils::derive_public_key(&self.onchain_tx_handler.secp_ctx,
                                &per_commitment_point,
                                &self.counterparty_commitment_params.counterparty_delayed_payment_base_key);
                        let revokeable_p2wsh = chan_utils::get_revokeable_redeemscript(&revocation_pubkey,
@@ -2607,31 +2717,49 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        }
 
        /// Attempts to claim a counterparty HTLC-Success/HTLC-Timeout's outputs using the revocation key
-       fn check_spend_counterparty_htlc<L: Deref>(&mut self, tx: &Transaction, commitment_number: u64, height: u32, logger: &L) -> (Vec<PackageTemplate>, Option<TransactionOutputs>) where L::Target: Logger {
-               let htlc_txid = tx.txid();
-               if tx.input.len() != 1 || tx.output.len() != 1 || tx.input[0].witness.len() != 5 {
-                       return (Vec::new(), None)
-               }
+       fn check_spend_counterparty_htlc<L: Deref>(
+               &mut self, tx: &Transaction, commitment_number: u64, commitment_txid: &Txid, height: u32, logger: &L
+       ) -> (Vec<PackageTemplate>, Option<TransactionOutputs>) where L::Target: Logger {
+               let secret = if let Some(secret) = self.get_secret(commitment_number) { secret } else { return (Vec::new(), None); };
+               let per_commitment_key = match SecretKey::from_slice(&secret) {
+                       Ok(key) => key,
+                       Err(_) => return (Vec::new(), None)
+               };
+               let per_commitment_point = PublicKey::from_secret_key(&self.onchain_tx_handler.secp_ctx, &per_commitment_key);
 
-               macro_rules! ignore_error {
-                       ( $thing : expr ) => {
-                               match $thing {
-                                       Ok(a) => a,
-                                       Err(_) => return (Vec::new(), None)
+               let htlc_txid = tx.txid();
+               let mut claimable_outpoints = vec![];
+               let mut outputs_to_watch = None;
+               // Previously, we would only claim HTLCs from revoked HTLC transactions if they had 1 input
+               // with a witness of 5 elements and 1 output. This wasn't enough for anchor outputs, as the
+               // counterparty can now aggregate multiple HTLCs into a single transaction thanks to
+               // `SIGHASH_SINGLE` remote signatures, leading us to not claim any HTLCs upon seeing a
+               // confirmed revoked HTLC transaction (for more details, see
+               // https://lists.linuxfoundation.org/pipermail/lightning-dev/2022-April/003561.html).
+               //
+               // We make sure we're not vulnerable to this case by checking all inputs of the transaction,
+               // and claim those which spend the commitment transaction, have a witness of 5 elements, and
+               // have a corresponding output at the same index within the transaction.
+               for (idx, input) in tx.input.iter().enumerate() {
+                       if input.previous_output.txid == *commitment_txid && input.witness.len() == 5 && tx.output.get(idx).is_some() {
+                               log_error!(logger, "Got broadcast of revoked counterparty HTLC transaction, spending {}:{}", htlc_txid, idx);
+                               let revk_outp = RevokedOutput::build(
+                                       per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key,
+                                       self.counterparty_commitment_params.counterparty_htlc_base_key, per_commitment_key,
+                                       tx.output[idx].value, self.counterparty_commitment_params.on_counterparty_tx_csv
+                               );
+                               let justice_package = PackageTemplate::build_package(
+                                       htlc_txid, idx as u32, PackageSolvingData::RevokedOutput(revk_outp),
+                                       height + self.counterparty_commitment_params.on_counterparty_tx_csv as u32, true, height
+                               );
+                               claimable_outpoints.push(justice_package);
+                               if outputs_to_watch.is_none() {
+                                       outputs_to_watch = Some((htlc_txid, vec![]));
                                }
-                       };
+                               outputs_to_watch.as_mut().unwrap().1.push((idx as u32, tx.output[idx].clone()));
+                       }
                }
-
-               let secret = if let Some(secret) = self.get_secret(commitment_number) { secret } else { return (Vec::new(), None); };
-               let per_commitment_key = ignore_error!(SecretKey::from_slice(&secret));
-               let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
-
-               log_error!(logger, "Got broadcast of revoked counterparty HTLC transaction, spending {}:{}", htlc_txid, 0);
-               let revk_outp = RevokedOutput::build(per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, per_commitment_key, tx.output[0].value, self.counterparty_commitment_params.on_counterparty_tx_csv);
-               let justice_package = PackageTemplate::build_package(htlc_txid, 0, PackageSolvingData::RevokedOutput(revk_outp), height + self.counterparty_commitment_params.on_counterparty_tx_csv as u32, true, height);
-               let claimable_outpoints = vec!(justice_package);
-               let outputs = vec![(0, tx.output[0].clone())];
-               (claimable_outpoints, Some((htlc_txid, outputs)))
+               (claimable_outpoints, outputs_to_watch)
        }
 
        // Returns (1) `PackageTemplate`s that can be given to the OnchainTxHandler, so that the handler can
@@ -2645,18 +2773,28 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                for &(ref htlc, _, _) in holder_tx.htlc_outputs.iter() {
                        if let Some(transaction_output_index) = htlc.transaction_output_index {
-                               let htlc_output = if htlc.offered {
-                                               HolderHTLCOutput::build_offered(htlc.amount_msat, htlc.cltv_expiry)
+                               let (htlc_output, aggregable) = if htlc.offered {
+                                       let htlc_output = HolderHTLCOutput::build_offered(
+                                               htlc.amount_msat, htlc.cltv_expiry, self.onchain_tx_handler.opt_anchors()
+                                       );
+                                       (htlc_output, false)
+                               } else {
+                                       let payment_preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) {
+                                               preimage.clone()
                                        } else {
-                                               let payment_preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) {
-                                                       preimage.clone()
-                                               } else {
-                                                       // We can't build an HTLC-Success transaction without the preimage
-                                                       continue;
-                                               };
-                                               HolderHTLCOutput::build_accepted(payment_preimage, htlc.amount_msat)
+                                               // We can't build an HTLC-Success transaction without the preimage
+                                               continue;
                                        };
-                               let htlc_package = PackageTemplate::build_package(holder_tx.txid, transaction_output_index, PackageSolvingData::HolderHTLCOutput(htlc_output), htlc.cltv_expiry, false, conf_height);
+                                       let htlc_output = HolderHTLCOutput::build_accepted(
+                                               payment_preimage, htlc.amount_msat, self.onchain_tx_handler.opt_anchors()
+                                       );
+                                       (htlc_output, self.onchain_tx_handler.opt_anchors())
+                               };
+                               let htlc_package = PackageTemplate::build_package(
+                                       holder_tx.txid, transaction_output_index,
+                                       PackageSolvingData::HolderHTLCOutput(htlc_output),
+                                       htlc.cltv_expiry, aggregable, conf_height
+                               );
                                claim_requests.push(htlc_package);
                        }
                }
@@ -2889,9 +3027,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                        if tx.input.len() == 1 {
                                // Assuming our keys were not leaked (in which case we're screwed no matter what),
-                               // commitment transactions and HTLC transactions will all only ever have one input,
-                               // which is an easy way to filter out any potential non-matching txn for lazy
-                               // filters.
+                               // commitment transactions and HTLC transactions will all only ever have one input
+                               // (except for HTLC transactions for channels with anchor outputs), which is an easy
+                               // way to filter out any potential non-matching txn for lazy filters.
                                let prevout = &tx.input[0].previous_output;
                                if prevout.txid == self.funding_info.0.txid && prevout.vout == self.funding_info.0.index as u32 {
                                        let mut balance_spendable_csv = None;
@@ -2929,22 +3067,33 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                        commitment_tx_to_counterparty_output,
                                                },
                                        });
-                               } else {
-                                       if let Some(&commitment_number) = self.counterparty_commitment_txn_on_chain.get(&prevout.txid) {
-                                               let (mut new_outpoints, new_outputs_option) = self.check_spend_counterparty_htlc(&tx, commitment_number, height, &logger);
+                               }
+                       }
+                       if tx.input.len() >= 1 {
+                               // While all commitment transactions have one input, HTLC transactions may have more
+                               // if the HTLC was present in an anchor channel. HTLCs can also be resolved in a few
+                               // other ways which can have more than one output.
+                               for tx_input in &tx.input {
+                                       let commitment_txid = tx_input.previous_output.txid;
+                                       if let Some(&commitment_number) = self.counterparty_commitment_txn_on_chain.get(&commitment_txid) {
+                                               let (mut new_outpoints, new_outputs_option) = self.check_spend_counterparty_htlc(
+                                                       &tx, commitment_number, &commitment_txid, height, &logger
+                                               );
                                                claimable_outpoints.append(&mut new_outpoints);
                                                if let Some(new_outputs) = new_outputs_option {
                                                        watch_outputs.push(new_outputs);
                                                }
+                                               // Since there may be multiple HTLCs for this channel (all spending the
+                                               // same commitment tx) being claimed by the counterparty within the same
+                                               // transaction, and `check_spend_counterparty_htlc` already checks all the
+                                               // ones relevant to this channel, we can safely break from our loop.
+                                               break;
                                        }
                                }
-                       }
-                       // While all commitment/HTLC-Success/HTLC-Timeout transactions have one input, HTLCs
-                       // can also be resolved in a few other ways which can have more than one output. Thus,
-                       // we call is_resolving_htlc_output here outside of the tx.input.len() == 1 check.
-                       self.is_resolving_htlc_output(&tx, height, &block_hash, &logger);
+                               self.is_resolving_htlc_output(&tx, height, &block_hash, &logger);
 
-                       self.is_paying_spendable_output(&tx, height, &block_hash, &logger);
+                               self.is_paying_spendable_output(&tx, height, &block_hash, &logger);
+                       }
                }
 
                if height > self.best_block.height() {
@@ -3058,7 +3207,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                htlc_value_satoshis,
                                        }));
                                        self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC {
-                                               commitment_tx_output_idx, resolving_txid: Some(entry.txid),
+                                               commitment_tx_output_idx,
+                                               resolving_txid: Some(entry.txid),
+                                               resolving_tx: entry.transaction,
                                                payment_preimage: None,
                                        });
                                },
@@ -3071,7 +3222,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                },
                                OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. } => {
                                        self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC {
-                                               commitment_tx_output_idx: Some(commitment_tx_output_idx), resolving_txid: Some(entry.txid),
+                                               commitment_tx_output_idx: Some(commitment_tx_output_idx),
+                                               resolving_txid: Some(entry.txid),
+                                               resolving_tx: entry.transaction,
                                                payment_preimage: preimage,
                                        });
                                },
@@ -3551,7 +3704,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        }
 }
 
-impl<Signer: Sign, T: Deref, F: Deref, L: Deref> chain::Listen for (ChannelMonitor<Signer>, T, F, L)
+impl<Signer: WriteableEcdsaChannelSigner, T: Deref, F: Deref, L: Deref> chain::Listen for (ChannelMonitor<Signer>, T, F, L)
 where
        T::Target: BroadcasterInterface,
        F::Target: FeeEstimator,
@@ -3566,7 +3719,7 @@ where
        }
 }
 
-impl<Signer: Sign, T: Deref, F: Deref, L: Deref> chain::Confirm for (ChannelMonitor<Signer>, T, F, L)
+impl<Signer: WriteableEcdsaChannelSigner, T: Deref, F: Deref, L: Deref> chain::Confirm for (ChannelMonitor<Signer>, T, F, L)
 where
        T::Target: BroadcasterInterface,
        F::Target: FeeEstimator,
@@ -3591,9 +3744,9 @@ where
 
 const MAX_ALLOC_SIZE: usize = 64*1024;
 
-impl<'a, K: KeysInterface> ReadableArgs<&'a K>
-               for (BlockHash, ChannelMonitor<K::Signer>) {
-       fn read<R: io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
+impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP)>
+               for (BlockHash, ChannelMonitor<SP::Signer>) {
+       fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP)) -> Result<Self, DecodeError> {
                macro_rules! unwrap_obj {
                        ($key: expr) => {
                                match $key {
@@ -3603,6 +3756,8 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                        }
                }
 
+               let (entropy_source, signer_provider) = args;
+
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let latest_update_id: u64 = Readable::read(reader)?;
@@ -3776,7 +3931,9 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                                return Err(DecodeError::InvalidValue);
                        }
                }
-               let onchain_tx_handler: OnchainTxHandler<K::Signer> = ReadableArgs::read(reader, keys_manager)?;
+               let onchain_tx_handler: OnchainTxHandler<SP::Signer> = ReadableArgs::read(
+                       reader, (entropy_source, signer_provider, channel_value_satoshis, channel_keys_id)
+               )?;
 
                let lockdown_from_offchain = Readable::read(reader)?;
                let holder_tx_signed = Readable::read(reader)?;
@@ -3804,6 +3961,7 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                let mut counterparty_node_id = None;
                let mut confirmed_commitment_tx_counterparty_output = None;
                let mut spendable_txids_confirmed = Some(Vec::new());
+               let mut counterparty_fulfilled_htlcs = Some(HashMap::new());
                read_tlv_fields!(reader, {
                        (1, funding_spend_confirmed, option),
                        (3, htlcs_resolved_on_chain, vec_type),
@@ -3812,11 +3970,9 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                        (9, counterparty_node_id, option),
                        (11, confirmed_commitment_tx_counterparty_output, option),
                        (13, spendable_txids_confirmed, vec_type),
+                       (15, counterparty_fulfilled_htlcs, option),
                });
 
-               let mut secp_ctx = Secp256k1::new();
-               secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
-
                Ok((best_block.block_hash(), ChannelMonitor::from_impl(ChannelMonitorImpl {
                        latest_update_id,
                        commitment_transaction_number_obscure_factor,
@@ -3843,6 +3999,7 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
                        counterparty_claimable_outpoints,
                        counterparty_commitment_txn_on_chain,
                        counterparty_hash_commitment_number,
+                       counterparty_fulfilled_htlcs: counterparty_fulfilled_htlcs.unwrap(),
 
                        prev_holder_signed_commitment_tx,
                        current_holder_commitment_tx,
@@ -3868,8 +4025,6 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
 
                        best_block,
                        counterparty_node_id,
-
-                       secp_ctx,
                })))
        }
 }
@@ -3904,7 +4059,7 @@ mod tests {
        use crate::ln::{PaymentPreimage, PaymentHash};
        use crate::ln::chan_utils;
        use crate::ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
-       use crate::ln::channelmanager::{self, PaymentSendFailure, PaymentId};
+       use crate::ln::channelmanager::{PaymentSendFailure, PaymentId};
        use crate::ln::functional_test_utils::*;
        use crate::ln::script::ShutdownScript;
        use crate::util::errors::APIError;
@@ -3932,10 +4087,8 @@ mod tests {
                let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
-               let channel = create_announced_chan_between_nodes(
-                       &nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
-               create_announced_chan_between_nodes(
-                       &nodes, 1, 2, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               let channel = create_announced_chan_between_nodes(&nodes, 0, 1);
+               create_announced_chan_between_nodes(&nodes, 1, 2);
 
                // Rebalance somewhat
                send_payment(&nodes[0], &[&nodes[1]], 10_000_000);
@@ -3964,7 +4117,7 @@ mod tests {
 
                let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor<InMemorySigner>)>::read(
                                                &mut io::Cursor::new(&get_monitor!(nodes[1], channel.2).encode()),
-                                               &nodes[1].keys_manager.backing).unwrap();
+                                               (&nodes[1].keys_manager.backing, &nodes[1].keys_manager.backing)).unwrap();
 
                // If the ChannelManager tries to update the channel, however, the ChainMonitor will pass
                // the update through to the ChannelMonitor which will refuse it (as the channel is closed).
@@ -4013,11 +4166,13 @@ mod tests {
        fn test_prune_preimages() {
                let secp_ctx = Secp256k1::new();
                let logger = Arc::new(TestLogger::new());
-               let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))});
+               let broadcaster = Arc::new(TestBroadcaster {
+                       txn_broadcasted: Mutex::new(Vec::new()),
+                       blocks: Arc::new(Mutex::new(Vec::new()))
+               });
                let fee_estimator = TestFeeEstimator { sat_per_kw: Mutex::new(253) };
 
                let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
-               let dummy_tx = Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() };
 
                let mut preimages = Vec::new();
                {
@@ -4028,7 +4183,7 @@ mod tests {
                        }
                }
 
-               macro_rules! preimages_slice_to_htlc_outputs {
+               macro_rules! preimages_slice_to_htlcs {
                        ($preimages_slice: expr) => {
                                {
                                        let mut res = Vec::new();
@@ -4039,21 +4194,20 @@ mod tests {
                                                        cltv_expiry: 0,
                                                        payment_hash: preimage.1.clone(),
                                                        transaction_output_index: Some(idx as u32),
-                                               }, None));
+                                               }, ()));
                                        }
                                        res
                                }
                        }
                }
-               macro_rules! preimages_to_holder_htlcs {
+               macro_rules! preimages_slice_to_htlc_outputs {
                        ($preimages_slice: expr) => {
-                               {
-                                       let mut inp = preimages_slice_to_htlc_outputs!($preimages_slice);
-                                       let res: Vec<_> = inp.drain(..).map(|e| { (e.0, None, e.1) }).collect();
-                                       res
-                               }
+                               preimages_slice_to_htlcs!($preimages_slice).into_iter().map(|(htlc, _)| (htlc, None)).collect()
                        }
                }
+               let dummy_sig = crate::util::crypto::sign(&secp_ctx,
+                       &bitcoin::secp256k1::Message::from_slice(&[42; 32]).unwrap(),
+                       &SecretKey::from_slice(&[42; 32]).unwrap());
 
                macro_rules! test_preimages_exist {
                        ($preimages_slice: expr, $monitor: expr) => {
@@ -4070,7 +4224,6 @@ mod tests {
                        SecretKey::from_slice(&[41; 32]).unwrap(),
                        SecretKey::from_slice(&[41; 32]).unwrap(),
                        SecretKey::from_slice(&[41; 32]).unwrap(),
-                       SecretKey::from_slice(&[41; 32]).unwrap(),
                        [41; 32],
                        0,
                        [0; 32],
@@ -4099,20 +4252,21 @@ mod tests {
                // Prune with one old state and a holder commitment tx holding a few overlaps with the
                // old state.
                let shutdown_pubkey = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
-               let best_block = BestBlock::from_genesis(Network::Testnet);
+               let best_block = BestBlock::from_network(Network::Testnet);
                let monitor = ChannelMonitor::new(Secp256k1::new(), keys,
-                                                 Some(ShutdownScript::new_p2wpkh_from_pubkey(shutdown_pubkey).into_inner()), 0, &Script::new(),
-                                                 (OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
-                                                 &channel_parameters,
-                                                 Script::new(), 46, 0,
-                                                 HolderCommitmentTransaction::dummy(), best_block, dummy_key);
-
-               monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..10])).unwrap();
-               let dummy_txid = dummy_tx.txid();
-               monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger);
-               monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger);
-               monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
-               monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
+                       Some(ShutdownScript::new_p2wpkh_from_pubkey(shutdown_pubkey).into_inner()), 0, &Script::new(),
+                       (OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
+                       &channel_parameters, Script::new(), 46, 0, HolderCommitmentTransaction::dummy(&mut Vec::new()),
+                       best_block, dummy_key);
+
+               let mut htlcs = preimages_slice_to_htlcs!(preimages[0..10]);
+               let dummy_commitment_tx = HolderCommitmentTransaction::dummy(&mut htlcs);
+               monitor.provide_latest_holder_commitment_tx(dummy_commitment_tx.clone(),
+                       htlcs.into_iter().map(|(htlc, _)| (htlc, Some(dummy_sig), None)).collect()).unwrap();
+               monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"1").into_inner()),
+                       preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger);
+               monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"2").into_inner()),
+                       preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger);
                for &(ref preimage, ref hash) in preimages.iter() {
                        let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_estimator);
                        monitor.provide_payment_preimage(hash, preimage, &broadcaster, &bounded_fee_estimator, &logger);
@@ -4126,6 +4280,9 @@ mod tests {
                test_preimages_exist!(&preimages[0..10], monitor);
                test_preimages_exist!(&preimages[15..20], monitor);
 
+               monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"3").into_inner()),
+                       preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
+
                // Now provide a further secret, pruning preimages 15-17
                secret[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
                monitor.provide_secret(281474976710654, secret.clone()).unwrap();
@@ -4133,9 +4290,15 @@ mod tests {
                test_preimages_exist!(&preimages[0..10], monitor);
                test_preimages_exist!(&preimages[17..20], monitor);
 
+               monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"4").into_inner()),
+                       preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
+
                // Now update holder commitment tx info, pruning only element 18 as we still care about the
                // previous commitment tx's preimages too
-               monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..5])).unwrap();
+               let mut htlcs = preimages_slice_to_htlcs!(preimages[0..5]);
+               let dummy_commitment_tx = HolderCommitmentTransaction::dummy(&mut htlcs);
+               monitor.provide_latest_holder_commitment_tx(dummy_commitment_tx.clone(),
+                       htlcs.into_iter().map(|(htlc, _)| (htlc, Some(dummy_sig), None)).collect()).unwrap();
                secret[0..32].clone_from_slice(&hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap());
                monitor.provide_secret(281474976710653, secret.clone()).unwrap();
                assert_eq!(monitor.inner.lock().unwrap().payment_preimages.len(), 12);
@@ -4143,7 +4306,10 @@ mod tests {
                test_preimages_exist!(&preimages[18..20], monitor);
 
                // But if we do it again, we'll prune 5-10
-               monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..3])).unwrap();
+               let mut htlcs = preimages_slice_to_htlcs!(preimages[0..3]);
+               let dummy_commitment_tx = HolderCommitmentTransaction::dummy(&mut htlcs);
+               monitor.provide_latest_holder_commitment_tx(dummy_commitment_tx,
+                       htlcs.into_iter().map(|(htlc, _)| (htlc, Some(dummy_sig), None)).collect()).unwrap();
                secret[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
                monitor.provide_secret(281474976710652, secret.clone()).unwrap();
                assert_eq!(monitor.inner.lock().unwrap().payment_preimages.len(), 5);