Merge pull request #1435 from TheBlueMatt/2022-04-1126-first-step
[rust-lightning] / lightning / src / chain / channelmonitor.rs
index f0b23c08619632c4ab14d45f5322d51cc017c38d..681d895f27e05fa6ef42105f468bae7a1a258250 100644 (file)
@@ -20,9 +20,8 @@
 //! security-domain-separated system design, you should consider having multiple paths for
 //! ChannelMonitors to get out of the HSM and onto monitoring devices.
 
-use bitcoin::blockdata::block::{Block, BlockHeader};
+use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::transaction::{TxOut,Transaction};
-use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
 use bitcoin::blockdata::script::{Script, Builder};
 use bitcoin::blockdata::opcodes;
 
@@ -34,31 +33,33 @@ use bitcoin::secp256k1::{Secp256k1,Signature};
 use bitcoin::secp256k1::key::{SecretKey,PublicKey};
 use bitcoin::secp256k1;
 
+use ln::{PaymentHash, PaymentPreimage};
 use ln::msgs::DecodeError;
 use ln::chan_utils;
 use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCType, ChannelTransactionParameters, HolderCommitmentTransaction};
-use ln::channelmanager::{BestBlock, HTLCSource, PaymentPreimage, PaymentHash};
-use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
+use ln::channelmanager::HTLCSource;
 use chain;
-use chain::WatchedOutput;
+use chain::{BestBlock, WatchedOutput};
 use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
 use chain::transaction::{OutPoint, TransactionData};
 use chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, Sign, KeysInterface};
+use chain::onchaintx::OnchainTxHandler;
+use chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
 use chain::Filter;
 use util::logger::Logger;
-use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48};
+use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48, OptionDeserWrapper};
 use util::byte_utils;
 use util::events::Event;
 
-use std::collections::{HashMap, HashSet};
-use std::{cmp, mem};
-use std::io::Error;
-use std::ops::Deref;
-use std::sync::Mutex;
+use prelude::*;
+use core::{cmp, mem};
+use io::{self, Error};
+use core::ops::Deref;
+use sync::Mutex;
 
 /// An update generated by the underlying Channel itself which contains some new information the
 /// ChannelMonitor should be made aware of.
-#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
+#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq))]
 #[derive(Clone)]
 #[must_use]
 pub struct ChannelMonitorUpdate {
@@ -84,108 +85,78 @@ pub struct ChannelMonitorUpdate {
 /// then we allow the `ChannelManager` to send a `ChannelMonitorUpdate` with this update ID,
 /// with the update providing said payment preimage. No other update types are allowed after
 /// force-close.
-pub const CLOSED_CHANNEL_UPDATE_ID: u64 = std::u64::MAX;
+pub const CLOSED_CHANNEL_UPDATE_ID: u64 = core::u64::MAX;
 
 impl Writeable for ChannelMonitorUpdate {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               write_ver_prefix!(w, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
                self.update_id.write(w)?;
                (self.updates.len() as u64).write(w)?;
                for update_step in self.updates.iter() {
                        update_step.write(w)?;
                }
+               write_tlv_fields!(w, {});
                Ok(())
        }
 }
 impl Readable for ChannelMonitorUpdate {
-       fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
+       fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
+               let _ver = read_ver_prefix!(r, SERIALIZATION_VERSION);
                let update_id: u64 = Readable::read(r)?;
                let len: u64 = Readable::read(r)?;
-               let mut updates = Vec::with_capacity(cmp::min(len as usize, MAX_ALLOC_SIZE / ::std::mem::size_of::<ChannelMonitorUpdateStep>()));
+               let mut updates = Vec::with_capacity(cmp::min(len as usize, MAX_ALLOC_SIZE / ::core::mem::size_of::<ChannelMonitorUpdateStep>()));
                for _ in 0..len {
-                       updates.push(Readable::read(r)?);
+                       if let Some(upd) = MaybeReadable::read(r)? {
+                               updates.push(upd);
+                       }
                }
+               read_tlv_fields!(r, {});
                Ok(Self { update_id, updates })
        }
 }
 
-/// An error enum representing a failure to persist a channel monitor update.
-#[derive(Clone, Debug)]
-pub enum ChannelMonitorUpdateErr {
-       /// Used to indicate a temporary failure (eg connection to a watchtower or remote backup of
-       /// our state failed, but is expected to succeed at some point in the future).
-       ///
-       /// Such a failure will "freeze" a channel, preventing us from revoking old states or
-       /// submitting new commitment transactions to the counterparty. Once the update(s) which failed
-       /// have been successfully applied, ChannelManager::channel_monitor_updated can be used to
-       /// restore the channel to an operational state.
-       ///
-       /// Note that a given ChannelManager will *never* re-generate a given ChannelMonitorUpdate. If
-       /// you return a TemporaryFailure you must ensure that it is written to disk safely before
-       /// writing out the latest ChannelManager state.
-       ///
-       /// Even when a channel has been "frozen" updates to the ChannelMonitor can continue to occur
-       /// (eg if an inbound HTLC which we forwarded was claimed upstream resulting in us attempting
-       /// to claim it on this channel) and those updates must be applied wherever they can be. At
-       /// least one such updated ChannelMonitor must be persisted otherwise PermanentFailure should
-       /// be returned to get things on-chain ASAP using only the in-memory copy. Obviously updates to
-       /// the channel which would invalidate previous ChannelMonitors are not made when a channel has
-       /// been "frozen".
-       ///
-       /// Note that even if updates made after TemporaryFailure succeed you must still call
-       /// channel_monitor_updated to ensure you have the latest monitor and re-enable normal channel
-       /// operation.
-       ///
-       /// Note that the update being processed here will not be replayed for you when you call
-       /// ChannelManager::channel_monitor_updated, so you must store the update itself along
-       /// with the persisted ChannelMonitor on your own local disk prior to returning a
-       /// TemporaryFailure. You may, of course, employ a journaling approach, storing only the
-       /// ChannelMonitorUpdate on disk without updating the monitor itself, replaying the journal at
-       /// reload-time.
-       ///
-       /// For deployments where a copy of ChannelMonitors and other local state are backed up in a
-       /// remote location (with local copies persisted immediately), it is anticipated that all
-       /// updates will return TemporaryFailure until the remote copies could be updated.
-       TemporaryFailure,
-       /// Used to indicate no further channel monitor updates will be allowed (eg we've moved on to a
-       /// different watchtower and cannot update with all watchtowers that were previously informed
-       /// of this channel).
-       ///
-       /// At reception of this error, ChannelManager will force-close the channel and return at
-       /// least a final ChannelMonitorUpdate::ChannelForceClosed which must be delivered to at
-       /// least one ChannelMonitor copy. Revocation secret MUST NOT be released and offchain channel
-       /// update must be rejected.
-       ///
-       /// This failure may also signal a failure to update the local persisted copy of one of
-       /// the channel monitor instance.
-       ///
-       /// Note that even when you fail a holder commitment transaction update, you must store the
-       /// update to ensure you can claim from it in case of a duplicate copy of this ChannelMonitor
-       /// broadcasts it (e.g distributed channel-monitor deployment)
-       ///
-       /// In case of distributed watchtowers deployment, the new version must be written to disk, as
-       /// state may have been stored but rejected due to a block forcing a commitment broadcast. This
-       /// storage is used to claim outputs of rejected state confirmed onchain by another watchtower,
-       /// lagging behind on block processing.
-       PermanentFailure,
-}
-
-/// General Err type for ChannelMonitor actions. Generally, this implies that the data provided is
-/// inconsistent with the ChannelMonitor being called. eg for ChannelMonitor::update_monitor this
-/// means you tried to update a monitor for a different channel or the ChannelMonitorUpdate was
-/// corrupted.
-/// Contains a developer-readable error message.
-#[derive(Clone, Debug)]
-pub struct MonitorUpdateError(pub &'static str);
-
 /// An event to be processed by the ChannelManager.
 #[derive(Clone, PartialEq)]
 pub enum MonitorEvent {
        /// A monitor event containing an HTLCUpdate.
        HTLCEvent(HTLCUpdate),
 
-       /// A monitor event that the Channel's commitment transaction was broadcasted.
-       CommitmentTxBroadcasted(OutPoint),
+       /// A monitor event that the Channel's commitment transaction was confirmed.
+       CommitmentTxConfirmed(OutPoint),
+
+       /// Indicates a [`ChannelMonitor`] update has completed. See
+       /// [`ChannelMonitorUpdateErr::TemporaryFailure`] for more information on how this is used.
+       ///
+       /// [`ChannelMonitorUpdateErr::TemporaryFailure`]: super::ChannelMonitorUpdateErr::TemporaryFailure
+       UpdateCompleted {
+               /// The funding outpoint of the [`ChannelMonitor`] that was updated
+               funding_txo: OutPoint,
+               /// The Update ID from [`ChannelMonitorUpdate::update_id`] which was applied or
+               /// [`ChannelMonitor::get_latest_update_id`].
+               ///
+               /// Note that this should only be set to a given update's ID if all previous updates for the
+               /// same [`ChannelMonitor`] have been applied and persisted.
+               monitor_update_id: u64,
+       },
+
+       /// Indicates a [`ChannelMonitor`] update has failed. See
+       /// [`ChannelMonitorUpdateErr::PermanentFailure`] for more information on how this is used.
+       ///
+       /// [`ChannelMonitorUpdateErr::PermanentFailure`]: super::ChannelMonitorUpdateErr::PermanentFailure
+       UpdateFailed(OutPoint),
 }
+impl_writeable_tlv_based_enum_upgradable!(MonitorEvent,
+       // Note that UpdateCompleted and UpdateFailed are currently never serialized to disk as they are
+       // generated only in ChainMonitor
+       (0, UpdateCompleted) => {
+               (0, funding_txo, required),
+               (2, monitor_update_id, required),
+       },
+;
+       (2, HTLCEvent),
+       (4, CommitmentTxConfirmed),
+       (6, UpdateFailed),
+);
 
 /// Simple structure sent back by `chain::Watch` when an HTLC from a forward channel is detected on
 /// chain. Used to update the corresponding HTLC in the backward channel. Failing to pass the
@@ -194,9 +165,15 @@ pub enum MonitorEvent {
 pub struct HTLCUpdate {
        pub(crate) payment_hash: PaymentHash,
        pub(crate) payment_preimage: Option<PaymentPreimage>,
-       pub(crate) source: HTLCSource
+       pub(crate) source: HTLCSource,
+       pub(crate) onchain_value_satoshis: Option<u64>,
 }
-impl_writeable!(HTLCUpdate, 0, { payment_hash, payment_preimage, source });
+impl_writeable_tlv_based!(HTLCUpdate, {
+       (0, payment_hash, required),
+       (1, onchain_value_satoshis, option),
+       (2, source, required),
+       (4, payment_preimage, option),
+});
 
 /// If an HTLC expires within this many blocks, don't try to claim it in a shared transaction,
 /// instead claiming it in its own individual transaction.
@@ -205,7 +182,7 @@ pub(crate) const CLTV_SHARED_CLAIM_BUFFER: u32 = 12;
 /// HTLC-Success transaction.
 /// In other words, this is an upper bound on how many blocks we think it can take us to get a
 /// transaction confirmed (and we use it in a few more, equivalent, places).
-pub(crate) const CLTV_CLAIM_BUFFER: u32 = 6;
+pub(crate) const CLTV_CLAIM_BUFFER: u32 = 18;
 /// Number of blocks by which point we expect our counterparty to have seen new blocks on the
 /// network and done a full update_fail_htlc/commitment_signed dance (+ we've updated all our
 /// copies of ChannelMonitors, including watchtowers). We could enforce the contract by failing
@@ -219,13 +196,18 @@ pub(crate) const CLTV_CLAIM_BUFFER: u32 = 6;
 /// with at worst this delay, so we are not only using this value as a mercy for them but also
 /// us as a safeguard to delay with enough time.
 pub(crate) const LATENCY_GRACE_PERIOD_BLOCKS: u32 = 3;
-/// Number of blocks we wait on seeing a HTLC output being solved before we fail corresponding inbound
-/// HTLCs. This prevents us from failing backwards and then getting a reorg resulting in us losing money.
-/// We use also this delay to be sure we can remove our in-flight claim txn from bump candidates buffer.
-/// It may cause spurrious generation of bumped claim txn but that's allright given the outpoint is already
-/// solved by a previous claim tx. What we want to avoid is reorg evicting our claim tx and us not
-/// keeping bumping another claim tx to solve the outpoint.
-pub(crate) const ANTI_REORG_DELAY: u32 = 6;
+/// Number of blocks we wait on seeing a HTLC output being solved before we fail corresponding
+/// inbound HTLCs. This prevents us from failing backwards and then getting a reorg resulting in us
+/// losing money.
+///
+/// Note that this is a library-wide security assumption. If a reorg deeper than this number of
+/// blocks occurs, counterparties may be able to steal funds or claims made by and balances exposed
+/// by a  [`ChannelMonitor`] may be incorrect.
+// We also use this delay to be sure we can remove our in-flight claim txn from bump candidates buffer.
+// It may cause spurious generation of bumped claim txn but that's alright given the outpoint is already
+// solved by a previous claim tx. What we want to avoid is reorg evicting our claim tx and us not
+// keep bumping another claim tx to solve the outpoint.
+pub const ANTI_REORG_DELAY: u32 = 6;
 /// Number of blocks before confirmation at which we fail back an un-relayed HTLC or at which we
 /// refuse to accept a new HTLC.
 ///
@@ -235,8 +217,6 @@ pub(crate) const ANTI_REORG_DELAY: u32 = 6;
 ///    fail this HTLC,
 /// 2) if we receive an HTLC within this many blocks of its expiry (plus one to avoid a race
 ///    condition with the above), we will fail this HTLC without telling the user we received it,
-/// 3) if we are waiting on a connection or a channel state update to send an HTLC to a peer, and
-///    that HTLC expires within this many blocks, we will simply fail the HTLC instead.
 ///
 /// (1) is all about protecting us - we need enough time to update the channel state before we hit
 /// CLTV_CLAIM_BUFFER, at which point we'd go on chain to claim the HTLC with the preimage.
@@ -244,9 +224,6 @@ pub(crate) const ANTI_REORG_DELAY: u32 = 6;
 /// (2) is the same, but with an additional buffer to avoid accepting an HTLC which is immediately
 /// in a race condition between the user connecting a block (which would fail it) and the user
 /// providing us the preimage (which would claim it).
-///
-/// (3) is about our counterparty - we don't want to relay an HTLC to a counterparty when they may
-/// end up force-closing the channel on us to claim it.
 pub(crate) const HTLC_FAIL_BACK_BUFFER: u32 = CLTV_CLAIM_BUFFER + LATENCY_GRACE_PERIOD_BLOCKS;
 
 // TODO(devrandom) replace this with HolderCommitmentTransaction
@@ -259,212 +236,76 @@ struct HolderSignedTx {
        b_htlc_key: PublicKey,
        delayed_payment_key: PublicKey,
        per_commitment_point: PublicKey,
-       feerate_per_kw: u32,
        htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
+       to_self_value_sat: u64,
+       feerate_per_kw: u32,
 }
-
-/// We use this to track counterparty commitment transactions and htlcs outputs and
-/// use it to generate any justice or 2nd-stage preimage/timeout transactions.
+impl_writeable_tlv_based!(HolderSignedTx, {
+       (0, txid, required),
+       // Note that this is filled in with data from OnchainTxHandler if it's missing.
+       // For HolderSignedTx objects serialized with 0.0.100+, this should be filled in.
+       (1, to_self_value_sat, (default_value, u64::max_value())),
+       (2, revocation_key, required),
+       (4, a_htlc_key, required),
+       (6, b_htlc_key, required),
+       (8, delayed_payment_key, required),
+       (10, per_commitment_point, required),
+       (12, feerate_per_kw, required),
+       (14, htlc_outputs, vec_type)
+});
+
+/// We use this to track static counterparty commitment transaction data and to generate any
+/// justice or 2nd-stage preimage/timeout transactions.
 #[derive(PartialEq)]
-struct CounterpartyCommitmentTransaction {
+struct CounterpartyCommitmentParameters {
        counterparty_delayed_payment_base_key: PublicKey,
        counterparty_htlc_base_key: PublicKey,
        on_counterparty_tx_csv: u16,
-       per_htlc: HashMap<Txid, Vec<HTLCOutputInCommitment>>
 }
 
-impl Writeable for CounterpartyCommitmentTransaction {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
-               self.counterparty_delayed_payment_base_key.write(w)?;
-               self.counterparty_htlc_base_key.write(w)?;
-               w.write_all(&byte_utils::be16_to_array(self.on_counterparty_tx_csv))?;
-               w.write_all(&byte_utils::be64_to_array(self.per_htlc.len() as u64))?;
-               for (ref txid, ref htlcs) in self.per_htlc.iter() {
-                       w.write_all(&txid[..])?;
-                       w.write_all(&byte_utils::be64_to_array(htlcs.len() as u64))?;
-                       for &ref htlc in htlcs.iter() {
-                               htlc.write(w)?;
-                       }
-               }
+impl Writeable for CounterpartyCommitmentParameters {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               w.write_all(&byte_utils::be64_to_array(0))?;
+               write_tlv_fields!(w, {
+                       (0, self.counterparty_delayed_payment_base_key, required),
+                       (2, self.counterparty_htlc_base_key, required),
+                       (4, self.on_counterparty_tx_csv, required),
+               });
                Ok(())
        }
 }
-impl Readable for CounterpartyCommitmentTransaction {
-       fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
+impl Readable for CounterpartyCommitmentParameters {
+       fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
                let counterparty_commitment_transaction = {
-                       let counterparty_delayed_payment_base_key = Readable::read(r)?;
-                       let counterparty_htlc_base_key = Readable::read(r)?;
-                       let on_counterparty_tx_csv: u16 = Readable::read(r)?;
+                       // Versions prior to 0.0.100 had some per-HTLC state stored here, which is no longer
+                       // used. Read it for compatibility.
                        let per_htlc_len: u64 = Readable::read(r)?;
-                       let mut per_htlc = HashMap::with_capacity(cmp::min(per_htlc_len as usize, MAX_ALLOC_SIZE / 64));
                        for _  in 0..per_htlc_len {
-                               let txid: Txid = Readable::read(r)?;
+                               let _txid: Txid = Readable::read(r)?;
                                let htlcs_count: u64 = Readable::read(r)?;
-                               let mut htlcs = Vec::with_capacity(cmp::min(htlcs_count as usize, MAX_ALLOC_SIZE / 32));
                                for _ in 0..htlcs_count {
-                                       let htlc = Readable::read(r)?;
-                                       htlcs.push(htlc);
-                               }
-                               if let Some(_) = per_htlc.insert(txid, htlcs) {
-                                       return Err(DecodeError::InvalidValue);
+                                       let _htlc: HTLCOutputInCommitment = Readable::read(r)?;
                                }
                        }
-                       CounterpartyCommitmentTransaction {
-                               counterparty_delayed_payment_base_key,
-                               counterparty_htlc_base_key,
+
+                       let mut counterparty_delayed_payment_base_key = OptionDeserWrapper(None);
+                       let mut counterparty_htlc_base_key = OptionDeserWrapper(None);
+                       let mut on_counterparty_tx_csv: u16 = 0;
+                       read_tlv_fields!(r, {
+                               (0, counterparty_delayed_payment_base_key, required),
+                               (2, counterparty_htlc_base_key, required),
+                               (4, on_counterparty_tx_csv, required),
+                       });
+                       CounterpartyCommitmentParameters {
+                               counterparty_delayed_payment_base_key: counterparty_delayed_payment_base_key.0.unwrap(),
+                               counterparty_htlc_base_key: counterparty_htlc_base_key.0.unwrap(),
                                on_counterparty_tx_csv,
-                               per_htlc,
                        }
                };
                Ok(counterparty_commitment_transaction)
        }
 }
 
-/// When ChannelMonitor discovers an onchain outpoint being a step of a channel and that it needs
-/// to generate a tx to push channel state forward, we cache outpoint-solving tx material to build
-/// a new bumped one in case of lenghty confirmation delay
-#[derive(Clone, PartialEq)]
-pub(crate) enum InputMaterial {
-       Revoked {
-               per_commitment_point: PublicKey,
-               counterparty_delayed_payment_base_key: PublicKey,
-               counterparty_htlc_base_key: PublicKey,
-               per_commitment_key: SecretKey,
-               input_descriptor: InputDescriptors,
-               amount: u64,
-               htlc: Option<HTLCOutputInCommitment>,
-               on_counterparty_tx_csv: u16,
-       },
-       CounterpartyHTLC {
-               per_commitment_point: PublicKey,
-               counterparty_delayed_payment_base_key: PublicKey,
-               counterparty_htlc_base_key: PublicKey,
-               preimage: Option<PaymentPreimage>,
-               htlc: HTLCOutputInCommitment
-       },
-       HolderHTLC {
-               preimage: Option<PaymentPreimage>,
-               amount: u64,
-       },
-       Funding {
-               funding_redeemscript: Script,
-       }
-}
-
-impl Writeable for InputMaterial  {
-       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
-               match self {
-                       &InputMaterial::Revoked { ref per_commitment_point, ref counterparty_delayed_payment_base_key, ref counterparty_htlc_base_key, ref per_commitment_key, ref input_descriptor, ref amount, ref htlc, ref on_counterparty_tx_csv} => {
-                               writer.write_all(&[0; 1])?;
-                               per_commitment_point.write(writer)?;
-                               counterparty_delayed_payment_base_key.write(writer)?;
-                               counterparty_htlc_base_key.write(writer)?;
-                               writer.write_all(&per_commitment_key[..])?;
-                               input_descriptor.write(writer)?;
-                               writer.write_all(&byte_utils::be64_to_array(*amount))?;
-                               htlc.write(writer)?;
-                               on_counterparty_tx_csv.write(writer)?;
-                       },
-                       &InputMaterial::CounterpartyHTLC { ref per_commitment_point, ref counterparty_delayed_payment_base_key, ref counterparty_htlc_base_key, ref preimage, ref htlc} => {
-                               writer.write_all(&[1; 1])?;
-                               per_commitment_point.write(writer)?;
-                               counterparty_delayed_payment_base_key.write(writer)?;
-                               counterparty_htlc_base_key.write(writer)?;
-                               preimage.write(writer)?;
-                               htlc.write(writer)?;
-                       },
-                       &InputMaterial::HolderHTLC { ref preimage, ref amount } => {
-                               writer.write_all(&[2; 1])?;
-                               preimage.write(writer)?;
-                               writer.write_all(&byte_utils::be64_to_array(*amount))?;
-                       },
-                       &InputMaterial::Funding { ref funding_redeemscript } => {
-                               writer.write_all(&[3; 1])?;
-                               funding_redeemscript.write(writer)?;
-                       }
-               }
-               Ok(())
-       }
-}
-
-impl Readable for InputMaterial {
-       fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
-               let input_material = match <u8 as Readable>::read(reader)? {
-                       0 => {
-                               let per_commitment_point = Readable::read(reader)?;
-                               let counterparty_delayed_payment_base_key = Readable::read(reader)?;
-                               let counterparty_htlc_base_key = Readable::read(reader)?;
-                               let per_commitment_key = Readable::read(reader)?;
-                               let input_descriptor = Readable::read(reader)?;
-                               let amount = Readable::read(reader)?;
-                               let htlc = Readable::read(reader)?;
-                               let on_counterparty_tx_csv = Readable::read(reader)?;
-                               InputMaterial::Revoked {
-                                       per_commitment_point,
-                                       counterparty_delayed_payment_base_key,
-                                       counterparty_htlc_base_key,
-                                       per_commitment_key,
-                                       input_descriptor,
-                                       amount,
-                                       htlc,
-                                       on_counterparty_tx_csv
-                               }
-                       },
-                       1 => {
-                               let per_commitment_point = Readable::read(reader)?;
-                               let counterparty_delayed_payment_base_key = Readable::read(reader)?;
-                               let counterparty_htlc_base_key = Readable::read(reader)?;
-                               let preimage = Readable::read(reader)?;
-                               let htlc = Readable::read(reader)?;
-                               InputMaterial::CounterpartyHTLC {
-                                       per_commitment_point,
-                                       counterparty_delayed_payment_base_key,
-                                       counterparty_htlc_base_key,
-                                       preimage,
-                                       htlc
-                               }
-                       },
-                       2 => {
-                               let preimage = Readable::read(reader)?;
-                               let amount = Readable::read(reader)?;
-                               InputMaterial::HolderHTLC {
-                                       preimage,
-                                       amount,
-                               }
-                       },
-                       3 => {
-                               InputMaterial::Funding {
-                                       funding_redeemscript: Readable::read(reader)?,
-                               }
-                       }
-                       _ => return Err(DecodeError::InvalidValue),
-               };
-               Ok(input_material)
-       }
-}
-
-/// ClaimRequest is a descriptor structure to communicate between detection
-/// and reaction module. They are generated by ChannelMonitor while parsing
-/// onchain txn leaked from a channel and handed over to OnchainTxHandler which
-/// is responsible for opportunistic aggregation, selecting and enforcing
-/// bumping logic, building and signing transactions.
-pub(crate) struct ClaimRequest {
-       // Block height before which claiming is exclusive to one party,
-       // after reaching it, claiming may be contentious.
-       pub(crate) absolute_timelock: u32,
-       // Timeout tx must have nLocktime set which means aggregating multiple
-       // ones must take the higher nLocktime among them to satisfy all of them.
-       // Sadly it has few pitfalls, a) it takes longuer to get fund back b) CLTV_DELTA
-       // of a sooner-HTLC could be swallowed by the highest nLocktime of the HTLC set.
-       // Do simplify we mark them as non-aggregable.
-       pub(crate) aggregable: bool,
-       // Basic bitcoin outpoint (txid, vout)
-       pub(crate) outpoint: BitcoinOutPoint,
-       // Following outpoint type, set of data needed to generate transaction digest
-       // and satisfy witness program.
-       pub(crate) witness_data: InputMaterial
-}
-
 /// An entry for an [`OnchainEvent`], stating the block height when the event was observed and the
 /// transaction causing it.
 ///
@@ -478,11 +319,28 @@ struct OnchainEventEntry {
 
 impl OnchainEventEntry {
        fn confirmation_threshold(&self) -> u32 {
-               self.height + ANTI_REORG_DELAY - 1
+               let mut conf_threshold = self.height + ANTI_REORG_DELAY - 1;
+               match self.event {
+                       OnchainEvent::MaturingOutput {
+                               descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(ref descriptor)
+                       } => {
+                               // A CSV'd transaction is confirmable in block (input height) + CSV delay, which means
+                               // it's broadcastable when we see the previous block.
+                               conf_threshold = cmp::max(conf_threshold, self.height + descriptor.to_self_delay as u32 - 1);
+                       },
+                       OnchainEvent::FundingSpendConfirmation { on_local_output_csv: Some(csv), .. } |
+                       OnchainEvent::HTLCSpendConfirmation { on_to_local_output_csv: Some(csv), .. } => {
+                               // A CSV'd transaction is confirmable in block (input height) + CSV delay, which means
+                               // it's broadcastable when we see the previous block.
+                               conf_threshold = cmp::max(conf_threshold, self.height + csv as u32 - 1);
+                       },
+                       _ => {},
+               }
+               conf_threshold
        }
 
-       fn has_reached_confirmation_threshold(&self, height: u32) -> bool {
-               height >= self.confirmation_threshold()
+       fn has_reached_confirmation_threshold(&self, best_block: &BestBlock) -> bool {
+               best_block.height() >= self.confirmation_threshold()
        }
 }
 
@@ -490,21 +348,100 @@ impl OnchainEventEntry {
 /// once they mature to enough confirmations (ANTI_REORG_DELAY)
 #[derive(PartialEq)]
 enum OnchainEvent {
-       /// HTLC output getting solved by a timeout, at maturation we pass upstream payment source information to solve
-       /// inbound HTLC in backward channel. Note, in case of preimage, we pass info to upstream without delay as we can
-       /// only win from it, so it's never an OnchainEvent
+       /// An outbound HTLC failing after a transaction is confirmed. Used
+       ///  * when an outbound HTLC output is spent by us after the HTLC timed out
+       ///  * an outbound HTLC which was not present in the commitment transaction which appeared
+       ///    on-chain (either because it was not fully committed to or it was dust).
+       /// Note that this is *not* used for preimage claims, as those are passed upstream immediately,
+       /// appearing only as an `HTLCSpendConfirmation`, below.
        HTLCUpdate {
-               htlc_update: (HTLCSource, PaymentHash),
+               source: HTLCSource,
+               payment_hash: PaymentHash,
+               onchain_value_satoshis: Option<u64>,
+               /// None in the second case, above, ie when there is no relevant output in the commitment
+               /// transaction which appeared on chain.
+               input_idx: Option<u32>,
        },
        MaturingOutput {
                descriptor: SpendableOutputDescriptor,
        },
+       /// A spend of the funding output, either a commitment transaction or a cooperative closing
+       /// transaction.
+       FundingSpendConfirmation {
+               /// The CSV delay for the output of the funding spend transaction (implying it is a local
+               /// commitment transaction, and this is the delay on the to_self output).
+               on_local_output_csv: Option<u16>,
+       },
+       /// A spend of a commitment transaction HTLC output, set in the cases where *no* `HTLCUpdate`
+       /// is constructed. This is used when
+       ///  * an outbound HTLC is claimed by our counterparty with a preimage, causing us to
+       ///    immediately claim the HTLC on the inbound edge and track the resolution here,
+       ///  * an inbound HTLC is claimed by our counterparty (with a timeout),
+       ///  * an inbound HTLC is claimed by us (with a preimage).
+       ///  * a revoked-state HTLC transaction was broadcasted, which was claimed by the revocation
+       ///    signature.
+       HTLCSpendConfirmation {
+               input_idx: u32,
+               /// If the claim was made by either party with a preimage, this is filled in
+               preimage: Option<PaymentPreimage>,
+               /// If the claim was made by us on an inbound HTLC against a local commitment transaction,
+               /// we set this to the output CSV value which we will have to wait until to spend the
+               /// output (and generate a SpendableOutput event).
+               on_to_local_output_csv: Option<u16>,
+       },
 }
 
-const SERIALIZATION_VERSION: u8 = 1;
-const MIN_SERIALIZATION_VERSION: u8 = 1;
+impl Writeable for OnchainEventEntry {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               write_tlv_fields!(writer, {
+                       (0, self.txid, required),
+                       (2, self.height, required),
+                       (4, self.event, required),
+               });
+               Ok(())
+       }
+}
 
-#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
+impl MaybeReadable for OnchainEventEntry {
+       fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
+               let mut txid = Default::default();
+               let mut height = 0;
+               let mut event = None;
+               read_tlv_fields!(reader, {
+                       (0, txid, required),
+                       (2, height, required),
+                       (4, event, ignorable),
+               });
+               if let Some(ev) = event {
+                       Ok(Some(Self { txid, height, event: ev }))
+               } else {
+                       Ok(None)
+               }
+       }
+}
+
+impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
+       (0, HTLCUpdate) => {
+               (0, source, required),
+               (1, onchain_value_satoshis, option),
+               (2, payment_hash, required),
+               (3, input_idx, option),
+       },
+       (1, MaturingOutput) => {
+               (0, descriptor, required),
+       },
+       (3, FundingSpendConfirmation) => {
+               (0, on_local_output_csv, option),
+       },
+       (5, HTLCSpendConfirmation) => {
+               (0, input_idx, required),
+               (2, preimage, option),
+               (4, on_to_local_output_csv, option),
+       },
+
+);
+
+#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq))]
 #[derive(Clone)]
 pub(crate) enum ChannelMonitorUpdateStep {
        LatestHolderCommitmentTXInfo {
@@ -531,101 +468,116 @@ pub(crate) enum ChannelMonitorUpdateStep {
                /// think we've fallen behind!
                should_broadcast: bool,
        },
+       ShutdownScript {
+               scriptpubkey: Script,
+       },
 }
 
-impl Writeable for ChannelMonitorUpdateStep {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+impl ChannelMonitorUpdateStep {
+       fn variant_name(&self) -> &'static str {
                match self {
-                       &ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { ref commitment_tx, ref htlc_outputs } => {
-                               0u8.write(w)?;
-                               commitment_tx.write(w)?;
-                               (htlc_outputs.len() as u64).write(w)?;
-                               for &(ref output, ref signature, ref source) in htlc_outputs.iter() {
-                                       output.write(w)?;
-                                       signature.write(w)?;
-                                       source.write(w)?;
-                               }
-                       }
-                       &ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, ref htlc_outputs, ref commitment_number, ref their_revocation_point } => {
-                               1u8.write(w)?;
-                               commitment_txid.write(w)?;
-                               commitment_number.write(w)?;
-                               their_revocation_point.write(w)?;
-                               (htlc_outputs.len() as u64).write(w)?;
-                               for &(ref output, ref source) in htlc_outputs.iter() {
-                                       output.write(w)?;
-                                       source.as_ref().map(|b| b.as_ref()).write(w)?;
-                               }
-                       },
-                       &ChannelMonitorUpdateStep::PaymentPreimage { ref payment_preimage } => {
-                               2u8.write(w)?;
-                               payment_preimage.write(w)?;
-                       },
-                       &ChannelMonitorUpdateStep::CommitmentSecret { ref idx, ref secret } => {
-                               3u8.write(w)?;
-                               idx.write(w)?;
-                               secret.write(w)?;
-                       },
-                       &ChannelMonitorUpdateStep::ChannelForceClosed { ref should_broadcast } => {
-                               4u8.write(w)?;
-                               should_broadcast.write(w)?;
-                       },
+                       ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo",
+                       ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo",
+                       ChannelMonitorUpdateStep::PaymentPreimage { .. } => "PaymentPreimage",
+                       ChannelMonitorUpdateStep::CommitmentSecret { .. } => "CommitmentSecret",
+                       ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
+                       ChannelMonitorUpdateStep::ShutdownScript { .. } => "ShutdownScript",
                }
-               Ok(())
        }
 }
-impl Readable for ChannelMonitorUpdateStep {
-       fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
-               match Readable::read(r)? {
-                       0u8 => {
-                               Ok(ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
-                                       commitment_tx: Readable::read(r)?,
-                                       htlc_outputs: {
-                                               let len: u64 = Readable::read(r)?;
-                                               let mut res = Vec::new();
-                                               for _ in 0..len {
-                                                       res.push((Readable::read(r)?, Readable::read(r)?, Readable::read(r)?));
-                                               }
-                                               res
-                                       },
-                               })
-                       },
-                       1u8 => {
-                               Ok(ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo {
-                                       commitment_txid: Readable::read(r)?,
-                                       commitment_number: Readable::read(r)?,
-                                       their_revocation_point: Readable::read(r)?,
-                                       htlc_outputs: {
-                                               let len: u64 = Readable::read(r)?;
-                                               let mut res = Vec::new();
-                                               for _ in 0..len {
-                                                       res.push((Readable::read(r)?, <Option<HTLCSource> as Readable>::read(r)?.map(|o| Box::new(o))));
-                                               }
-                                               res
-                                       },
-                               })
-                       },
-                       2u8 => {
-                               Ok(ChannelMonitorUpdateStep::PaymentPreimage {
-                                       payment_preimage: Readable::read(r)?,
-                               })
-                       },
-                       3u8 => {
-                               Ok(ChannelMonitorUpdateStep::CommitmentSecret {
-                                       idx: Readable::read(r)?,
-                                       secret: Readable::read(r)?,
-                               })
-                       },
-                       4u8 => {
-                               Ok(ChannelMonitorUpdateStep::ChannelForceClosed {
-                                       should_broadcast: Readable::read(r)?
-                               })
-                       },
-                       _ => Err(DecodeError::InvalidValue),
-               }
-       }
+
+impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
+       (0, LatestHolderCommitmentTXInfo) => {
+               (0, commitment_tx, required),
+               (2, htlc_outputs, vec_type),
+       },
+       (1, LatestCounterpartyCommitmentTXInfo) => {
+               (0, commitment_txid, required),
+               (2, commitment_number, required),
+               (4, their_revocation_point, required),
+               (6, htlc_outputs, vec_type),
+       },
+       (2, PaymentPreimage) => {
+               (0, payment_preimage, required),
+       },
+       (3, CommitmentSecret) => {
+               (0, idx, required),
+               (2, secret, required),
+       },
+       (4, ChannelForceClosed) => {
+               (0, should_broadcast, required),
+       },
+       (5, ShutdownScript) => {
+               (0, scriptpubkey, required),
+       },
+);
+
+/// Details about the balance(s) available for spending once the channel appears on chain.
+///
+/// See [`ChannelMonitor::get_claimable_balances`] for more details on when these will or will not
+/// be provided.
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[cfg_attr(test, derive(PartialOrd, Ord))]
+pub enum Balance {
+       /// The channel is not yet closed (or the commitment or closing transaction has not yet
+       /// appeared in a block). The given balance is claimable (less on-chain fees) if the channel is
+       /// force-closed now.
+       ClaimableOnChannelClose {
+               /// The amount available to claim, in satoshis, excluding the on-chain fees which will be
+               /// required to do so.
+               claimable_amount_satoshis: u64,
+       },
+       /// The channel has been closed, and the given balance is ours but awaiting confirmations until
+       /// we consider it spendable.
+       ClaimableAwaitingConfirmations {
+               /// The amount available to claim, in satoshis, possibly excluding the on-chain fees which
+               /// were spent in broadcasting the transaction.
+               claimable_amount_satoshis: u64,
+               /// The height at which an [`Event::SpendableOutputs`] event will be generated for this
+               /// amount.
+               confirmation_height: u32,
+       },
+       /// The channel has been closed, and the given balance should be ours but awaiting spending
+       /// transaction confirmation. If the spending transaction does not confirm in time, it is
+       /// possible our counterparty can take the funds by broadcasting an HTLC timeout on-chain.
+       ///
+       /// Once the spending transaction confirms, before it has reached enough confirmations to be
+       /// considered safe from chain reorganizations, the balance will instead be provided via
+       /// [`Balance::ClaimableAwaitingConfirmations`].
+       ContentiousClaimable {
+               /// The amount available to claim, in satoshis, excluding the on-chain fees which will be
+               /// required to do so.
+               claimable_amount_satoshis: u64,
+               /// The height at which the counterparty may be able to claim the balance if we have not
+               /// done so.
+               timeout_height: u32,
+       },
+       /// HTLCs which we sent to our counterparty which are claimable after a timeout (less on-chain
+       /// fees) if the counterparty does not know the preimage for the HTLCs. These are somewhat
+       /// likely to be claimed by our counterparty before we do.
+       MaybeClaimableHTLCAwaitingTimeout {
+               /// The amount available to claim, in satoshis, excluding the on-chain fees which will be
+               /// required to do so.
+               claimable_amount_satoshis: u64,
+               /// The height at which we will be able to claim the balance if our counterparty has not
+               /// done so.
+               claimable_height: u32,
+       },
 }
 
+/// An HTLC which has been irrevocably resolved on-chain, and has reached ANTI_REORG_DELAY.
+#[derive(PartialEq)]
+struct IrrevocablyResolvedHTLC {
+       input_idx: u32,
+       /// Only set if the HTLC claim was ours using a payment preimage
+       payment_preimage: Option<PaymentPreimage>,
+}
+
+impl_writeable_tlv_based!(IrrevocablyResolvedHTLC, {
+       (0, input_idx, required),
+       (2, payment_preimage, option),
+});
+
 /// A ChannelMonitor handles chain events (blocks connected and disconnected) and generates
 /// on-chain transactions to ensure no loss of funds occurs.
 ///
@@ -656,7 +608,7 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
        destination_script: Script,
        broadcasted_holder_revokable_script: Option<(Script, PublicKey, PublicKey)>,
        counterparty_payment_script: Script,
-       shutdown_script: Script,
+       shutdown_script: Option<Script>,
 
        channel_keys_id: [u8; 32],
        holder_revocation_basepoint: PublicKey,
@@ -664,7 +616,7 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
        current_counterparty_commitment_txid: Option<Txid>,
        prev_counterparty_commitment_txid: Option<Txid>,
 
-       counterparty_tx_cache: CounterpartyCommitmentTransaction,
+       counterparty_commitment_params: CounterpartyCommitmentParameters,
        funding_redeemscript: Script,
        channel_value_satoshis: u64,
        // first is the idx of the first of the two revocation points
@@ -673,6 +625,9 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
        on_holder_tx_csv: u16,
 
        commitment_secrets: CounterpartyCommitmentSecrets,
+       /// The set of outpoints in each counterparty commitment transaction. We always need at least
+       /// the payment hash from `HTLCOutputInCommitment` to claim even a revoked commitment
+       /// transaction broadcast as we need to be able to construct the witness script in all cases.
        counterparty_claimable_outpoints: HashMap<Txid, Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>>,
        /// We cannot identify HTLC-Success or HTLC-Timeout transactions by themselves on the chain.
        /// Nor can we figure out their commitment numbers without the commitment transaction they are
@@ -702,7 +657,17 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
 
        payment_preimages: HashMap<PaymentHash, PaymentPreimage>,
 
+       // Note that `MonitorEvent`s MUST NOT be generated during update processing, only generated
+       // during chain data processing. This prevents a race in `ChainMonitor::update_channel` (and
+       // presumably user implementations thereof as well) where we update the in-memory channel
+       // object, then before the persistence finishes (as it's all under a read-lock), we return
+       // pending events to the user or to the relevant `ChannelManager`. Then, on reload, we'll have
+       // the pre-event state here, but have processed the event in the `ChannelManager`.
+       // Note that because the `event_lock` in `ChainMonitor` is only taken in
+       // block/transaction-connected events and *not* during block/transaction-disconnected events,
+       // we further MUST NOT generate events during block/transaction-disconnection.
        pending_monitor_events: Vec<MonitorEvent>,
+
        pending_events: Vec<Event>,
 
        // Used to track on-chain events (i.e., transactions part of channels confirmed on chain) on
@@ -735,6 +700,17 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
        // remote monitor out-of-order with regards to the block view.
        holder_tx_signed: bool,
 
+       // If a spend of the funding output is seen, we set this to true and reject any further
+       // updates. This prevents any further changes in the offchain state no matter the order
+       // of block connection between ChannelMonitors and the ChannelManager.
+       funding_spend_seen: bool,
+
+       funding_spend_confirmed: Option<Txid>,
+       /// The set of HTLCs which have been either claimed or failed on chain and have reached
+       /// the requisite confirmations on the claim/fail transaction (either ANTI_REORG_DELAY or the
+       /// spending CSV for revocable outputs).
+       htlcs_resolved_on_chain: Vec<IrrevocablyResolvedHTLC>,
+
        // We simply modify best_block in Channel's block_connected so that serialization is
        // consistent but hopefully the users' copy handles block_connected in a consistent way.
        // (we do *not*, however, update them in update_monitor to ensure any local user copies keep
@@ -748,9 +724,9 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
 /// Transaction outputs to watch for on-chain spends.
 pub type TransactionOutputs = (Txid, Vec<(u32, TxOut)>);
 
-#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
-/// Used only in testing and fuzztarget to check serialization roundtrips don't change the
-/// underlying object
+#[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();
@@ -759,9 +735,9 @@ impl<Signer: Sign> PartialEq for ChannelMonitor<Signer> {
        }
 }
 
-#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
-/// Used only in testing and fuzztarget to check serialization roundtrips don't change the
-/// underlying object
+#[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> {
        fn eq(&self, other: &Self) -> bool {
                if self.latest_update_id != other.latest_update_id ||
@@ -774,7 +750,7 @@ impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
                        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_tx_cache != other.counterparty_tx_cache ||
+                       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_revocation_points != other.their_cur_revocation_points ||
@@ -793,7 +769,10 @@ impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
                        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.holder_tx_signed != other.holder_tx_signed ||
+                       self.funding_spend_seen != other.funding_spend_seen ||
+                       self.funding_spend_confirmed != other.funding_spend_confirmed ||
+                       self.htlcs_resolved_on_chain != other.htlcs_resolved_on_chain
                {
                        false
                } else {
@@ -804,17 +783,18 @@ impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
 
 impl<Signer: Sign> Writeable for ChannelMonitor<Signer> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
-               //TODO: We still write out all the serialization here manually instead of using the fancy
-               //serialization framework we have, we should migrate things over to it.
-               writer.write_all(&[SERIALIZATION_VERSION; 1])?;
-               writer.write_all(&[MIN_SERIALIZATION_VERSION; 1])?;
-
                self.inner.lock().unwrap().write(writer)
        }
 }
 
+// These are also used for ChannelMonitorUpdate, above.
+const SERIALIZATION_VERSION: u8 = 1;
+const MIN_SERIALIZATION_VERSION: u8 = 1;
+
 impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
+               write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
+
                self.latest_update_id.write(writer)?;
 
                // Set in initial Channel-object creation, so should always be set by now:
@@ -831,7 +811,10 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                }
 
                self.counterparty_payment_script.write(writer)?;
-               self.shutdown_script.write(writer)?;
+               match &self.shutdown_script {
+                       Some(script) => script.write(writer)?,
+                       None => Script::new().write(writer)?,
+               }
 
                self.channel_keys_id.write(writer)?;
                self.holder_revocation_basepoint.write(writer)?;
@@ -841,7 +824,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                self.current_counterparty_commitment_txid.write(writer)?;
                self.prev_counterparty_commitment_txid.write(writer)?;
 
-               self.counterparty_tx_cache.write(writer)?;
+               self.counterparty_commitment_params.write(writer)?;
                self.funding_redeemscript.write(writer)?;
                self.channel_value_satoshis.write(writer)?;
 
@@ -899,38 +882,14 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                        writer.write_all(&byte_utils::be48_to_array(*commitment_number))?;
                }
 
-               macro_rules! serialize_holder_tx {
-                       ($holder_tx: expr) => {
-                               $holder_tx.txid.write(writer)?;
-                               writer.write_all(&$holder_tx.revocation_key.serialize())?;
-                               writer.write_all(&$holder_tx.a_htlc_key.serialize())?;
-                               writer.write_all(&$holder_tx.b_htlc_key.serialize())?;
-                               writer.write_all(&$holder_tx.delayed_payment_key.serialize())?;
-                               writer.write_all(&$holder_tx.per_commitment_point.serialize())?;
-
-                               writer.write_all(&byte_utils::be32_to_array($holder_tx.feerate_per_kw))?;
-                               writer.write_all(&byte_utils::be64_to_array($holder_tx.htlc_outputs.len() as u64))?;
-                               for &(ref htlc_output, ref sig, ref htlc_source) in $holder_tx.htlc_outputs.iter() {
-                                       serialize_htlc_in_commitment!(htlc_output);
-                                       if let &Some(ref their_sig) = sig {
-                                               1u8.write(writer)?;
-                                               writer.write_all(&their_sig.serialize_compact())?;
-                                       } else {
-                                               0u8.write(writer)?;
-                                       }
-                                       htlc_source.write(writer)?;
-                               }
-                       }
-               }
-
                if let Some(ref prev_holder_tx) = self.prev_holder_signed_commitment_tx {
                        writer.write_all(&[1; 1])?;
-                       serialize_holder_tx!(prev_holder_tx);
+                       prev_holder_tx.write(writer)?;
                } else {
                        writer.write_all(&[0; 1])?;
                }
 
-               serialize_holder_tx!(self.current_holder_commitment_tx);
+               self.current_holder_commitment_tx.write(writer)?;
 
                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))?;
@@ -940,14 +899,19 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                        writer.write_all(&payment_preimage.0[..])?;
                }
 
-               writer.write_all(&byte_utils::be64_to_array(self.pending_monitor_events.len() as u64))?;
+               writer.write_all(&(self.pending_monitor_events.iter().filter(|ev| match ev {
+                       MonitorEvent::HTLCEvent(_) => true,
+                       MonitorEvent::CommitmentTxConfirmed(_) => true,
+                       _ => false,
+               }).count() as u64).to_be_bytes())?;
                for event in self.pending_monitor_events.iter() {
                        match event {
                                MonitorEvent::HTLCEvent(upd) => {
                                        0u8.write(writer)?;
                                        upd.write(writer)?;
                                },
-                               MonitorEvent::CommitmentTxBroadcasted(_) => 1u8.write(writer)?
+                               MonitorEvent::CommitmentTxConfirmed(_) => 1u8.write(writer)?,
+                               _ => {}, // Covered in the TLV writes below
                        }
                }
 
@@ -961,19 +925,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
 
                writer.write_all(&byte_utils::be64_to_array(self.onchain_events_awaiting_threshold_conf.len() as u64))?;
                for ref entry in self.onchain_events_awaiting_threshold_conf.iter() {
-                       entry.txid.write(writer)?;
-                       writer.write_all(&byte_utils::be32_to_array(entry.height))?;
-                       match entry.event {
-                               OnchainEvent::HTLCUpdate { ref htlc_update } => {
-                                       0u8.write(writer)?;
-                                       htlc_update.0.write(writer)?;
-                                       htlc_update.1.write(writer)?;
-                               },
-                               OnchainEvent::MaturingOutput { ref descriptor } => {
-                                       1u8.write(writer)?;
-                                       descriptor.write(writer)?;
-                               },
-                       }
+                       entry.write(writer)?;
                }
 
                (self.outputs_to_watch.len() as u64).write(writer)?;
@@ -990,12 +942,19 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
                self.lockdown_from_offchain.write(writer)?;
                self.holder_tx_signed.write(writer)?;
 
+               write_tlv_fields!(writer, {
+                       (1, self.funding_spend_confirmed, option),
+                       (3, self.htlcs_resolved_on_chain, vec_type),
+                       (5, self.pending_monitor_events, vec_type),
+                       (7, self.funding_spend_seen, required),
+               });
+
                Ok(())
        }
 }
 
 impl<Signer: Sign> ChannelMonitor<Signer> {
-       pub(crate) fn new(secp_ctx: Secp256k1<secp256k1::All>, keys: Signer, shutdown_pubkey: &PublicKey,
+       pub(crate) fn new(secp_ctx: Secp256k1<secp256k1::All>, keys: Signer, shutdown_script: Option<Script>,
                          on_counterparty_tx_csv: u16, destination_script: &Script, funding_info: (OutPoint, Script),
                          channel_parameters: &ChannelTransactionParameters,
                          funding_redeemscript: Script, channel_value_satoshis: u64,
@@ -1004,15 +963,13 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                          best_block: BestBlock) -> ChannelMonitor<Signer> {
 
                assert!(commitment_transaction_number_obscure_factor <= (1 << 48));
-               let our_channel_close_key_hash = WPubkeyHash::hash(&shutdown_pubkey.serialize());
-               let shutdown_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_close_key_hash[..]).into_script();
                let payment_key_hash = WPubkeyHash::hash(&keys.pubkeys().payment_point.serialize());
                let counterparty_payment_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_key_hash[..]).into_script();
 
                let counterparty_channel_parameters = channel_parameters.counterparty_parameters.as_ref().unwrap();
                let counterparty_delayed_payment_base_key = counterparty_channel_parameters.pubkeys.delayed_payment_basepoint;
                let counterparty_htlc_base_key = counterparty_channel_parameters.pubkeys.htlc_basepoint;
-               let counterparty_tx_cache = CounterpartyCommitmentTransaction { counterparty_delayed_payment_base_key, counterparty_htlc_base_key, on_counterparty_tx_csv, per_htlc: HashMap::new() };
+               let counterparty_commitment_params = CounterpartyCommitmentParameters { counterparty_delayed_payment_base_key, counterparty_htlc_base_key, on_counterparty_tx_csv };
 
                let channel_keys_id = keys.channel_keys_id();
                let holder_revocation_basepoint = keys.pubkeys().revocation_basepoint;
@@ -1030,8 +987,9 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                                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,
-                               feerate_per_kw: trusted_tx.feerate_per_kw(),
                                htlc_outputs: Vec::new(), // There are never any HTLCs in the initial commitment transactions
+                               to_self_value_sat: initial_holder_commitment_tx.to_broadcaster_value_sat(),
+                               feerate_per_kw: trusted_tx.feerate_per_kw(),
                        };
                        (holder_commitment_tx, trusted_tx.commitment_number())
                };
@@ -1059,7 +1017,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                                current_counterparty_commitment_txid: None,
                                prev_counterparty_commitment_txid: None,
 
-                               counterparty_tx_cache,
+                               counterparty_commitment_params,
                                funding_redeemscript,
                                channel_value_satoshis,
                                their_cur_revocation_points: None,
@@ -1087,6 +1045,9 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
 
                                lockdown_from_offchain: false,
                                holder_tx_signed: false,
+                               funding_spend_seen: false,
+                               funding_spend_confirmed: None,
+                               htlcs_resolved_on_chain: Vec::new(),
 
                                best_block,
 
@@ -1096,7 +1057,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
        }
 
        #[cfg(test)]
-       fn provide_secret(&self, idx: u64, secret: [u8; 32]) -> Result<(), MonitorUpdateError> {
+       fn provide_secret(&self, idx: u64, secret: [u8; 32]) -> Result<(), &'static str> {
                self.inner.lock().unwrap().provide_secret(idx, secret)
        }
 
@@ -1118,12 +1079,10 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
 
        #[cfg(test)]
        fn provide_latest_holder_commitment_tx(
-               &self,
-               holder_commitment_tx: HolderCommitmentTransaction,
+               &self, holder_commitment_tx: HolderCommitmentTransaction,
                htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
-       ) -> Result<(), MonitorUpdateError> {
-               self.inner.lock().unwrap().provide_latest_holder_commitment_tx(
-                       holder_commitment_tx, htlc_outputs)
+       ) -> Result<(), ()> {
+               self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs).map_err(|_| ())
        }
 
        #[cfg(test)]
@@ -1164,7 +1123,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                broadcaster: &B,
                fee_estimator: &F,
                logger: &L,
-       ) -> Result<(), MonitorUpdateError>
+       ) -> Result<(), ()>
        where
                B::Target: BroadcasterInterface,
                F::Target: FeeEstimator,
@@ -1389,15 +1348,374 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                txids.dedup();
                txids
        }
+
+       /// Gets the latest best block which was connected either via the [`chain::Listen`] or
+       /// [`chain::Confirm`] interfaces.
+       pub fn current_best_block(&self) -> BestBlock {
+               self.inner.lock().unwrap().best_block.clone()
+       }
+
+       /// 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).
+       ///
+       /// Any balances in the channel which are available on-chain (excluding on-chain fees) are
+       /// included here until an [`Event::SpendableOutputs`] event has been generated for the
+       /// balance, or until our counterparty has claimed the balance and accrued several
+       /// confirmations on the claim transaction.
+       ///
+       /// Note that the balances available when you or your counterparty have broadcasted revoked
+       /// state(s) may not be fully captured here.
+       // TODO, fix that ^
+       ///
+       /// See [`Balance`] for additional details on the types of claimable balances which
+       /// may be returned here and their meanings.
+       pub fn get_claimable_balances(&self) -> Vec<Balance> {
+               let mut res = Vec::new();
+               let us = self.inner.lock().unwrap();
+
+               let mut confirmed_txid = us.funding_spend_confirmed;
+               let mut pending_commitment_tx_conf_thresh = None;
+               let funding_spend_pending = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
+                       if let OnchainEvent::FundingSpendConfirmation { .. } = event.event {
+                               Some((event.txid, event.confirmation_threshold()))
+                       } else { None }
+               });
+               if let Some((txid, conf_thresh)) = funding_spend_pending {
+                       debug_assert!(us.funding_spend_confirmed.is_none(),
+                               "We have a pending funding spend awaiting anti-reorg confirmation, we can't have confirmed it already!");
+                       confirmed_txid = Some(txid);
+                       pending_commitment_tx_conf_thresh = Some(conf_thresh);
+               }
+
+               macro_rules! walk_htlcs {
+                       ($holder_commitment: expr, $htlc_iter: expr) => {
+                               for htlc in $htlc_iter {
+                                       if let Some(htlc_input_idx) = htlc.transaction_output_index {
+                                               if let Some(conf_thresh) = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
+                                                       if let OnchainEvent::MaturingOutput { descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) } = &event.event {
+                                                               if descriptor.outpoint.index as u32 == htlc_input_idx { Some(event.confirmation_threshold()) } else { None }
+                                                       } else { None }
+                                               }) {
+                                                       debug_assert!($holder_commitment);
+                                                       res.push(Balance::ClaimableAwaitingConfirmations {
+                                                               claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                               confirmation_height: conf_thresh,
+                                                       });
+                                               } else if us.htlcs_resolved_on_chain.iter().any(|v| v.input_idx == htlc_input_idx) {
+                                                       // Funding transaction spends should be fully confirmed by the time any
+                                                       // HTLC transactions are resolved, unless we're talking about a holder
+                                                       // commitment tx, whose resolution is delayed until the CSV timeout is
+                                                       // reached, even though HTLCs may be resolved after only
+                                                       // ANTI_REORG_DELAY confirmations.
+                                                       debug_assert!($holder_commitment || us.funding_spend_confirmed.is_some());
+                                               } else if htlc.offered == $holder_commitment {
+                                                       // If the payment was outbound, check if there's an HTLCUpdate
+                                                       // indicating we have spent this HTLC with a timeout, claiming it back
+                                                       // and awaiting confirmations on it.
+                                                       let htlc_update_pending = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
+                                                               if let OnchainEvent::HTLCUpdate { input_idx: Some(input_idx), .. } = event.event {
+                                                                       if input_idx == htlc_input_idx { Some(event.confirmation_threshold()) } else { None }
+                                                               } else { None }
+                                                       });
+                                                       if let Some(conf_thresh) = htlc_update_pending {
+                                                               res.push(Balance::ClaimableAwaitingConfirmations {
+                                                                       claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                                       confirmation_height: conf_thresh,
+                                                               });
+                                                       } else {
+                                                               res.push(Balance::MaybeClaimableHTLCAwaitingTimeout {
+                                                                       claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                                       claimable_height: htlc.cltv_expiry,
+                                                               });
+                                                       }
+                                               } else if us.payment_preimages.get(&htlc.payment_hash).is_some() {
+                                                       // Otherwise (the payment was inbound), only expose it as claimable if
+                                                       // we know the preimage.
+                                                       // Note that if there is a pending claim, but it did not use the
+                                                       // preimage, we lost funds to our counterparty! We will then continue
+                                                       // to show it as ContentiousClaimable until ANTI_REORG_DELAY.
+                                                       let htlc_spend_pending = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
+                                                               if let OnchainEvent::HTLCSpendConfirmation { input_idx, preimage, .. } = event.event {
+                                                                       if input_idx == htlc_input_idx {
+                                                                               Some((event.confirmation_threshold(), preimage.is_some()))
+                                                                       } else { None }
+                                                               } else { None }
+                                                       });
+                                                       if let Some((conf_thresh, true)) = htlc_spend_pending {
+                                                               res.push(Balance::ClaimableAwaitingConfirmations {
+                                                                       claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                                       confirmation_height: conf_thresh,
+                                                               });
+                                                       } else {
+                                                               res.push(Balance::ContentiousClaimable {
+                                                                       claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                                                       timeout_height: htlc.cltv_expiry,
+                                                               });
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               if let Some(txid) = confirmed_txid {
+                       let mut found_commitment_tx = false;
+                       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().map(|(a, _)| a));
+                               if let Some(conf_thresh) = pending_commitment_tx_conf_thresh {
+                                       if let Some(value) = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
+                                               if let OnchainEvent::MaturingOutput {
+                                                       descriptor: SpendableOutputDescriptor::StaticPaymentOutput(descriptor)
+                                               } = &event.event {
+                                                       Some(descriptor.output.value)
+                                               } else { None }
+                                       }) {
+                                               res.push(Balance::ClaimableAwaitingConfirmations {
+                                                       claimable_amount_satoshis: value,
+                                                       confirmation_height: conf_thresh,
+                                               });
+                                       } else {
+                                               // If a counterparty commitment transaction is awaiting confirmation, we
+                                               // should either have a StaticPaymentOutput MaturingOutput event awaiting
+                                               // confirmation with the same height or have never met our dust amount.
+                                       }
+                               }
+                               found_commitment_tx = true;
+                       } else if txid == us.current_holder_commitment_tx.txid {
+                               walk_htlcs!(true, us.current_holder_commitment_tx.htlc_outputs.iter().map(|(a, _, _)| a));
+                               if let Some(conf_thresh) = pending_commitment_tx_conf_thresh {
+                                       res.push(Balance::ClaimableAwaitingConfirmations {
+                                               claimable_amount_satoshis: us.current_holder_commitment_tx.to_self_value_sat,
+                                               confirmation_height: conf_thresh,
+                                       });
+                               }
+                               found_commitment_tx = true;
+                       } 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().map(|(a, _, _)| a));
+                                       if let Some(conf_thresh) = pending_commitment_tx_conf_thresh {
+                                               res.push(Balance::ClaimableAwaitingConfirmations {
+                                                       claimable_amount_satoshis: prev_commitment.to_self_value_sat,
+                                                       confirmation_height: conf_thresh,
+                                               });
+                                       }
+                                       found_commitment_tx = true;
+                               }
+                       }
+                       if !found_commitment_tx {
+                               if let Some(conf_thresh) = pending_commitment_tx_conf_thresh {
+                                       // We blindly assume this is a cooperative close transaction here, and that
+                                       // neither us nor our counterparty misbehaved. At worst we've under-estimated
+                                       // the amount we can claim as we'll punish a misbehaving counterparty.
+                                       res.push(Balance::ClaimableAwaitingConfirmations {
+                                               claimable_amount_satoshis: us.current_holder_commitment_tx.to_self_value_sat,
+                                               confirmation_height: conf_thresh,
+                                       });
+                               }
+                       }
+                       // TODO: Add logic to provide claimable balances for counterparty broadcasting revoked
+                       // outputs.
+               } else {
+                       let mut claimable_inbound_htlc_value_sat = 0;
+                       for (htlc, _, _) in us.current_holder_commitment_tx.htlc_outputs.iter() {
+                               if htlc.transaction_output_index.is_none() { continue; }
+                               if htlc.offered {
+                                       res.push(Balance::MaybeClaimableHTLCAwaitingTimeout {
+                                               claimable_amount_satoshis: htlc.amount_msat / 1000,
+                                               claimable_height: htlc.cltv_expiry,
+                                       });
+                               } else if us.payment_preimages.get(&htlc.payment_hash).is_some() {
+                                       claimable_inbound_htlc_value_sat += htlc.amount_msat / 1000;
+                               }
+                       }
+                       res.push(Balance::ClaimableOnChannelClose {
+                               claimable_amount_satoshis: us.current_holder_commitment_tx.to_self_value_sat + claimable_inbound_htlc_value_sat,
+                       });
+               }
+
+               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> {
+               let mut res = HashMap::new();
+               let us = self.inner.lock().unwrap();
+
+               macro_rules! walk_htlcs {
+                       ($holder_commitment: expr, $htlc_iter: expr) => {
+                               for (htlc, source) in $htlc_iter {
+                                       if us.htlcs_resolved_on_chain.iter().any(|v| Some(v.input_idx) == htlc.transaction_output_index) {
+                                               // We should assert that funding_spend_confirmed is_some() here, but we
+                                               // have some unit tests which violate HTLC transaction CSVs entirely and
+                                               // would fail.
+                                               // TODO: Once tests all connect transactions at consensus-valid times, we
+                                               // should assert here like we do in `get_claimable_balances`.
+                                       } else if htlc.offered == $holder_commitment {
+                                               // If the payment was outbound, check if there's an HTLCUpdate
+                                               // indicating we have spent this HTLC with a timeout, claiming it back
+                                               // and awaiting confirmations on it.
+                                               let htlc_update_confd = us.onchain_events_awaiting_threshold_conf.iter().any(|event| {
+                                                       if let OnchainEvent::HTLCUpdate { input_idx: Some(input_idx), .. } = event.event {
+                                                               // If the HTLC was timed out, we wait for ANTI_REORG_DELAY blocks
+                                                               // before considering it "no longer pending" - this matches when we
+                                                               // provide the ChannelManager an HTLC failure event.
+                                                               Some(input_idx) == htlc.transaction_output_index &&
+                                                                       us.best_block.height() >= event.height + ANTI_REORG_DELAY - 1
+                                                       } else if let OnchainEvent::HTLCSpendConfirmation { input_idx, .. } = event.event {
+                                                               // If the HTLC was fulfilled with a preimage, we consider the HTLC
+                                                               // immediately non-pending, matching when we provide ChannelManager
+                                                               // the preimage.
+                                                               Some(input_idx) == htlc.transaction_output_index
+                                                       } else { false }
+                                               });
+                                               if !htlc_update_confd {
+                                                       res.insert(source.clone(), htlc.clone());
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // 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 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)| {
+                                       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);
+                       }
+               }
+
+               res
+       }
+}
+
+/// Compares a broadcasted commitment transaction's HTLCs with those in the latest state,
+/// failing any HTLCs which didn't make it into the broadcasted commitment transaction back
+/// after ANTI_REORG_DELAY blocks.
+///
+/// We always compare against the set of HTLCs in counterparty commitment transactions, as those
+/// are the commitment transactions which are generated by us. The off-chain state machine in
+/// `Channel` will automatically resolve any HTLCs which were never included in a commitment
+/// transaction when it detects channel closure, but it is up to us to ensure any HTLCs which were
+/// included in a remote commitment transaction are failed back if they are not present in the
+/// broadcasted commitment transaction.
+///
+/// Specifically, the removal process for HTLCs in `Channel` is always based on the counterparty
+/// sending a `revoke_and_ack`, which causes us to clear `prev_counterparty_commitment_txid`. Thus,
+/// as long as we examine both the current counterparty commitment transaction and, if it hasn't
+/// been revoked yet, the previous one, we we will never "forget" to resolve an HTLC.
+macro_rules! fail_unbroadcast_htlcs {
+       ($self: expr, $commitment_tx_type: expr, $commitment_tx_conf_height: expr, $confirmed_htlcs_list: expr, $logger: expr) => { {
+               macro_rules! check_htlc_fails {
+                       ($txid: expr, $commitment_tx: expr) => {
+                               if let Some(ref latest_outpoints) = $self.counterparty_claimable_outpoints.get($txid) {
+                                       for &(ref htlc, ref source_option) in latest_outpoints.iter() {
+                                               if let &Some(ref source) = source_option {
+                                                       // Check if the HTLC is present in the commitment transaction that was
+                                                       // broadcast, but not if it was below the dust limit, which we should
+                                                       // fail backwards immediately as there is no way for us to learn the
+                                                       // payment_preimage.
+                                                       // Note that if the dust limit were allowed to change between
+                                                       // commitment transactions we'd want to be check whether *any*
+                                                       // broadcastable commitment transaction has the HTLC in it, but it
+                                                       // cannot currently change after channel initialization, so we don't
+                                                       // need to here.
+                                                       let confirmed_htlcs_iter: &mut Iterator<Item = (&HTLCOutputInCommitment, Option<&HTLCSource>)> = &mut $confirmed_htlcs_list;
+                                                       let mut matched_htlc = false;
+                                                       for (ref broadcast_htlc, ref broadcast_source) in confirmed_htlcs_iter {
+                                                               if broadcast_htlc.transaction_output_index.is_some() && Some(&**source) == *broadcast_source {
+                                                                       matched_htlc = true;
+                                                                       break;
+                                                               }
+                                                       }
+                                                       if matched_htlc { continue; }
+                                                       $self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
+                                                               if entry.height != $commitment_tx_conf_height { return true; }
+                                                               match entry.event {
+                                                                       OnchainEvent::HTLCUpdate { source: ref update_source, .. } => {
+                                                                               *update_source != **source
+                                                                       },
+                                                                       _ => true,
+                                                               }
+                                                       });
+                                                       let entry = OnchainEventEntry {
+                                                               txid: *$txid,
+                                                               height: $commitment_tx_conf_height,
+                                                               event: OnchainEvent::HTLCUpdate {
+                                                                       source: (**source).clone(),
+                                                                       payment_hash: htlc.payment_hash.clone(),
+                                                                       onchain_value_satoshis: Some(htlc.amount_msat / 1000),
+                                                                       input_idx: None,
+                                                               },
+                                                       };
+                                                       log_trace!($logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of {} commitment transaction, waiting for confirmation (at height {})",
+                                                               log_bytes!(htlc.payment_hash.0), $commitment_tx, $commitment_tx_type, entry.confirmation_threshold());
+                                                       $self.onchain_events_awaiting_threshold_conf.push(entry);
+                                               }
+                                       }
+                               }
+                       }
+               }
+               if let Some(ref txid) = $self.current_counterparty_commitment_txid {
+                       check_htlc_fails!(txid, "current");
+               }
+               if let Some(ref txid) = $self.prev_counterparty_commitment_txid {
+                       check_htlc_fails!(txid, "previous");
+               }
+       } }
 }
 
 impl<Signer: Sign> 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).
-       fn provide_secret(&mut self, idx: u64, secret: [u8; 32]) -> Result<(), MonitorUpdateError> {
+       fn provide_secret(&mut self, idx: u64, secret: [u8; 32]) -> Result<(), &'static str> {
                if let Err(()) = self.commitment_secrets.provide_secret(idx, secret) {
-                       return Err(MonitorUpdateError("Previous secret did not match new one"));
+                       return Err("Previous secret did not match new one");
                }
 
                // Prune HTLCs from the previous counterparty commitment tx so we don't generate failure/fulfill
@@ -1482,7 +1800,6 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                htlcs.push(htlc.0);
                        }
                }
-               self.counterparty_tx_cache.per_htlc.insert(txid, htlcs);
        }
 
        /// Informs this monitor of the latest holder (ie broadcastable) commitment transaction. The
@@ -1490,7 +1807,7 @@ 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<(), MonitorUpdateError> {
+       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();
@@ -1504,15 +1821,16 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                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,
-                               feerate_per_kw: trusted_tx.feerate_per_kw(),
                                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);
                if self.holder_tx_signed {
-                       return Err(MonitorUpdateError("Latest holder commitment signed has already been signed, update is rejected"));
+                       return Err("Latest holder commitment signed has already been signed, update is rejected");
                }
                Ok(())
        }
@@ -1531,7 +1849,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                macro_rules! claim_htlcs {
                        ($commitment_number: expr, $txid: expr) => {
                                let htlc_claim_reqs = self.get_counterparty_htlc_output_claim_reqs($commitment_number, $txid, None);
-                               self.onchain_tx_handler.update_claims_view(&Vec::new(), htlc_claim_reqs, None, broadcaster, fee_estimator, logger);
+                               self.onchain_tx_handler.update_claims_view(&Vec::new(), htlc_claim_reqs, self.best_block.height(), self.best_block.height(), broadcaster, fee_estimator, logger);
                        }
                }
                if let Some(txid) = self.current_counterparty_commitment_txid {
@@ -1553,11 +1871,14 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                // *we* sign a holder commitment transaction, not when e.g. a watchtower broadcasts one of our
                // holder commitment transactions.
                if self.broadcasted_holder_revokable_script.is_some() {
-                       let (claim_reqs, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx);
-                       self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, None, broadcaster, fee_estimator, logger);
+                       // Assume that the broadcasted commitment transaction confirmed in the current best
+                       // block. Even if not, its a reasonable metric for the bump criteria on the HTLC
+                       // transactions.
+                       let (claim_reqs, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height());
+                       self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, self.best_block.height(), self.best_block.height(), broadcaster, fee_estimator, logger);
                        if let Some(ref tx) = self.prev_holder_signed_commitment_tx {
-                               let (claim_reqs, _) = self.get_broadcasted_holder_claims(&tx);
-                               self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, None, broadcaster, fee_estimator, logger);
+                               let (claim_reqs, _) = self.get_broadcasted_holder_claims(&tx, self.best_block.height());
+                               self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, self.best_block.height(), self.best_block.height(), broadcaster, fee_estimator, logger);
                        }
                }
        }
@@ -1567,35 +1888,46 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        L::Target: Logger,
        {
                for tx in self.get_latest_holder_commitment_txn(logger).iter() {
+                       log_info!(logger, "Broadcasting local {}", log_tx!(tx));
                        broadcaster.broadcast_transaction(tx);
                }
-               self.pending_monitor_events.push(MonitorEvent::CommitmentTxBroadcasted(self.funding_info.0));
+               self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0));
        }
 
-       pub fn update_monitor<B: Deref, F: Deref, L: Deref>(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: &F, logger: &L) -> Result<(), MonitorUpdateError>
+       pub fn update_monitor<B: Deref, F: Deref, L: Deref>(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: &F, logger: &L) -> Result<(), ()>
        where B::Target: BroadcasterInterface,
                    F::Target: FeeEstimator,
                    L::Target: Logger,
        {
+               log_info!(logger, "Applying update to monitor {}, bringing update_id from {} to {} with {} changes.",
+                       log_funding_info!(self), self.latest_update_id, updates.update_id, updates.updates.len());
                // ChannelMonitor updates may be applied after force close if we receive a
                // preimage for a broadcasted commitment transaction HTLC output that we'd
                // like to claim on-chain. If this is the case, we no longer have guaranteed
                // access to the monitor's update ID, so we use a sentinel value instead.
                if updates.update_id == CLOSED_CHANNEL_UPDATE_ID {
+                       assert_eq!(updates.updates.len(), 1);
                        match updates.updates[0] {
                                ChannelMonitorUpdateStep::PaymentPreimage { .. } => {},
-                               _ => panic!("Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage"),
+                               _ => {
+                                       log_error!(logger, "Attempted to apply post-force-close ChannelMonitorUpdate of type {}", updates.updates[0].variant_name());
+                                       panic!("Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage");
+                               },
                        }
-                       assert_eq!(updates.updates.len(), 1);
                } else if self.latest_update_id + 1 != updates.update_id {
                        panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!");
                }
+               let mut ret = Ok(());
                for update in updates.updates.iter() {
                        match update {
                                ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs } => {
                                        log_trace!(logger, "Updating ChannelMonitor with latest holder commitment transaction info");
                                        if self.lockdown_from_offchain { panic!(); }
-                                       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()) {
+                                               log_error!(logger, "Providing latest holder commitment transaction failed/was refused:");
+                                               log_error!(logger, "    {}", e);
+                                               ret = Err(());
+                                       }
                                }
                                ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_revocation_point } => {
                                        log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
@@ -1607,7 +1939,11 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                },
                                ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => {
                                        log_trace!(logger, "Updating ChannelMonitor with commitment secret");
-                                       self.provide_secret(*idx, *secret)?
+                                       if let Err(e) = self.provide_secret(*idx, *secret) {
+                                               log_error!(logger, "Providing latest counterparty commitment secret failed/was refused:");
+                                               log_error!(logger, "    {}", e);
+                                               ret = Err(());
+                                       }
                                },
                                ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => {
                                        log_trace!(logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}", should_broadcast);
@@ -1617,16 +1953,26 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        } else if !self.holder_tx_signed {
                                                log_error!(logger, "You have a toxic holder commitment transaction avaible in channel monitor, read comment in ChannelMonitor::get_latest_holder_commitment_txn to be informed of manual action to take");
                                        } else {
-                                               // If we generated a MonitorEvent::CommitmentTxBroadcasted, the ChannelManager
+                                               // If we generated a MonitorEvent::CommitmentTxConfirmed, the ChannelManager
                                                // will still give us a ChannelForceClosed event with !should_broadcast, but we
                                                // shouldn't print the scary warning above.
                                                log_info!(logger, "Channel off-chain state closed after we broadcasted our latest commitment transaction.");
                                        }
-                               }
+                               },
+                               ChannelMonitorUpdateStep::ShutdownScript { scriptpubkey } => {
+                                       log_trace!(logger, "Updating ChannelMonitor with shutdown script");
+                                       if let Some(shutdown_script) = self.shutdown_script.replace(scriptpubkey.clone()) {
+                                               panic!("Attempted to replace shutdown script {} with {}", shutdown_script, scriptpubkey);
+                                       }
+                               },
                        }
                }
                self.latest_update_id = updates.update_id;
-               Ok(())
+
+               if ret.is_ok() && self.funding_spend_seen {
+                       log_error!(logger, "Refusing Channel Monitor Update as counterparty attempted to update commitment after funding was spent");
+                       Err(())
+               } else { ret }
        }
 
        pub fn get_latest_update_id(&self) -> u64 {
@@ -1682,7 +2028,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        /// HTLC-Success/HTLC-Timeout transactions.
        /// Return updates for HTLC pending in the channel and failed automatically by the broadcast of
        /// revoked counterparty commitment tx
-       fn check_spend_counterparty_transaction<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) -> (Vec<ClaimRequest>, TransactionOutputs) where L::Target: Logger {
+       fn check_spend_counterparty_transaction<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) -> (Vec<PackageTemplate>, TransactionOutputs) where L::Target: Logger {
                // Most secp and related errors trying to create keys means we have no hope of constructing
                // a spend transaction...so we return no transactions to broadcast
                let mut claimable_outpoints = Vec::new();
@@ -1706,16 +2052,17 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        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 = ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint));
-                       let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.counterparty_tx_cache.counterparty_delayed_payment_base_key));
+                       let delayed_key = ignore_error!(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 revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.counterparty_tx_cache.on_counterparty_tx_csv, &delayed_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();
 
                        // First, process non-htlc outputs (to_holder & to_counterparty)
                        for (idx, outp) in tx.output.iter().enumerate() {
                                if outp.script_pubkey == revokeable_p2wsh {
-                                       let witness_data = InputMaterial::Revoked { per_commitment_point, counterparty_delayed_payment_base_key: self.counterparty_tx_cache.counterparty_delayed_payment_base_key, counterparty_htlc_base_key: self.counterparty_tx_cache.counterparty_htlc_base_key, per_commitment_key, input_descriptor: InputDescriptors::RevokedOutput, amount: outp.value, htlc: None, on_counterparty_tx_csv: self.counterparty_tx_cache.on_counterparty_tx_csv};
-                                       claimable_outpoints.push(ClaimRequest { absolute_timelock: height + self.counterparty_tx_cache.on_counterparty_tx_csv as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: idx as u32 }, witness_data});
+                                       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, outp.value, self.counterparty_commitment_params.on_counterparty_tx_csv);
+                                       let justice_package = PackageTemplate::build_package(commitment_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);
                                }
                        }
 
@@ -1727,8 +2074,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                                tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
                                                        return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user
                                                }
-                                               let witness_data = InputMaterial::Revoked { per_commitment_point, counterparty_delayed_payment_base_key: self.counterparty_tx_cache.counterparty_delayed_payment_base_key, counterparty_htlc_base_key: self.counterparty_tx_cache.counterparty_htlc_base_key, per_commitment_key, input_descriptor: if htlc.offered { InputDescriptors::RevokedOfferedHTLC } else { InputDescriptors::RevokedReceivedHTLC }, amount: tx.output[transaction_output_index as usize].value, htlc: Some(htlc.clone()), on_counterparty_tx_csv: self.counterparty_tx_cache.on_counterparty_tx_csv};
-                                               claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
+                                               let revk_htlc_outp = RevokedHTLCOutput::build(per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, per_commitment_key, htlc.amount_msat / 1000, htlc.clone(), self.onchain_tx_handler.channel_transaction_parameters.opt_anchors.is_some());
+                                               let justice_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, PackageSolvingData::RevokedHTLCOutput(revk_htlc_outp), htlc.cltv_expiry, true, height);
+                                               claimable_outpoints.push(justice_package);
                                        }
                                }
                        }
@@ -1736,47 +2084,13 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        // Last, track onchain revoked commitment transaction and fail backward outgoing HTLCs as payment path is broken
                        if !claimable_outpoints.is_empty() || per_commitment_option.is_some() { // ie we're confident this is actually ours
                                // We're definitely a counterparty commitment transaction!
-                               log_trace!(logger, "Got broadcast of revoked counterparty commitment transaction, going to generate general spend tx with {} inputs", claimable_outpoints.len());
+                               log_error!(logger, "Got broadcast of revoked counterparty commitment transaction, going to generate general spend tx with {} inputs", claimable_outpoints.len());
                                for (idx, outp) in tx.output.iter().enumerate() {
                                        watch_outputs.push((idx as u32, outp.clone()));
                                }
                                self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number);
 
-                               macro_rules! check_htlc_fails {
-                                       ($txid: expr, $commitment_tx: expr) => {
-                                               if let Some(ref outpoints) = self.counterparty_claimable_outpoints.get($txid) {
-                                                       for &(ref htlc, ref source_option) in outpoints.iter() {
-                                                               if let &Some(ref source) = source_option {
-                                                                       self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
-                                                                               if entry.height != height { return true; }
-                                                                               match entry.event {
-                                                                                        OnchainEvent::HTLCUpdate { ref htlc_update } => {
-                                                                                                htlc_update.0 != **source
-                                                                                        },
-                                                                                        _ => true,
-                                                                               }
-                                                                       });
-                                                                       let entry = OnchainEventEntry {
-                                                                               txid: *$txid,
-                                                                               height,
-                                                                               event: OnchainEvent::HTLCUpdate {
-                                                                                       htlc_update: ((**source).clone(), htlc.payment_hash.clone())
-                                                                               },
-                                                                       };
-                                                                       log_info!(logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of revoked counterparty commitment transaction, waiting for confirmation (at height {})", log_bytes!(htlc.payment_hash.0), $commitment_tx, entry.confirmation_threshold());
-                                                                       self.onchain_events_awaiting_threshold_conf.push(entry);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                               if let Some(ref txid) = self.current_counterparty_commitment_txid {
-                                       check_htlc_fails!(txid, "current");
-                               }
-                               if let Some(ref txid) = self.prev_counterparty_commitment_txid {
-                                       check_htlc_fails!(txid, "counterparty");
-                               }
-                               // No need to check holder commitment txn, symmetric HTLCSource must be present as per-htlc data on counterparty commitment tx
+                               fail_unbroadcast_htlcs!(self, "revoked counterparty", height, [].iter().map(|a| *a), logger);
                        }
                } else if let Some(per_commitment_data) = per_commitment_option {
                        // While this isn't useful yet, there is a potential race where if a counterparty
@@ -1791,55 +2105,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        }
                        self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number);
 
-                       log_trace!(logger, "Got broadcast of non-revoked counterparty commitment transaction {}", commitment_txid);
-
-                       macro_rules! check_htlc_fails {
-                               ($txid: expr, $commitment_tx: expr, $id: tt) => {
-                                       if let Some(ref latest_outpoints) = self.counterparty_claimable_outpoints.get($txid) {
-                                               $id: for &(ref htlc, ref source_option) in latest_outpoints.iter() {
-                                                       if let &Some(ref source) = source_option {
-                                                               // Check if the HTLC is present in the commitment transaction that was
-                                                               // broadcast, but not if it was below the dust limit, which we should
-                                                               // fail backwards immediately as there is no way for us to learn the
-                                                               // payment_preimage.
-                                                               // Note that if the dust limit were allowed to change between
-                                                               // commitment transactions we'd want to be check whether *any*
-                                                               // broadcastable commitment transaction has the HTLC in it, but it
-                                                               // cannot currently change after channel initialization, so we don't
-                                                               // need to here.
-                                                               for &(ref broadcast_htlc, ref broadcast_source) in per_commitment_data.iter() {
-                                                                       if broadcast_htlc.transaction_output_index.is_some() && Some(source) == broadcast_source.as_ref() {
-                                                                               continue $id;
-                                                                       }
-                                                               }
-                                                               log_trace!(logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of counterparty commitment transaction", log_bytes!(htlc.payment_hash.0), $commitment_tx);
-                                                               self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
-                                                                       if entry.height != height { return true; }
-                                                                       match entry.event {
-                                                                                OnchainEvent::HTLCUpdate { ref htlc_update } => {
-                                                                                        htlc_update.0 != **source
-                                                                                },
-                                                                                _ => true,
-                                                                       }
-                                                               });
-                                                               self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
-                                                                       txid: *$txid,
-                                                                       height,
-                                                                       event: OnchainEvent::HTLCUpdate {
-                                                                               htlc_update: ((**source).clone(), htlc.payment_hash.clone())
-                                                                       },
-                                                               });
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if let Some(ref txid) = self.current_counterparty_commitment_txid {
-                               check_htlc_fails!(txid, "current", 'current_loop);
-                       }
-                       if let Some(ref txid) = self.prev_counterparty_commitment_txid {
-                               check_htlc_fails!(txid, "previous", 'prev_loop);
-                       }
+                       log_info!(logger, "Got broadcast of non-revoked counterparty commitment transaction {}", commitment_txid);
+                       fail_unbroadcast_htlcs!(self, "counterparty", height, per_commitment_data.iter().map(|(a, b)| (a, b.as_ref().map(|b| b.as_ref()))), logger);
 
                        let htlc_claim_reqs = self.get_counterparty_htlc_output_claim_reqs(commitment_number, commitment_txid, Some(tx));
                        for req in htlc_claim_reqs {
@@ -1850,8 +2117,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                (claimable_outpoints, (commitment_txid, watch_outputs))
        }
 
-       fn get_counterparty_htlc_output_claim_reqs(&self, commitment_number: u64, commitment_txid: Txid, tx: Option<&Transaction>) -> Vec<ClaimRequest> {
-               let mut claims = Vec::new();
+       fn get_counterparty_htlc_output_claim_reqs(&self, commitment_number: u64, commitment_txid: Txid, tx: Option<&Transaction>) -> Vec<PackageTemplate> {
+               let mut claimable_outpoints = Vec::new();
                if let Some(htlc_outputs) = self.counterparty_claimable_outpoints.get(&commitment_txid) {
                        if let Some(revocation_points) = self.their_cur_revocation_points {
                                let revocation_point_option =
@@ -1870,30 +2137,26 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                        if let Some(transaction) = tx {
                                                                if transaction_output_index as usize >= transaction.output.len() ||
                                                                        transaction.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
-                                                                               return claims; // Corrupted per_commitment_data, fuck this user
+                                                                               return claimable_outpoints; // Corrupted per_commitment_data, fuck this user
                                                                        }
                                                        }
-                                                       let preimage =
-                                                               if htlc.offered {
-                                                                       if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) {
-                                                                               Some(*p)
-                                                                       } else { None }
-                                                               } else { None };
-                                                       let aggregable = if !htlc.offered { false } else { true };
+                                                       let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
                                                        if preimage.is_some() || !htlc.offered {
-                                                               let witness_data = InputMaterial::CounterpartyHTLC { per_commitment_point: *revocation_point, counterparty_delayed_payment_base_key: self.counterparty_tx_cache.counterparty_delayed_payment_base_key, counterparty_htlc_base_key: self.counterparty_tx_cache.counterparty_htlc_base_key, preimage, htlc: htlc.clone() };
-                                                               claims.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
+                                                               let counterparty_htlc_outp = if htlc.offered { PackageSolvingData::CounterpartyOfferedHTLCOutput(CounterpartyOfferedHTLCOutput::build(*revocation_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, preimage.unwrap(), htlc.clone())) } else { PackageSolvingData::CounterpartyReceivedHTLCOutput(CounterpartyReceivedHTLCOutput::build(*revocation_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, htlc.clone())) };
+                                                               let aggregation = if !htlc.offered { false } else { true };
+                                                               let counterparty_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc.cltv_expiry,aggregation, 0);
+                                                               claimable_outpoints.push(counterparty_package);
                                                        }
                                                }
                                        }
                                }
                        }
                }
-               claims
+               claimable_outpoints
        }
 
        /// 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<ClaimRequest>, Option<TransactionOutputs>) where L::Target: Logger {
+       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)
@@ -1912,17 +2175,18 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                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_trace!(logger, "Counterparty HTLC broadcast {}:{}", htlc_txid, 0);
-               let witness_data = InputMaterial::Revoked { per_commitment_point, counterparty_delayed_payment_base_key: self.counterparty_tx_cache.counterparty_delayed_payment_base_key, counterparty_htlc_base_key: self.counterparty_tx_cache.counterparty_htlc_base_key,  per_commitment_key, input_descriptor: InputDescriptors::RevokedOutput, amount: tx.output[0].value, htlc: None, on_counterparty_tx_csv: self.counterparty_tx_cache.on_counterparty_tx_csv };
-               let claimable_outpoints = vec!(ClaimRequest { absolute_timelock: height + self.counterparty_tx_cache.on_counterparty_tx_csv as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: htlc_txid, vout: 0}, witness_data });
+               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)))
        }
 
-       // Returns (1) `ClaimRequest`s that can be given to the OnChainTxHandler, so that the handler can
+       // Returns (1) `PackageTemplate`s that can be given to the OnChainTxHandler, so that the handler can
        // broadcast transactions claiming holder HTLC commitment outputs and (2) a holder revokable
        // script so we can detect whether a holder transaction has been seen on-chain.
-       fn get_broadcasted_holder_claims(&self, holder_tx: &HolderSignedTx) -> (Vec<ClaimRequest>, Option<(Script, PublicKey, PublicKey)>) {
+       fn get_broadcasted_holder_claims(&self, holder_tx: &HolderSignedTx, conf_height: u32) -> (Vec<PackageTemplate>, Option<(Script, PublicKey, PublicKey)>) {
                let mut claim_requests = Vec::with_capacity(holder_tx.htlc_outputs.len());
 
                let redeemscript = chan_utils::get_revokeable_redeemscript(&holder_tx.revocation_key, self.on_holder_tx_csv, &holder_tx.delayed_payment_key);
@@ -1930,18 +2194,19 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                for &(ref htlc, _, _) in holder_tx.htlc_outputs.iter() {
                        if let Some(transaction_output_index) = htlc.transaction_output_index {
-                               claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: holder_tx.txid, vout: transaction_output_index as u32 },
-                                       witness_data: InputMaterial::HolderHTLC {
-                                               preimage: if !htlc.offered {
-                                                               if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) {
-                                                                       Some(preimage.clone())
-                                                               } else {
-                                                                       // We can't build an HTLC-Success transaction without the preimage
-                                                                       continue;
-                                                               }
-                                                       } else { None },
-                                               amount: htlc.amount_msat,
-                               }});
+                               let htlc_output = if htlc.offered {
+                                               HolderHTLCOutput::build_offered(htlc.amount_msat, htlc.cltv_expiry)
+                                       } 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)
+                                       };
+                               let htlc_package = PackageTemplate::build_package(holder_tx.txid, transaction_output_index, PackageSolvingData::HolderHTLCOutput(htlc_output), htlc.cltv_expiry, false, conf_height);
+                               claim_requests.push(htlc_package);
                        }
                }
 
@@ -1962,32 +2227,12 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        /// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet)
        /// revoked using data in holder_claimable_outpoints.
        /// Should not be used if check_spend_revoked_transaction succeeds.
-       fn check_spend_holder_transaction<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) -> (Vec<ClaimRequest>, TransactionOutputs) where L::Target: Logger {
+       /// Returns None unless the transaction is definitely one of our commitment transactions.
+       fn check_spend_holder_transaction<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) -> Option<(Vec<PackageTemplate>, TransactionOutputs)> where L::Target: Logger {
                let commitment_txid = tx.txid();
                let mut claim_requests = Vec::new();
                let mut watch_outputs = Vec::new();
 
-               macro_rules! wait_threshold_conf {
-                       ($source: expr, $commitment_tx: expr, $payment_hash: expr) => {
-                               self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
-                                       if entry.height != height { return true; }
-                                       match entry.event {
-                                                OnchainEvent::HTLCUpdate { ref htlc_update } => {
-                                                        htlc_update.0 != $source
-                                                },
-                                                _ => true,
-                                       }
-                               });
-                               let entry = OnchainEventEntry {
-                                       txid: commitment_txid,
-                                       height,
-                                       event: OnchainEvent::HTLCUpdate { htlc_update: ($source, $payment_hash) },
-                               };
-                               log_trace!(logger, "Failing HTLC with payment_hash {} from {} holder commitment tx due to broadcast of transaction, waiting confirmation (at height{})", log_bytes!($payment_hash.0), $commitment_tx, entry.confirmation_threshold());
-                               self.onchain_events_awaiting_threshold_conf.push(entry);
-                       }
-               }
-
                macro_rules! append_onchain_update {
                        ($updates: expr, $to_watch: expr) => {
                                claim_requests = $updates.0;
@@ -2001,48 +2246,35 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                if self.current_holder_commitment_tx.txid == commitment_txid {
                        is_holder_tx = true;
-                       log_trace!(logger, "Got latest holder commitment tx broadcast, searching for available HTLCs to claim");
-                       let res = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx);
+                       log_info!(logger, "Got broadcast of latest holder commitment tx {}, searching for available HTLCs to claim", commitment_txid);
+                       let res = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, height);
                        let mut to_watch = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, tx);
                        append_onchain_update!(res, to_watch);
+                       fail_unbroadcast_htlcs!(self, "latest holder", height, self.current_holder_commitment_tx.htlc_outputs.iter().map(|(a, _, c)| (a, c.as_ref())), logger);
                } else if let &Some(ref holder_tx) = &self.prev_holder_signed_commitment_tx {
                        if holder_tx.txid == commitment_txid {
                                is_holder_tx = true;
-                               log_trace!(logger, "Got previous holder commitment tx broadcast, searching for available HTLCs to claim");
-                               let res = self.get_broadcasted_holder_claims(holder_tx);
+                               log_info!(logger, "Got broadcast of previous holder commitment tx {}, searching for available HTLCs to claim", commitment_txid);
+                               let res = self.get_broadcasted_holder_claims(holder_tx, height);
                                let mut to_watch = self.get_broadcasted_holder_watch_outputs(holder_tx, tx);
                                append_onchain_update!(res, to_watch);
-                       }
-               }
-
-               macro_rules! fail_dust_htlcs_after_threshold_conf {
-                       ($holder_tx: expr) => {
-                               for &(ref htlc, _, ref source) in &$holder_tx.htlc_outputs {
-                                       if htlc.transaction_output_index.is_none() {
-                                               if let &Some(ref source) = source {
-                                                       wait_threshold_conf!(source.clone(), "lastest", htlc.payment_hash.clone());
-                                               }
-                                       }
-                               }
+                               fail_unbroadcast_htlcs!(self, "previous holder", height, holder_tx.htlc_outputs.iter().map(|(a, _, c)| (a, c.as_ref())), logger);
                        }
                }
 
                if is_holder_tx {
-                       fail_dust_htlcs_after_threshold_conf!(self.current_holder_commitment_tx);
-                       if let &Some(ref holder_tx) = &self.prev_holder_signed_commitment_tx {
-                               fail_dust_htlcs_after_threshold_conf!(holder_tx);
-                       }
+                       Some((claim_requests, (commitment_txid, watch_outputs)))
+               } else {
+                       None
                }
-
-               (claim_requests, (commitment_txid, watch_outputs))
        }
 
        pub fn get_latest_holder_commitment_txn<L: Deref>(&mut self, logger: &L) -> Vec<Transaction> where L::Target: Logger {
-               log_trace!(logger, "Getting signed latest holder commitment transaction!");
+               log_debug!(logger, "Getting signed latest holder commitment transaction!");
                self.holder_tx_signed = true;
                let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
                let txid = commitment_tx.txid();
-               let mut res = vec![commitment_tx];
+               let mut holder_transactions = vec![commitment_tx];
                for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
                        if let Some(vout) = htlc.0.transaction_output_index {
                                let preimage = if !htlc.0.offered {
@@ -2050,24 +2282,32 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                // We can't build an HTLC-Success transaction without the preimage
                                                continue;
                                        }
+                               } else if htlc.0.cltv_expiry > self.best_block.height() + 1 {
+                                       // Don't broadcast HTLC-Timeout transactions immediately as they don't meet the
+                                       // current locktime requirements on-chain. We will broadcast them in
+                                       // `block_confirmed` when `should_broadcast_holder_commitment_txn` returns true.
+                                       // Note that we add + 1 as transactions are broadcastable when they can be
+                                       // confirmed in the next block.
+                                       continue;
                                } else { None };
                                if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(
                                        &::bitcoin::OutPoint { txid, vout }, &preimage) {
-                                       res.push(htlc_tx);
+                                       holder_transactions.push(htlc_tx);
                                }
                        }
                }
                // We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do.
                // The data will be re-generated and tracked in check_spend_holder_transaction if we get a confirmation.
-               return res;
+               holder_transactions
        }
 
        #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
+       /// Note that this includes possibly-locktimed-in-the-future transactions!
        fn unsafe_get_latest_holder_commitment_txn<L: Deref>(&mut self, logger: &L) -> Vec<Transaction> where L::Target: Logger {
-               log_trace!(logger, "Getting signed copy of latest holder commitment transaction!");
+               log_debug!(logger, "Getting signed copy of latest holder commitment transaction!");
                let commitment_tx = self.onchain_tx_handler.get_fully_signed_copy_holder_tx(&self.funding_redeemscript);
                let txid = commitment_tx.txid();
-               let mut res = vec![commitment_tx];
+               let mut holder_transactions = vec![commitment_tx];
                for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
                        if let Some(vout) = htlc.0.transaction_output_index {
                                let preimage = if !htlc.0.offered {
@@ -2078,11 +2318,11 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                } else { None };
                                if let Some(htlc_tx) = self.onchain_tx_handler.unsafe_get_fully_signed_htlc_tx(
                                        &::bitcoin::OutPoint { txid, vout }, &preimage) {
-                                       res.push(htlc_tx);
+                                       holder_transactions.push(htlc_tx);
                                }
                        }
                }
-               return res
+               holder_transactions
        }
 
        pub fn block_connected<B: Deref, F: Deref, L: Deref>(&mut self, header: &BlockHeader, txdata: &TransactionData, height: u32, broadcaster: B, fee_estimator: F, logger: L) -> Vec<TransactionOutputs>
@@ -2091,7 +2331,6 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        L::Target: Logger,
        {
                let block_hash = header.block_hash();
-               log_trace!(logger, "New best block {} at height {}", block_hash, height);
                self.best_block = BestBlock::new(block_hash, height);
 
                self.transactions_confirmed(header, txdata, height, broadcaster, fee_estimator, logger)
@@ -2111,17 +2350,16 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                L::Target: Logger,
        {
                let block_hash = header.block_hash();
-               log_trace!(logger, "New best block {} at height {}", block_hash, height);
 
                if height > self.best_block.height() {
                        self.best_block = BestBlock::new(block_hash, height);
-                       self.block_confirmed(height, vec![], vec![], vec![], broadcaster, fee_estimator, logger)
-               } else {
+                       self.block_confirmed(height, vec![], vec![], vec![], &broadcaster, &fee_estimator, &logger)
+               } else if block_hash != self.best_block.block_hash() {
                        self.best_block = BestBlock::new(block_hash, height);
                        self.onchain_events_awaiting_threshold_conf.retain(|ref entry| entry.height <= height);
                        self.onchain_tx_handler.block_disconnected(height + 1, broadcaster, fee_estimator, logger);
                        Vec::new()
-               }
+               } else { Vec::new() }
        }
 
        fn transactions_confirmed<B: Deref, F: Deref, L: Deref>(
@@ -2149,7 +2387,6 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                }
 
                let block_hash = header.block_hash();
-               log_trace!(logger, "Block {} at height {} connected with {} txn matched", block_hash, height, txn_matched.len());
 
                let mut watch_outputs = Vec::new();
                let mut claimable_outpoints = Vec::new();
@@ -2161,20 +2398,34 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                // 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;
+                                       log_info!(logger, "Channel {} closed by funding output spend in txid {}.",
+                                               log_bytes!(self.funding_info.0.to_channel_id()), tx.txid());
+                                       self.funding_spend_seen = true;
                                        if (tx.input[0].sequence >> 8*3) as u8 == 0x80 && (tx.lock_time >> 8*3) as u8 == 0x20 {
                                                let (mut new_outpoints, new_outputs) = self.check_spend_counterparty_transaction(&tx, height, &logger);
                                                if !new_outputs.1.is_empty() {
                                                        watch_outputs.push(new_outputs);
                                                }
+                                               claimable_outpoints.append(&mut new_outpoints);
                                                if new_outpoints.is_empty() {
-                                                       let (mut new_outpoints, new_outputs) = self.check_spend_holder_transaction(&tx, height, &logger);
-                                                       if !new_outputs.1.is_empty() {
-                                                               watch_outputs.push(new_outputs);
+                                                       if let Some((mut new_outpoints, new_outputs)) = self.check_spend_holder_transaction(&tx, height, &logger) {
+                                                               if !new_outputs.1.is_empty() {
+                                                                       watch_outputs.push(new_outputs);
+                                                               }
+                                                               claimable_outpoints.append(&mut new_outpoints);
+                                                               balance_spendable_csv = Some(self.on_holder_tx_csv);
                                                        }
-                                                       claimable_outpoints.append(&mut new_outpoints);
                                                }
-                                               claimable_outpoints.append(&mut new_outpoints);
                                        }
+                                       let txid = tx.txid();
+                                       self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
+                                               txid,
+                                               height: height,
+                                               event: OnchainEvent::FundingSpendConfirmation {
+                                                       on_local_output_csv: balance_spendable_csv,
+                                               },
+                                       });
                                } 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);
@@ -2193,31 +2444,50 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        self.is_paying_spendable_output(&tx, height, &logger);
                }
 
-               self.block_confirmed(height, txn_matched, watch_outputs, claimable_outpoints, broadcaster, fee_estimator, logger)
+               if height > self.best_block.height() {
+                       self.best_block = BestBlock::new(block_hash, height);
+               }
+
+               self.block_confirmed(height, txn_matched, watch_outputs, claimable_outpoints, &broadcaster, &fee_estimator, &logger)
        }
 
+       /// Update state for new block(s)/transaction(s) confirmed. Note that the caller must update
+       /// `self.best_block` before calling if a new best blockchain tip is available. More
+       /// concretely, `self.best_block` must never be at a lower height than `conf_height`, avoiding
+       /// complexity especially in `OnchainTx::update_claims_view`.
+       ///
+       /// `conf_height` should be set to the height at which any new transaction(s)/block(s) were
+       /// confirmed at, even if it is not the current best height.
        fn block_confirmed<B: Deref, F: Deref, L: Deref>(
                &mut self,
-               height: u32,
+               conf_height: u32,
                txn_matched: Vec<&Transaction>,
                mut watch_outputs: Vec<TransactionOutputs>,
-               mut claimable_outpoints: Vec<ClaimRequest>,
-               broadcaster: B,
-               fee_estimator: F,
-               logger: L,
+               mut claimable_outpoints: Vec<PackageTemplate>,
+               broadcaster: &B,
+               fee_estimator: &F,
+               logger: &L,
        ) -> Vec<TransactionOutputs>
        where
                B::Target: BroadcasterInterface,
                F::Target: FeeEstimator,
                L::Target: Logger,
        {
-               let should_broadcast = self.would_broadcast_at_height(height, &logger);
+               log_trace!(logger, "Processing {} matched transactions for block at height {}.", txn_matched.len(), conf_height);
+               debug_assert!(self.best_block.height() >= conf_height);
+
+               let should_broadcast = self.should_broadcast_holder_commitment_txn(logger);
                if should_broadcast {
-                       claimable_outpoints.push(ClaimRequest { absolute_timelock: height, aggregable: false, outpoint: BitcoinOutPoint { txid: self.funding_info.0.txid.clone(), vout: self.funding_info.0.index as u32 }, witness_data: InputMaterial::Funding { funding_redeemscript: self.funding_redeemscript.clone() }});
-                       self.pending_monitor_events.push(MonitorEvent::CommitmentTxBroadcasted(self.funding_info.0));
+                       let funding_outp = HolderFundingOutput::build(self.funding_redeemscript.clone());
+                       let commitment_package = PackageTemplate::build_package(self.funding_info.0.txid.clone(), self.funding_info.0.index as u32, PackageSolvingData::HolderFundingOutput(funding_outp), self.best_block.height(), false, self.best_block.height());
+                       claimable_outpoints.push(commitment_package);
+                       self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0));
                        let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
                        self.holder_tx_signed = true;
-                       let (mut new_outpoints, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx);
+                       // Because we're broadcasting a commitment transaction, we should construct the package
+                       // assuming it gets confirmed in the next block. Sadly, we have code which considers
+                       // "not yet confirmed" things as discardable, so we cannot do that here.
+                       let (mut new_outpoints, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height());
                        let new_outputs = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, &commitment_tx);
                        if !new_outputs.is_empty() {
                                watch_outputs.push((self.current_holder_commitment_tx.txid.clone(), new_outputs));
@@ -2230,7 +2500,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        self.onchain_events_awaiting_threshold_conf.drain(..).collect::<Vec<_>>();
                let mut onchain_events_reaching_threshold_conf = Vec::new();
                for entry in onchain_events_awaiting_threshold_conf {
-                       if entry.has_reached_confirmation_threshold(height) {
+                       if entry.has_reached_confirmation_threshold(&self.best_block) {
                                onchain_events_reaching_threshold_conf.push(entry);
                        } else {
                                self.onchain_events_awaiting_threshold_conf.push(entry);
@@ -2242,8 +2512,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                let unmatured_htlcs: Vec<_> = self.onchain_events_awaiting_threshold_conf
                        .iter()
                        .filter_map(|entry| match &entry.event {
-                               OnchainEvent::HTLCUpdate { htlc_update } => Some(htlc_update.0.clone()),
-                               OnchainEvent::MaturingOutput { .. } => None,
+                               OnchainEvent::HTLCUpdate { source, .. } => Some(source),
+                               _ => None,
                        })
                        .collect();
                #[cfg(debug_assertions)]
@@ -2252,40 +2522,50 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                // Produce actionable events from on-chain events having reached their threshold.
                for entry in onchain_events_reaching_threshold_conf.drain(..) {
                        match entry.event {
-                               OnchainEvent::HTLCUpdate { htlc_update } => {
+                               OnchainEvent::HTLCUpdate { ref source, payment_hash, onchain_value_satoshis, input_idx } => {
                                        // Check for duplicate HTLC resolutions.
                                        #[cfg(debug_assertions)]
                                        {
                                                debug_assert!(
-                                                       unmatured_htlcs.iter().find(|&htlc| htlc == &htlc_update.0).is_none(),
+                                                       unmatured_htlcs.iter().find(|&htlc| htlc == &source).is_none(),
                                                        "An unmature HTLC transaction conflicts with a maturing one; failed to \
                                                         call either transaction_unconfirmed for the conflicting transaction \
                                                         or block_disconnected for a block containing it.");
                                                debug_assert!(
-                                                       matured_htlcs.iter().find(|&htlc| htlc == &htlc_update.0).is_none(),
+                                                       matured_htlcs.iter().find(|&htlc| htlc == source).is_none(),
                                                        "A matured HTLC transaction conflicts with a maturing one; failed to \
                                                         call either transaction_unconfirmed for the conflicting transaction \
                                                         or block_disconnected for a block containing it.");
-                                               matured_htlcs.push(htlc_update.0.clone());
+                                               matured_htlcs.push(source.clone());
                                        }
 
-                                       log_trace!(logger, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!((htlc_update.1).0));
+                                       log_debug!(logger, "HTLC {} failure update has got enough confirmations to be passed upstream", log_bytes!(payment_hash.0));
                                        self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
-                                               payment_hash: htlc_update.1,
+                                               payment_hash,
                                                payment_preimage: None,
-                                               source: htlc_update.0,
+                                               source: source.clone(),
+                                               onchain_value_satoshis,
                                        }));
+                                       if let Some(idx) = input_idx {
+                                               self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC { input_idx: idx, payment_preimage: None });
+                                       }
                                },
                                OnchainEvent::MaturingOutput { descriptor } => {
-                                       log_trace!(logger, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor));
+                                       log_debug!(logger, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor));
                                        self.pending_events.push(Event::SpendableOutputs {
                                                outputs: vec![descriptor]
                                        });
-                               }
+                               },
+                               OnchainEvent::HTLCSpendConfirmation { input_idx, preimage, .. } => {
+                                       self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC { input_idx, payment_preimage: preimage });
+                               },
+                               OnchainEvent::FundingSpendConfirmation { .. } => {
+                                       self.funding_spend_confirmed = Some(entry.txid);
+                               },
                        }
                }
 
-               self.onchain_tx_handler.update_claims_view(&txn_matched, claimable_outpoints, Some(height), &&*broadcaster, &&*fee_estimator, &&*logger);
+               self.onchain_tx_handler.update_claims_view(&txn_matched, claimable_outpoints, conf_height, self.best_block.height(), broadcaster, fee_estimator, logger);
 
                // Determine new outputs to watch by comparing against previously known outputs to watch,
                // updating the latter in the process.
@@ -2387,7 +2667,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                false
        }
 
-       fn would_broadcast_at_height<L: Deref>(&self, height: u32, logger: &L) -> bool where L::Target: Logger {
+       fn should_broadcast_holder_commitment_txn<L: Deref>(&self, logger: &L) -> bool where L::Target: Logger {
                // We need to consider all HTLCs which are:
                //  * in any unrevoked counterparty commitment transaction, as they could broadcast said
                //    transactions and we'd end up in a race, or
@@ -2398,6 +2678,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                // to the source, and if we don't fail the channel we will have to ensure that the next
                // updates that peer sends us are update_fails, failing the channel if not. It's probably
                // easier to just fail the channel as this case should be rare enough anyway.
+               let height = self.best_block.height();
                macro_rules! scan_commitment {
                        ($htlcs: expr, $holder_tx: expr) => {
                                for ref htlc in $htlcs {
@@ -2458,15 +2739,34 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        let revocation_sig_claim = (input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC) && input.witness[1].len() == 33)
                                || (input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::AcceptedHTLC) && input.witness[1].len() == 33);
                        let accepted_preimage_claim = input.witness.len() == 5 && HTLCType::scriptlen_to_htlctype(input.witness[4].len()) == Some(HTLCType::AcceptedHTLC);
-                       let offered_preimage_claim = input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC);
+                       #[cfg(not(fuzzing))]
+                       let accepted_timeout_claim = input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::AcceptedHTLC) && !revocation_sig_claim;
+                       let offered_preimage_claim = input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC) && !revocation_sig_claim;
+                       #[cfg(not(fuzzing))]
+                       let offered_timeout_claim = input.witness.len() == 5 && HTLCType::scriptlen_to_htlctype(input.witness[4].len()) == Some(HTLCType::OfferedHTLC);
+
+                       let mut payment_preimage = PaymentPreimage([0; 32]);
+                       if accepted_preimage_claim {
+                               payment_preimage.0.copy_from_slice(&input.witness[3]);
+                       } else if offered_preimage_claim {
+                               payment_preimage.0.copy_from_slice(&input.witness[1]);
+                       }
 
                        macro_rules! log_claim {
                                ($tx_info: expr, $holder_tx: expr, $htlc: expr, $source_avail: expr) => {
-                                       // We found the output in question, but aren't failing it backwards
-                                       // as we have no corresponding source and no valid counterparty commitment txid
-                                       // to try a weak source binding with same-hash, same-value still-valid offered HTLC.
-                                       // This implies either it is an inbound HTLC or an outbound HTLC on a revoked transaction.
                                        let outbound_htlc = $holder_tx == $htlc.offered;
+                                       // HTLCs must either be claimed by a matching script type or through the
+                                       // revocation path:
+                                       #[cfg(not(fuzzing))] // Note that the fuzzer is not bound by pesky things like "signatures"
+                                       debug_assert!(!$htlc.offered || offered_preimage_claim || offered_timeout_claim || revocation_sig_claim);
+                                       #[cfg(not(fuzzing))] // Note that the fuzzer is not bound by pesky things like "signatures"
+                                       debug_assert!($htlc.offered || accepted_preimage_claim || accepted_timeout_claim || revocation_sig_claim);
+                                       // Further, only exactly one of the possible spend paths should have been
+                                       // matched by any HTLC spend:
+                                       #[cfg(not(fuzzing))] // Note that the fuzzer is not bound by pesky things like "signatures"
+                                       debug_assert_eq!(accepted_preimage_claim as u8 + accepted_timeout_claim as u8 +
+                                                        offered_preimage_claim as u8 + offered_timeout_claim as u8 +
+                                                        revocation_sig_claim as u8, 1);
                                        if ($holder_tx && revocation_sig_claim) ||
                                                        (outbound_htlc && !$source_avail && (accepted_preimage_claim || offered_preimage_claim)) {
                                                log_error!(logger, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}!",
@@ -2489,7 +2789,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                        if pending_htlc.payment_hash == $htlc_output.payment_hash && pending_htlc.amount_msat == $htlc_output.amount_msat {
                                                                if let &Some(ref source) = pending_source {
                                                                        log_claim!("revoked counterparty commitment tx", false, pending_htlc, true);
-                                                                       payment_data = Some(((**source).clone(), $htlc_output.payment_hash));
+                                                                       payment_data = Some(((**source).clone(), $htlc_output.payment_hash, $htlc_output.amount_msat));
                                                                        break;
                                                                }
                                                        }
@@ -2509,15 +2809,39 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                                // transaction. This implies we either learned a preimage, the HTLC
                                                                // has timed out, or we screwed up. In any case, we should now
                                                                // resolve the source HTLC with the original sender.
-                                                               payment_data = Some(((*source).clone(), htlc_output.payment_hash));
+                                                               payment_data = Some(((*source).clone(), htlc_output.payment_hash, htlc_output.amount_msat));
                                                        } else if !$holder_tx {
-                                                                       check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid, htlc_output);
+                                                               check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid, htlc_output);
                                                                if payment_data.is_none() {
                                                                        check_htlc_valid_counterparty!(self.prev_counterparty_commitment_txid, htlc_output);
                                                                }
                                                        }
                                                        if payment_data.is_none() {
                                                                log_claim!($tx_info, $holder_tx, htlc_output, false);
+                                                               let outbound_htlc = $holder_tx == htlc_output.offered;
+                                                               if !outbound_htlc || revocation_sig_claim {
+                                                                       self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
+                                                                               txid: tx.txid(), height,
+                                                                               event: OnchainEvent::HTLCSpendConfirmation {
+                                                                                       input_idx: input.previous_output.vout,
+                                                                                       preimage: if accepted_preimage_claim || offered_preimage_claim {
+                                                                                               Some(payment_preimage) } else { None },
+                                                                                       // If this is a payment to us (!outbound_htlc, above),
+                                                                                       // wait for the CSV delay before dropping the HTLC from
+                                                                                       // claimable balance if the claim was an HTLC-Success
+                                                                                       // transaction.
+                                                                                       on_to_local_output_csv: if accepted_preimage_claim {
+                                                                                               Some(self.on_holder_tx_csv) } else { None },
+                                                                               },
+                                                                       });
+                                                               } else {
+                                                                       // Outbound claims should always have payment_data, unless
+                                                                       // we've already failed the HTLC as the commitment transaction
+                                                                       // which was broadcasted was revoked. In that case, we should
+                                                                       // spend the HTLC output here immediately, and expose that fact
+                                                                       // as a Balance, something which we do not yet do.
+                                                                       // TODO: Track the above as claimable!
+                                                               }
                                                                continue 'outer_loop;
                                                        }
                                                }
@@ -2542,16 +2866,24 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                        // Check that scan_commitment, above, decided there is some source worth relaying an
                        // HTLC resolution backwards to and figure out whether we learned a preimage from it.
-                       if let Some((source, payment_hash)) = payment_data {
-                               let mut payment_preimage = PaymentPreimage([0; 32]);
+                       if let Some((source, payment_hash, amount_msat)) = payment_data {
                                if accepted_preimage_claim {
                                        if !self.pending_monitor_events.iter().any(
                                                |update| if let &MonitorEvent::HTLCEvent(ref upd) = update { upd.source == source } else { false }) {
-                                               payment_preimage.0.copy_from_slice(&input.witness[3]);
+                                               self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
+                                                       txid: tx.txid(),
+                                                       height,
+                                                       event: OnchainEvent::HTLCSpendConfirmation {
+                                                               input_idx: input.previous_output.vout,
+                                                               preimage: Some(payment_preimage),
+                                                               on_to_local_output_csv: None,
+                                                       },
+                                               });
                                                self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
                                                        source,
                                                        payment_preimage: Some(payment_preimage),
-                                                       payment_hash
+                                                       payment_hash,
+                                                       onchain_value_satoshis: Some(amount_msat / 1000),
                                                }));
                                        }
                                } else if offered_preimage_claim {
@@ -2559,29 +2891,42 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                |update| if let &MonitorEvent::HTLCEvent(ref upd) = update {
                                                        upd.source == source
                                                } else { false }) {
-                                               payment_preimage.0.copy_from_slice(&input.witness[1]);
+                                               self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
+                                                       txid: tx.txid(),
+                                                       height,
+                                                       event: OnchainEvent::HTLCSpendConfirmation {
+                                                               input_idx: input.previous_output.vout,
+                                                               preimage: Some(payment_preimage),
+                                                               on_to_local_output_csv: None,
+                                                       },
+                                               });
                                                self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
                                                        source,
                                                        payment_preimage: Some(payment_preimage),
-                                                       payment_hash
+                                                       payment_hash,
+                                                       onchain_value_satoshis: Some(amount_msat / 1000),
                                                }));
                                        }
                                } else {
                                        self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
                                                if entry.height != height { return true; }
                                                match entry.event {
-                                                        OnchainEvent::HTLCUpdate { ref htlc_update } => {
-                                                                htlc_update.0 != source
-                                                        },
-                                                        _ => true,
+                                                       OnchainEvent::HTLCUpdate { source: ref htlc_source, .. } => {
+                                                               *htlc_source != source
+                                                       },
+                                                       _ => true,
                                                }
                                        });
                                        let entry = OnchainEventEntry {
                                                txid: tx.txid(),
                                                height,
-                                               event: OnchainEvent::HTLCUpdate { htlc_update: (source, payment_hash) },
+                                               event: OnchainEvent::HTLCUpdate {
+                                                       source, payment_hash,
+                                                       onchain_value_satoshis: Some(amount_msat / 1000),
+                                                       input_idx: Some(input.previous_output.vout),
+                                               },
                                        };
-                                       log_info!(logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height{})", log_bytes!(payment_hash.0), entry.confirmation_threshold());
+                                       log_info!(logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height {})", log_bytes!(payment_hash.0), entry.confirmation_threshold());
                                        self.onchain_events_awaiting_threshold_conf.push(entry);
                                }
                        }
@@ -2592,7 +2937,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        fn is_paying_spendable_output<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) where L::Target: Logger {
                let mut spendable_output = None;
                for (i, outp) in tx.output.iter().enumerate() { // There is max one spendable output for any channel tx, including ones generated by us
-                       if i > ::std::u16::MAX as usize {
+                       if i > ::core::u16::MAX as usize {
                                // While it is possible that an output exists on chain which is greater than the
                                // 2^16th output in a given transaction, this is only possible if the output is not
                                // in a lightning transaction and was instead placed there by some third party who
@@ -2612,7 +2957,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        output: outp.clone(),
                                });
                                break;
-                       } else if let Some(ref broadcasted_holder_revokable_script) = self.broadcasted_holder_revokable_script {
+                       }
+                       if let Some(ref broadcasted_holder_revokable_script) = self.broadcasted_holder_revokable_script {
                                if broadcasted_holder_revokable_script.0 == outp.script_pubkey {
                                        spendable_output =  Some(SpendableOutputDescriptor::DelayedPaymentOutput(DelayedPaymentOutputDescriptor {
                                                outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
@@ -2625,7 +2971,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        }));
                                        break;
                                }
-                       } else if self.counterparty_payment_script == outp.script_pubkey {
+                       }
+                       if self.counterparty_payment_script == outp.script_pubkey {
                                spendable_output = Some(SpendableOutputDescriptor::StaticPaymentOutput(StaticPaymentOutputDescriptor {
                                        outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
                                        output: outp.clone(),
@@ -2633,11 +2980,13 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        channel_value_satoshis: self.channel_value_satoshis,
                                }));
                                break;
-                       } else if outp.script_pubkey == self.shutdown_script {
+                       }
+                       if self.shutdown_script.as_ref() == Some(&outp.script_pubkey) {
                                spendable_output = Some(SpendableOutputDescriptor::StaticOutput {
                                        outpoint: OutPoint { txid: tx.txid(), index: i as u16 },
                                        output: outp.clone(),
                                });
+                               break;
                        }
                }
                if let Some(spendable_output) = spendable_output {
@@ -2646,68 +2995,20 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                height: height,
                                event: OnchainEvent::MaturingOutput { descriptor: spendable_output.clone() },
                        };
-                       log_trace!(logger, "Maturing {} until {}", log_spendable!(spendable_output), entry.confirmation_threshold());
+                       log_info!(logger, "Received spendable output {}, spendable at height {}", log_spendable!(spendable_output), entry.confirmation_threshold());
                        self.onchain_events_awaiting_threshold_conf.push(entry);
                }
        }
 }
 
-/// `Persist` defines behavior for persisting channel monitors: this could mean
-/// writing once to disk, and/or uploading to one or more backup services.
-///
-/// Note that for every new monitor, you **must** persist the new `ChannelMonitor`
-/// to disk/backups. And, on every update, you **must** persist either the
-/// `ChannelMonitorUpdate` or the updated monitor itself. Otherwise, there is risk
-/// of situations such as revoking a transaction, then crashing before this
-/// revocation can be persisted, then unintentionally broadcasting a revoked
-/// transaction and losing money. This is a risk because previous channel states
-/// are toxic, so it's important that whatever channel state is persisted is
-/// kept up-to-date.
-pub trait Persist<ChannelSigner: Sign>: Send + Sync {
-       /// Persist a new channel's data. The data can be stored any way you want, but
-       /// the identifier provided by Rust-Lightning is the channel's outpoint (and
-       /// it is up to you to maintain a correct mapping between the outpoint and the
-       /// stored channel data). Note that you **must** persist every new monitor to
-       /// disk. See the `Persist` trait documentation for more details.
-       ///
-       /// See [`ChannelMonitor::write`] for writing out a `ChannelMonitor`,
-       /// and [`ChannelMonitorUpdateErr`] for requirements when returning errors.
-       fn persist_new_channel(&self, id: OutPoint, data: &ChannelMonitor<ChannelSigner>) -> Result<(), ChannelMonitorUpdateErr>;
-
-       /// Update one channel's data. The provided `ChannelMonitor` has already
-       /// applied the given update.
-       ///
-       /// Note that on every update, you **must** persist either the
-       /// `ChannelMonitorUpdate` or the updated monitor itself to disk/backups. See
-       /// the `Persist` trait documentation for more details.
-       ///
-       /// If an implementer chooses to persist the updates only, they need to make
-       /// sure that all the updates are applied to the `ChannelMonitors` *before*
-       /// the set of channel monitors is given to the `ChannelManager`
-       /// deserialization routine. See [`ChannelMonitor::update_monitor`] for
-       /// applying a monitor update to a monitor. If full `ChannelMonitors` are
-       /// persisted, then there is no need to persist individual updates.
-       ///
-       /// Note that there could be a performance tradeoff between persisting complete
-       /// channel monitors on every update vs. persisting only updates and applying
-       /// them in batches. The size of each monitor grows `O(number of state updates)`
-       /// whereas updates are small and `O(1)`.
-       ///
-       /// See [`ChannelMonitor::write`] for writing out a `ChannelMonitor`,
-       /// [`ChannelMonitorUpdate::write`] for writing out an update, and
-       /// [`ChannelMonitorUpdateErr`] for requirements when returning errors.
-       fn update_persisted_channel(&self, id: OutPoint, update: &ChannelMonitorUpdate, data: &ChannelMonitor<ChannelSigner>) -> Result<(), ChannelMonitorUpdateErr>;
-}
-
 impl<Signer: Sign, T: Deref, F: Deref, L: Deref> chain::Listen for (ChannelMonitor<Signer>, T, F, L)
 where
        T::Target: BroadcasterInterface,
        F::Target: FeeEstimator,
        L::Target: Logger,
 {
-       fn block_connected(&self, block: &Block, height: u32) {
-               let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
-               self.0.block_connected(&block.header, &txdata, height, &*self.1, &*self.2, &*self.3);
+       fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
+               self.0.block_connected(header, txdata, height, &*self.1, &*self.2, &*self.3);
        }
 
        fn block_disconnected(&self, header: &BlockHeader, height: u32) {
@@ -2742,7 +3043,7 @@ const MAX_ALLOC_SIZE: usize = 64*1024;
 
 impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                for (BlockHash, ChannelMonitor<Signer>) {
-       fn read<R: ::std::io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
+       fn read<R: io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
                macro_rules! unwrap_obj {
                        ($key: expr) => {
                                match $key {
@@ -2752,11 +3053,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                        }
                }
 
-               let _ver: u8 = Readable::read(reader)?;
-               let min_ver: u8 = Readable::read(reader)?;
-               if min_ver > SERIALIZATION_VERSION {
-                       return Err(DecodeError::UnknownVersion);
-               }
+               let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let latest_update_id: u64 = Readable::read(reader)?;
                let commitment_transaction_number_obscure_factor = <U48 as Readable>::read(reader)?.0;
@@ -2773,7 +3070,10 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                        _ => return Err(DecodeError::InvalidValue),
                };
                let counterparty_payment_script = Readable::read(reader)?;
-               let shutdown_script = Readable::read(reader)?;
+               let shutdown_script = {
+                       let script = <Script as Readable>::read(reader)?;
+                       if script.is_empty() { None } else { Some(script) }
+               };
 
                let channel_keys_id = Readable::read(reader)?;
                let holder_revocation_basepoint = Readable::read(reader)?;
@@ -2787,7 +3087,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                let current_counterparty_commitment_txid = Readable::read(reader)?;
                let prev_counterparty_commitment_txid = Readable::read(reader)?;
 
-               let counterparty_tx_cache = Readable::read(reader)?;
+               let counterparty_commitment_params = Readable::read(reader)?;
                let funding_redeemscript = Readable::read(reader)?;
                let channel_value_satoshis = Readable::read(reader)?;
 
@@ -2860,46 +3160,15 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                        }
                }
 
-               macro_rules! read_holder_tx {
-                       () => {
-                               {
-                                       let txid = Readable::read(reader)?;
-                                       let revocation_key = Readable::read(reader)?;
-                                       let a_htlc_key = Readable::read(reader)?;
-                                       let b_htlc_key = Readable::read(reader)?;
-                                       let delayed_payment_key = Readable::read(reader)?;
-                                       let per_commitment_point = Readable::read(reader)?;
-                                       let feerate_per_kw: u32 = Readable::read(reader)?;
-
-                                       let htlcs_len: u64 = Readable::read(reader)?;
-                                       let mut htlcs = Vec::with_capacity(cmp::min(htlcs_len as usize, MAX_ALLOC_SIZE / 128));
-                                       for _ in 0..htlcs_len {
-                                               let htlc = read_htlc_in_commitment!();
-                                               let sigs = match <u8 as Readable>::read(reader)? {
-                                                       0 => None,
-                                                       1 => Some(Readable::read(reader)?),
-                                                       _ => return Err(DecodeError::InvalidValue),
-                                               };
-                                               htlcs.push((htlc, sigs, Readable::read(reader)?));
-                                       }
-
-                                       HolderSignedTx {
-                                               txid,
-                                               revocation_key, a_htlc_key, b_htlc_key, delayed_payment_key, per_commitment_point, feerate_per_kw,
-                                               htlc_outputs: htlcs
-                                       }
-                               }
-                       }
-               }
-
-               let prev_holder_signed_commitment_tx = match <u8 as Readable>::read(reader)? {
-                       0 => None,
-                       1 => {
-                               Some(read_holder_tx!())
-                       },
-                       _ => return Err(DecodeError::InvalidValue),
-               };
-               let current_holder_commitment_tx = read_holder_tx!();
+               let mut prev_holder_signed_commitment_tx: Option<HolderSignedTx> =
+                       match <u8 as Readable>::read(reader)? {
+                               0 => None,
+                               1 => {
+                                       Some(Readable::read(reader)?)
+                               },
+                               _ => return Err(DecodeError::InvalidValue),
+                       };
+               let mut current_holder_commitment_tx: HolderSignedTx = Readable::read(reader)?;
 
                let current_counterparty_commitment_number = <U48 as Readable>::read(reader)?.0;
                let current_holder_commitment_number = <U48 as Readable>::read(reader)?.0;
@@ -2915,14 +3184,15 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                }
 
                let pending_monitor_events_len: u64 = Readable::read(reader)?;
-               let mut pending_monitor_events = Vec::with_capacity(cmp::min(pending_monitor_events_len as usize, MAX_ALLOC_SIZE / (32 + 8*3)));
+               let mut pending_monitor_events = Some(
+                       Vec::with_capacity(cmp::min(pending_monitor_events_len as usize, MAX_ALLOC_SIZE / (32 + 8*3))));
                for _ in 0..pending_monitor_events_len {
                        let ev = match <u8 as Readable>::read(reader)? {
                                0 => MonitorEvent::HTLCEvent(Readable::read(reader)?),
-                               1 => MonitorEvent::CommitmentTxBroadcasted(funding_info.0),
+                               1 => MonitorEvent::CommitmentTxConfirmed(funding_info.0),
                                _ => return Err(DecodeError::InvalidValue)
                        };
-                       pending_monitor_events.push(ev);
+                       pending_monitor_events.as_mut().unwrap().push(ev);
                }
 
                let pending_events_len: u64 = Readable::read(reader)?;
@@ -2938,25 +3208,9 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                let waiting_threshold_conf_len: u64 = Readable::read(reader)?;
                let mut onchain_events_awaiting_threshold_conf = Vec::with_capacity(cmp::min(waiting_threshold_conf_len as usize, MAX_ALLOC_SIZE / 128));
                for _ in 0..waiting_threshold_conf_len {
-                       let txid = Readable::read(reader)?;
-                       let height = Readable::read(reader)?;
-                       let event = match <u8 as Readable>::read(reader)? {
-                               0 => {
-                                       let htlc_source = Readable::read(reader)?;
-                                       let hash = Readable::read(reader)?;
-                                       OnchainEvent::HTLCUpdate {
-                                               htlc_update: (htlc_source, hash)
-                                       }
-                               },
-                               1 => {
-                                       let descriptor = Readable::read(reader)?;
-                                       OnchainEvent::MaturingOutput {
-                                               descriptor
-                                       }
-                               },
-                               _ => return Err(DecodeError::InvalidValue),
-                       };
-                       onchain_events_awaiting_threshold_conf.push(OnchainEventEntry { txid, height, event });
+                       if let Some(val) = MaybeReadable::read(reader)? {
+                               onchain_events_awaiting_threshold_conf.push(val);
+                       }
                }
 
                let outputs_to_watch_len: u64 = Readable::read(reader)?;
@@ -2972,11 +3226,38 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                                return Err(DecodeError::InvalidValue);
                        }
                }
-               let onchain_tx_handler = ReadableArgs::read(reader, keys_manager)?;
+               let onchain_tx_handler: OnchainTxHandler<Signer> = ReadableArgs::read(reader, keys_manager)?;
 
                let lockdown_from_offchain = Readable::read(reader)?;
                let holder_tx_signed = Readable::read(reader)?;
 
+               if let Some(prev_commitment_tx) = prev_holder_signed_commitment_tx.as_mut() {
+                       let prev_holder_value = onchain_tx_handler.get_prev_holder_commitment_to_self_value();
+                       if prev_holder_value.is_none() { return Err(DecodeError::InvalidValue); }
+                       if prev_commitment_tx.to_self_value_sat == u64::max_value() {
+                               prev_commitment_tx.to_self_value_sat = prev_holder_value.unwrap();
+                       } else if prev_commitment_tx.to_self_value_sat != prev_holder_value.unwrap() {
+                               return Err(DecodeError::InvalidValue);
+                       }
+               }
+
+               let cur_holder_value = onchain_tx_handler.get_cur_holder_commitment_to_self_value();
+               if current_holder_commitment_tx.to_self_value_sat == u64::max_value() {
+                       current_holder_commitment_tx.to_self_value_sat = cur_holder_value;
+               } else if current_holder_commitment_tx.to_self_value_sat != cur_holder_value {
+                       return Err(DecodeError::InvalidValue);
+               }
+
+               let mut funding_spend_confirmed = None;
+               let mut htlcs_resolved_on_chain = Some(Vec::new());
+               let mut funding_spend_seen = Some(false);
+               read_tlv_fields!(reader, {
+                       (1, funding_spend_confirmed, option),
+                       (3, htlcs_resolved_on_chain, vec_type),
+                       (5, pending_monitor_events, vec_type),
+                       (7, funding_spend_seen, option),
+               });
+
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
 
@@ -2996,7 +3277,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                                current_counterparty_commitment_txid,
                                prev_counterparty_commitment_txid,
 
-                               counterparty_tx_cache,
+                               counterparty_commitment_params,
                                funding_redeemscript,
                                channel_value_satoshis,
                                their_cur_revocation_points,
@@ -3014,7 +3295,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                                current_holder_commitment_number,
 
                                payment_preimages,
-                               pending_monitor_events,
+                               pending_monitor_events: pending_monitor_events.unwrap(),
                                pending_events,
 
                                onchain_events_awaiting_threshold_conf,
@@ -3024,6 +3305,9 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
 
                                lockdown_from_offchain,
                                holder_tx_signed,
+                               funding_spend_seen: funding_spend_seen.unwrap(),
+                               funding_spend_confirmed,
+                               htlcs_resolved_on_chain: htlcs_resolved_on_chain.unwrap(),
 
                                best_block,
 
@@ -3035,6 +3319,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
 
 #[cfg(test)]
 mod tests {
+       use bitcoin::blockdata::block::BlockHeader;
        use bitcoin::blockdata::script::{Script, Builder};
        use bitcoin::blockdata::opcodes;
        use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, SigHashType};
@@ -3043,27 +3328,134 @@ mod tests {
        use bitcoin::hashes::Hash;
        use bitcoin::hashes::sha256::Hash as Sha256;
        use bitcoin::hashes::hex::FromHex;
-       use bitcoin::hash_types::Txid;
+       use bitcoin::hash_types::{BlockHash, Txid};
        use bitcoin::network::constants::Network;
+       use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+       use bitcoin::secp256k1::Secp256k1;
+
        use hex;
+
+       use super::ChannelMonitorUpdateStep;
+       use ::{check_added_monitors, check_closed_broadcast, check_closed_event, check_spends, get_local_commitment_txn, get_monitor, get_route_and_payment_hash, unwrap_send_err};
+       use chain::{BestBlock, Confirm};
        use chain::channelmonitor::ChannelMonitor;
+       use chain::package::{weight_offered_htlc, weight_received_htlc, weight_revoked_offered_htlc, weight_revoked_received_htlc, WEIGHT_REVOKED_OUTPUT};
        use chain::transaction::OutPoint;
-       use ln::channelmanager::{BestBlock, PaymentPreimage, PaymentHash};
-       use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
+       use chain::keysinterface::InMemorySigner;
+       use ln::{PaymentPreimage, PaymentHash};
        use ln::chan_utils;
        use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
+       use ln::channelmanager::PaymentSendFailure;
+       use ln::features::InitFeatures;
+       use ln::functional_test_utils::*;
+       use ln::script::ShutdownScript;
+       use util::errors::APIError;
+       use util::events::{ClosureReason, MessageSendEventsProvider};
        use util::test_utils::{TestLogger, TestBroadcaster, TestFeeEstimator};
-       use bitcoin::secp256k1::key::{SecretKey,PublicKey};
-       use bitcoin::secp256k1::Secp256k1;
-       use std::sync::{Arc, Mutex};
-       use chain::keysinterface::InMemorySigner;
+       use util::ser::{ReadableArgs, Writeable};
+       use sync::{Arc, Mutex};
+       use io;
+       use prelude::*;
+
+       fn do_test_funding_spend_refuses_updates(use_local_txn: bool) {
+               // Previously, monitor updates were allowed freely even after a funding-spend transaction
+               // confirmed. This would allow a race condition where we could receive a payment (including
+               // the counterparty revoking their broadcasted state!) and accept it without recourse as
+               // long as the ChannelMonitor receives the block first, the full commitment update dance
+               // occurs after the block is connected, and before the ChannelManager receives the block.
+               // Obviously this is an incredibly contrived race given the counterparty would be risking
+               // their full channel balance for it, but its worth fixing nonetheless as it makes the
+               // potential ChannelMonitor states simpler to reason about.
+               //
+               // This test checks said behavior, as well as ensuring a ChannelMonitorUpdate with multiple
+               // updates is handled correctly in such conditions.
+               let chanmon_cfgs = create_chanmon_cfgs(3);
+               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, InitFeatures::known(), InitFeatures::known());
+               create_announced_chan_between_nodes(
+                       &nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
+
+               // Rebalance somewhat
+               send_payment(&nodes[0], &[&nodes[1]], 10_000_000);
+
+               // First route two payments for testing at the end
+               let payment_preimage_1 = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000).0;
+               let payment_preimage_2 = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000).0;
+
+               let local_txn = get_local_commitment_txn!(nodes[1], channel.2);
+               assert_eq!(local_txn.len(), 1);
+               let remote_txn = get_local_commitment_txn!(nodes[0], channel.2);
+               assert_eq!(remote_txn.len(), 3); // Commitment and two HTLC-Timeouts
+               check_spends!(remote_txn[1], remote_txn[0]);
+               check_spends!(remote_txn[2], remote_txn[0]);
+               let broadcast_tx = if use_local_txn { &local_txn[0] } else { &remote_txn[0] };
+
+               // Connect a commitment transaction, but only to the ChainMonitor/ChannelMonitor. The
+               // channel is now closed, but the ChannelManager doesn't know that yet.
+               let new_header = BlockHeader {
+                       version: 2, time: 0, bits: 0, nonce: 0,
+                       prev_blockhash: nodes[0].best_block_info().0,
+                       merkle_root: Default::default() };
+               let conf_height = nodes[0].best_block_info().1 + 1;
+               nodes[1].chain_monitor.chain_monitor.transactions_confirmed(&new_header,
+                       &[(0, broadcast_tx)], conf_height);
+
+               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();
+
+               // 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).
+               let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 100_000);
+               unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)),
+                       true, APIError::ChannelUnavailable { ref err },
+                       assert!(err.contains("ChannelMonitor storage failure")));
+               check_added_monitors!(nodes[1], 2); // After the failure we generate a close-channel monitor update
+               check_closed_broadcast!(nodes[1], true);
+               check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: "ChannelMonitor storage failure".to_string() });
+
+               // Build a new ChannelMonitorUpdate which contains both the failing commitment tx update
+               // and provides the claim preimages for the two pending HTLCs. The first update generates
+               // an error, but the point of this test is to ensure the later updates are still applied.
+               let monitor_updates = nodes[1].chain_monitor.monitor_updates.lock().unwrap();
+               let mut replay_update = monitor_updates.get(&channel.2).unwrap().iter().rev().skip(1).next().unwrap().clone();
+               assert_eq!(replay_update.updates.len(), 1);
+               if let ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } = replay_update.updates[0] {
+               } else { panic!(); }
+               replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_1 });
+               replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_2 });
+
+               let broadcaster = TestBroadcaster::new(Arc::clone(&nodes[1].blocks));
+               assert!(
+                       pre_update_monitor.update_monitor(&replay_update, &&broadcaster, &&chanmon_cfgs[1].fee_estimator, &nodes[1].logger)
+                       .is_err());
+               // Even though we error'd on the first update, we should still have generated an HTLC claim
+               // transaction
+               let txn_broadcasted = broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
+               assert!(txn_broadcasted.len() >= 2);
+               let htlc_txn = txn_broadcasted.iter().filter(|tx| {
+                       assert_eq!(tx.input.len(), 1);
+                       tx.input[0].previous_output.txid == broadcast_tx.txid()
+               }).collect::<Vec<_>>();
+               assert_eq!(htlc_txn.len(), 2);
+               check_spends!(htlc_txn[0], broadcast_tx);
+               check_spends!(htlc_txn[1], broadcast_tx);
+       }
+       #[test]
+       fn test_funding_spend_refuses_updates() {
+               do_test_funding_spend_refuses_updates(true);
+               do_test_funding_spend_refuses_updates(false);
+       }
 
        #[test]
        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())});
-               let fee_estimator = Arc::new(TestFeeEstimator { sat_per_kw: 253 });
+               let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))});
+               let fee_estimator = Arc::new(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: 0, input: Vec::new(), output: Vec::new() };
@@ -3119,6 +3511,7 @@ 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]
@@ -3141,12 +3534,14 @@ mod tests {
                                selected_contest_delay: 67,
                        }),
                        funding_outpoint: Some(funding_outpoint),
+                       opt_anchors: None,
                };
                // 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 monitor = ChannelMonitor::new(Secp256k1::new(), keys,
-                                                 &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0, &Script::new(),
+                                                 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,
@@ -3202,28 +3597,27 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let privkey = SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
                let pubkey = PublicKey::from_secret_key(&secp_ctx, &privkey);
-               let mut sum_actual_sigs = 0;
 
                macro_rules! sign_input {
-                       ($sighash_parts: expr, $idx: expr, $amount: expr, $input_type: expr, $sum_actual_sigs: expr) => {
+                       ($sighash_parts: expr, $idx: expr, $amount: expr, $weight: expr, $sum_actual_sigs: expr, $opt_anchors: expr) => {
                                let htlc = HTLCOutputInCommitment {
-                                       offered: if *$input_type == InputDescriptors::RevokedOfferedHTLC || *$input_type == InputDescriptors::OfferedHTLC { true } else { false },
+                                       offered: if *$weight == weight_revoked_offered_htlc($opt_anchors) || *$weight == weight_offered_htlc($opt_anchors) { true } else { false },
                                        amount_msat: 0,
                                        cltv_expiry: 2 << 16,
                                        payment_hash: PaymentHash([1; 32]),
                                        transaction_output_index: Some($idx as u32),
                                };
-                               let redeem_script = if *$input_type == InputDescriptors::RevokedOutput { chan_utils::get_revokeable_redeemscript(&pubkey, 256, &pubkey) } else { chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &pubkey, &pubkey, &pubkey) };
+                               let redeem_script = if *$weight == WEIGHT_REVOKED_OUTPUT { chan_utils::get_revokeable_redeemscript(&pubkey, 256, &pubkey) } else { chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, $opt_anchors, &pubkey, &pubkey, &pubkey) };
                                let sighash = hash_to_message!(&$sighash_parts.signature_hash($idx, &redeem_script, $amount, SigHashType::All)[..]);
                                let sig = secp_ctx.sign(&sighash, &privkey);
                                $sighash_parts.access_witness($idx).push(sig.serialize_der().to_vec());
                                $sighash_parts.access_witness($idx)[0].push(SigHashType::All as u8);
-                               sum_actual_sigs += $sighash_parts.access_witness($idx)[0].len();
-                               if *$input_type == InputDescriptors::RevokedOutput {
+                               $sum_actual_sigs += $sighash_parts.access_witness($idx)[0].len();
+                               if *$weight == WEIGHT_REVOKED_OUTPUT {
                                        $sighash_parts.access_witness($idx).push(vec!(1));
-                               } else if *$input_type == InputDescriptors::RevokedOfferedHTLC || *$input_type == InputDescriptors::RevokedReceivedHTLC {
+                               } else if *$weight == weight_revoked_offered_htlc($opt_anchors) || *$weight == weight_revoked_received_htlc($opt_anchors) {
                                        $sighash_parts.access_witness($idx).push(pubkey.clone().serialize().to_vec());
-                               } else if *$input_type == InputDescriptors::ReceivedHTLC {
+                               } else if *$weight == weight_received_htlc($opt_anchors) {
                                        $sighash_parts.access_witness($idx).push(vec![0]);
                                } else {
                                        $sighash_parts.access_witness($idx).push(PaymentPreimage([1; 32]).0.to_vec());
@@ -3239,77 +3633,98 @@ mod tests {
                let txid = Txid::from_hex("56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d").unwrap();
 
                // Justice tx with 1 to_holder, 2 revoked offered HTLCs, 1 revoked received HTLCs
-               let mut claim_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
-               for i in 0..4 {
-                       claim_tx.input.push(TxIn {
-                               previous_output: BitcoinOutPoint {
-                                       txid,
-                                       vout: i,
-                               },
-                               script_sig: Script::new(),
-                               sequence: 0xfffffffd,
-                               witness: Vec::new(),
+               for &opt_anchors in [false, true].iter() {
+                       let mut claim_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
+                       let mut sum_actual_sigs = 0;
+                       for i in 0..4 {
+                               claim_tx.input.push(TxIn {
+                                       previous_output: BitcoinOutPoint {
+                                               txid,
+                                               vout: i,
+                                       },
+                                       script_sig: Script::new(),
+                                       sequence: 0xfffffffd,
+                                       witness: Vec::new(),
+                               });
+                       }
+                       claim_tx.output.push(TxOut {
+                               script_pubkey: script_pubkey.clone(),
+                               value: 0,
                        });
-               }
-               claim_tx.output.push(TxOut {
-                       script_pubkey: script_pubkey.clone(),
-                       value: 0,
-               });
-               let base_weight = claim_tx.get_weight();
-               let inputs_des = vec![InputDescriptors::RevokedOutput, InputDescriptors::RevokedOfferedHTLC, InputDescriptors::RevokedOfferedHTLC, InputDescriptors::RevokedReceivedHTLC];
-               {
-                       let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
-                       for (idx, inp) in inputs_des.iter().enumerate() {
-                               sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
+                       let base_weight = claim_tx.get_weight();
+                       let inputs_weight = vec![WEIGHT_REVOKED_OUTPUT, weight_revoked_offered_htlc(opt_anchors), weight_revoked_offered_htlc(opt_anchors), weight_revoked_received_htlc(opt_anchors)];
+                       let mut inputs_total_weight = 2; // count segwit flags
+                       {
+                               let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+                               for (idx, inp) in inputs_weight.iter().enumerate() {
+                                       sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors);
+                                       inputs_total_weight += inp;
+                               }
                        }
+                       assert_eq!(base_weight + inputs_total_weight as usize,  claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_weight.len() - sum_actual_sigs));
                }
-               assert_eq!(base_weight + OnchainTxHandler::<InMemorySigner>::get_witnesses_weight(&inputs_des[..]),  claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_des.len() - sum_actual_sigs));
 
                // Claim tx with 1 offered HTLCs, 3 received HTLCs
-               claim_tx.input.clear();
-               sum_actual_sigs = 0;
-               for i in 0..4 {
+               for &opt_anchors in [false, true].iter() {
+                       let mut claim_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
+                       let mut sum_actual_sigs = 0;
+                       for i in 0..4 {
+                               claim_tx.input.push(TxIn {
+                                       previous_output: BitcoinOutPoint {
+                                               txid,
+                                               vout: i,
+                                       },
+                                       script_sig: Script::new(),
+                                       sequence: 0xfffffffd,
+                                       witness: Vec::new(),
+                               });
+                       }
+                       claim_tx.output.push(TxOut {
+                               script_pubkey: script_pubkey.clone(),
+                               value: 0,
+                       });
+                       let base_weight = claim_tx.get_weight();
+                       let inputs_weight = vec![weight_offered_htlc(opt_anchors), weight_received_htlc(opt_anchors), weight_received_htlc(opt_anchors), weight_received_htlc(opt_anchors)];
+                       let mut inputs_total_weight = 2; // count segwit flags
+                       {
+                               let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+                               for (idx, inp) in inputs_weight.iter().enumerate() {
+                                       sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors);
+                                       inputs_total_weight += inp;
+                               }
+                       }
+                       assert_eq!(base_weight + inputs_total_weight as usize,  claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_weight.len() - sum_actual_sigs));
+               }
+
+               // Justice tx with 1 revoked HTLC-Success tx output
+               for &opt_anchors in [false, true].iter() {
+                       let mut claim_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
+                       let mut sum_actual_sigs = 0;
                        claim_tx.input.push(TxIn {
                                previous_output: BitcoinOutPoint {
                                        txid,
-                                       vout: i,
+                                       vout: 0,
                                },
                                script_sig: Script::new(),
                                sequence: 0xfffffffd,
                                witness: Vec::new(),
                        });
-               }
-               let base_weight = claim_tx.get_weight();
-               let inputs_des = vec![InputDescriptors::OfferedHTLC, InputDescriptors::ReceivedHTLC, InputDescriptors::ReceivedHTLC, InputDescriptors::ReceivedHTLC];
-               {
-                       let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
-                       for (idx, inp) in inputs_des.iter().enumerate() {
-                               sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
-                       }
-               }
-               assert_eq!(base_weight + OnchainTxHandler::<InMemorySigner>::get_witnesses_weight(&inputs_des[..]),  claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_des.len() - sum_actual_sigs));
-
-               // Justice tx with 1 revoked HTLC-Success tx output
-               claim_tx.input.clear();
-               sum_actual_sigs = 0;
-               claim_tx.input.push(TxIn {
-                       previous_output: BitcoinOutPoint {
-                               txid,
-                               vout: 0,
-                       },
-                       script_sig: Script::new(),
-                       sequence: 0xfffffffd,
-                       witness: Vec::new(),
-               });
-               let base_weight = claim_tx.get_weight();
-               let inputs_des = vec![InputDescriptors::RevokedOutput];
-               {
-                       let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
-                       for (idx, inp) in inputs_des.iter().enumerate() {
-                               sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
+                       claim_tx.output.push(TxOut {
+                               script_pubkey: script_pubkey.clone(),
+                               value: 0,
+                       });
+                       let base_weight = claim_tx.get_weight();
+                       let inputs_weight = vec![WEIGHT_REVOKED_OUTPUT];
+                       let mut inputs_total_weight = 2; // count segwit flags
+                       {
+                               let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+                               for (idx, inp) in inputs_weight.iter().enumerate() {
+                                       sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors);
+                                       inputs_total_weight += inp;
+                               }
                        }
+                       assert_eq!(base_weight + inputs_total_weight as usize, claim_tx.get_weight() + /* max_length_isg */ (73 * inputs_weight.len() - sum_actual_sigs));
                }
-               assert_eq!(base_weight + OnchainTxHandler::<InMemorySigner>::get_witnesses_weight(&inputs_des[..]), claim_tx.get_weight() + /* max_length_isg */ (73 * inputs_des.len() - sum_actual_sigs));
        }
 
        // Further testing is done in the ChannelManager integration tests.