Support all shutdown scripts defined in BOLT 2
[rust-lightning] / lightning / src / ln / channel.rs
index dc2dd758a9ea97bae465a69836f79200190c97d7..f6313c075de444d62088d44dc35d6dc48f4a9b84 100644 (file)
@@ -9,15 +9,15 @@
 
 use bitcoin::blockdata::script::{Script,Builder};
 use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType};
-use bitcoin::blockdata::opcodes;
 use bitcoin::util::bip143;
 use bitcoin::consensus::encode;
 
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::sha256d::Hash as Sha256d;
-use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
+use bitcoin::hash_types::{Txid, BlockHash};
 
+use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE;
 use bitcoin::secp256k1::key::{PublicKey,SecretKey};
 use bitcoin::secp256k1::{Secp256k1,Signature};
 use bitcoin::secp256k1;
@@ -26,6 +26,7 @@ use ln::{PaymentPreimage, PaymentHash};
 use ln::features::{ChannelFeatures, InitFeatures};
 use ln::msgs;
 use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
+use ln::script::ShutdownScript;
 use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
 use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor};
 use ln::chan_utils;
@@ -43,11 +44,11 @@ use util::scid_utils::scid_from_parts;
 
 use prelude::*;
 use core::{cmp,mem,fmt};
+use core::convert::TryFrom;
 use core::ops::Deref;
 #[cfg(any(test, feature = "fuzztarget", debug_assertions))]
 use sync::Mutex;
 use bitcoin::hashes::hex::ToHex;
-use bitcoin::blockdata::opcodes::all::OP_PUSHBYTES_0;
 
 #[cfg(test)]
 pub struct ChannelValueStat {
@@ -301,6 +302,33 @@ pub struct CounterpartyForwardingInfo {
        pub cltv_expiry_delta: u16,
 }
 
+/// A return value enum for get_update_fulfill_htlc. See UpdateFulfillCommitFetch variants for
+/// description
+enum UpdateFulfillFetch {
+       NewClaim {
+               monitor_update: ChannelMonitorUpdate,
+               msg: Option<msgs::UpdateFulfillHTLC>,
+       },
+       DuplicateClaim {},
+}
+
+/// The return type of get_update_fulfill_htlc_and_commit.
+pub enum UpdateFulfillCommitFetch {
+       /// Indicates the HTLC fulfill is new, and either generated an update_fulfill message, placed
+       /// it in the holding cell, or re-generated the update_fulfill message after the same claim was
+       /// previously placed in the holding cell (and has since been removed).
+       NewClaim {
+               /// The ChannelMonitorUpdate which places the new payment preimage in the channel monitor
+               monitor_update: ChannelMonitorUpdate,
+               /// The update_fulfill message and commitment_signed message (if the claim was not placed
+               /// in the holding cell).
+               msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>,
+       },
+       /// Indicates the HTLC fulfill is duplicative and already existed either in the holding cell
+       /// or has been forgotten (presumably previously claimed).
+       DuplicateClaim {},
+}
+
 // TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
 // has been completed, and then turn into a Channel to get compiler-time enforcement of things like
 // calling channel_id() before we're set up or things like get_outbound_funding_signed on an
@@ -321,7 +349,7 @@ pub(super) struct Channel<Signer: Sign> {
        latest_monitor_update_id: u64,
 
        holder_signer: Signer,
-       shutdown_pubkey: PublicKey,
+       shutdown_scriptpubkey: Option<ShutdownScript>,
        destination_script: Script,
 
        // Our commitment numbers start at 2^48-1 and count down, whereas the ones used in transaction
@@ -444,6 +472,15 @@ pub(super) struct Channel<Signer: Sign> {
        ///
        /// See-also <https://github.com/lightningnetwork/lnd/issues/4006>
        pub workaround_lnd_bug_4006: Option<msgs::FundingLocked>,
+
+       #[cfg(any(test, feature = "fuzztarget"))]
+       // When we receive an HTLC fulfill on an outbound path, we may immediately fulfill the
+       // corresponding HTLC on the inbound path. If, then, the outbound path channel is
+       // disconnected and reconnected (before we've exchange commitment_signed and revoke_and_ack
+       // messages), they may re-broadcast their update_fulfill_htlc, causing a duplicate claim. This
+       // is fine, but as a sanity check in our failure to generate the second claim, we check here
+       // that the original was a claim, and that we aren't now trying to fulfill a failed HTLC.
+       historical_inbound_htlc_fulfills: HashSet<u64>,
 }
 
 #[cfg(any(test, feature = "fuzztarget"))]
@@ -570,7 +607,7 @@ impl<Signer: Sign> Channel<Signer> {
                        latest_monitor_update_id: 0,
 
                        holder_signer,
-                       shutdown_pubkey: keys_provider.get_shutdown_pubkey(),
+                       shutdown_scriptpubkey: Some(keys_provider.get_shutdown_scriptpubkey()),
                        destination_script: keys_provider.get_destination_script(),
 
                        cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
@@ -644,6 +681,9 @@ impl<Signer: Sign> Channel<Signer> {
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
+
+                       #[cfg(any(test, feature = "fuzztarget"))]
+                       historical_inbound_htlc_fulfills: HashSet::new(),
                })
        }
 
@@ -783,11 +823,11 @@ impl<Signer: Sign> Channel<Signer> {
                                        // Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
                                        if script.len() == 0 {
                                                None
-                                       // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
-                                       } else if is_unsupported_shutdown_script(&their_features, script) {
-                                               return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
                                        } else {
-                                               Some(script.clone())
+                                               match ShutdownScript::try_from((script.clone(), &their_features)) {
+                                                       Ok(shutdown_script) => Some(shutdown_script.into_inner()),
+                                                       Err(_) => return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex()))),
+                                               }
                                        }
                                },
                                // Peer is signaling upfront shutdown but don't opt-out with correct mechanism (a.k.a 0-length script). Peer looks buggy, we fail the channel
@@ -811,7 +851,7 @@ impl<Signer: Sign> Channel<Signer> {
                        latest_monitor_update_id: 0,
 
                        holder_signer,
-                       shutdown_pubkey: keys_provider.get_shutdown_pubkey(),
+                       shutdown_scriptpubkey: Some(keys_provider.get_shutdown_scriptpubkey()),
                        destination_script: keys_provider.get_destination_script(),
 
                        cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
@@ -889,6 +929,9 @@ impl<Signer: Sign> Channel<Signer> {
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
+
+                       #[cfg(any(test, feature = "fuzztarget"))]
+                       historical_inbound_htlc_fulfills: HashSet::new(),
                };
 
                Ok(chan)
@@ -1087,8 +1130,7 @@ impl<Signer: Sign> Channel<Signer> {
 
        #[inline]
        fn get_closing_scriptpubkey(&self) -> Script {
-               let channel_close_key_hash = WPubkeyHash::hash(&self.shutdown_pubkey.serialize());
-               Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&channel_close_key_hash[..]).into_script()
+               self.shutdown_scriptpubkey.clone().unwrap().into_inner()
        }
 
        #[inline]
@@ -1216,13 +1258,7 @@ impl<Signer: Sign> Channel<Signer> {
                make_funding_redeemscript(&self.get_holder_pubkeys().funding_pubkey, self.counterparty_funding_pubkey())
        }
 
-       /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
-       /// In such cases we debug_assert!(false) and return a ChannelError::Ignore. Thus, will always
-       /// return Ok(_) if debug assertions are turned on or preconditions are met.
-       ///
-       /// Note that it is still possible to hit these assertions in case we find a preimage on-chain
-       /// but then have a reorg which settles on an HTLC-failure on chain.
-       fn get_update_fulfill_htlc<L: Deref>(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage, logger: &L) -> Result<(Option<msgs::UpdateFulfillHTLC>, Option<ChannelMonitorUpdate>), ChannelError> where L::Target: Logger {
+       fn get_update_fulfill_htlc<L: Deref>(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage, logger: &L) -> UpdateFulfillFetch where L::Target: Logger {
                // Either ChannelFunded got set (which means it won't be unset) or there is no way any
                // caller thought we could have something claimed (cause we wouldn't have accepted in an
                // incoming HTLC anyway). If we got to ShutdownComplete, callers aren't allowed to call us,
@@ -1248,9 +1284,9 @@ impl<Signer: Sign> Channel<Signer> {
                                                if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
                                                } else {
                                                        log_warn!(logger, "Have preimage and want to fulfill HTLC with payment hash {} we already failed against channel {}", log_bytes!(htlc.payment_hash.0), log_bytes!(self.channel_id()));
+                                                       debug_assert!(false, "Tried to fulfill an HTLC that was already failed");
                                                }
-                                               debug_assert!(false, "Tried to fulfill an HTLC that was already fail/fulfilled");
-                                               return Ok((None, None));
+                                               return UpdateFulfillFetch::DuplicateClaim {};
                                        },
                                        _ => {
                                                debug_assert!(false, "Have an inbound HTLC we tried to claim before it was fully committed to");
@@ -1262,7 +1298,11 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
                if pending_idx == core::usize::MAX {
-                       return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID".to_owned()));
+                       #[cfg(any(test, feature = "fuzztarget"))]
+                       // If we failed to find an HTLC to fulfill, make sure it was previously fulfilled and
+                       // this is simply a duplicate claim, not previously failed and we lost funds.
+                       debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
+                       return UpdateFulfillFetch::DuplicateClaim {};
                }
 
                // Now update local state:
@@ -1284,8 +1324,9 @@ impl<Signer: Sign> Channel<Signer> {
                                                if htlc_id_arg == htlc_id {
                                                        // Make sure we don't leave latest_monitor_update_id incremented here:
                                                        self.latest_monitor_update_id -= 1;
-                                                       debug_assert!(false, "Tried to fulfill an HTLC that was already fulfilled");
-                                                       return Ok((None, None));
+                                                       #[cfg(any(test, feature = "fuzztarget"))]
+                                                       debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
+                                                       return UpdateFulfillFetch::DuplicateClaim {};
                                                }
                                        },
                                        &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, .. } => {
@@ -1294,7 +1335,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                        // TODO: We may actually be able to switch to a fulfill here, though its
                                                        // rare enough it may not be worth the complexity burden.
                                                        debug_assert!(false, "Tried to fulfill an HTLC that was already failed");
-                                                       return Ok((None, Some(monitor_update)));
+                                                       return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
                                                }
                                        },
                                        _ => {}
@@ -1304,52 +1345,58 @@ impl<Signer: Sign> Channel<Signer> {
                        self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::ClaimHTLC {
                                payment_preimage: payment_preimage_arg, htlc_id: htlc_id_arg,
                        });
-                       return Ok((None, Some(monitor_update)));
+                       #[cfg(any(test, feature = "fuzztarget"))]
+                       self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
+                       return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
                }
+               #[cfg(any(test, feature = "fuzztarget"))]
+               self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
 
                {
                        let htlc = &mut self.pending_inbound_htlcs[pending_idx];
                        if let InboundHTLCState::Committed = htlc.state {
                        } else {
                                debug_assert!(false, "Have an inbound HTLC we tried to claim before it was fully committed to");
-                               return Ok((None, Some(monitor_update)));
+                               return UpdateFulfillFetch::NewClaim { monitor_update, msg: None };
                        }
                        log_trace!(logger, "Upgrading HTLC {} to LocalRemoved with a Fulfill in channel {}!", log_bytes!(htlc.payment_hash.0), log_bytes!(self.channel_id));
                        htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(payment_preimage_arg.clone()));
                }
 
-               Ok((Some(msgs::UpdateFulfillHTLC {
-                       channel_id: self.channel_id(),
-                       htlc_id: htlc_id_arg,
-                       payment_preimage: payment_preimage_arg,
-               }), Some(monitor_update)))
+               UpdateFulfillFetch::NewClaim {
+                       monitor_update,
+                       msg: Some(msgs::UpdateFulfillHTLC {
+                               channel_id: self.channel_id(),
+                               htlc_id: htlc_id_arg,
+                               payment_preimage: payment_preimage_arg,
+                       }),
+               }
        }
 
-       pub fn get_update_fulfill_htlc_and_commit<L: Deref>(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage, logger: &L) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option<ChannelMonitorUpdate>), ChannelError> where L::Target: Logger {
-               match self.get_update_fulfill_htlc(htlc_id, payment_preimage, logger)? {
-                       (Some(update_fulfill_htlc), Some(mut monitor_update)) => {
-                               let (commitment, mut additional_update) = self.send_commitment_no_status_check(logger)?;
+       pub fn get_update_fulfill_htlc_and_commit<L: Deref>(&mut self, htlc_id: u64, payment_preimage: PaymentPreimage, logger: &L) -> Result<UpdateFulfillCommitFetch, (ChannelError, ChannelMonitorUpdate)> where L::Target: Logger {
+               match self.get_update_fulfill_htlc(htlc_id, payment_preimage, logger) {
+                       UpdateFulfillFetch::NewClaim { mut monitor_update, msg: Some(update_fulfill_htlc) } => {
+                               let (commitment, mut additional_update) = match self.send_commitment_no_status_check(logger) {
+                                       Err(e) => return Err((e, monitor_update)),
+                                       Ok(res) => res
+                               };
                                // send_commitment_no_status_check may bump latest_monitor_id but we want them to be
                                // strictly increasing by one, so decrement it here.
                                self.latest_monitor_update_id = monitor_update.update_id;
                                monitor_update.updates.append(&mut additional_update.updates);
-                               Ok((Some((update_fulfill_htlc, commitment)), Some(monitor_update)))
+                               Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, msgs: Some((update_fulfill_htlc, commitment)) })
                        },
-                       (Some(update_fulfill_htlc), None) => {
-                               let (commitment, monitor_update) = self.send_commitment_no_status_check(logger)?;
-                               Ok((Some((update_fulfill_htlc, commitment)), Some(monitor_update)))
-                       },
-                       (None, Some(monitor_update)) => Ok((None, Some(monitor_update))),
-                       (None, None) => Ok((None, None))
+                       UpdateFulfillFetch::NewClaim { monitor_update, msg: None } => Ok(UpdateFulfillCommitFetch::NewClaim { monitor_update, msgs: None }),
+                       UpdateFulfillFetch::DuplicateClaim {} => Ok(UpdateFulfillCommitFetch::DuplicateClaim {}),
                }
        }
 
-       /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
-       /// In such cases we debug_assert!(false) and return a ChannelError::Ignore. Thus, will always
-       /// return Ok(_) if debug assertions are turned on or preconditions are met.
-       ///
-       /// Note that it is still possible to hit these assertions in case we find a preimage on-chain
-       /// but then have a reorg which settles on an HTLC-failure on chain.
+       /// We can only have one resolution per HTLC. In some cases around reconnect, we may fulfill
+       /// an HTLC more than once or fulfill once and then attempt to fail after reconnect. We cannot,
+       /// however, fail more than once as we wait for an upstream failure to be irrevocably committed
+       /// before we fail backwards.
+       /// If we do fail twice, we debug_assert!(false) and return Ok(None). Thus, will always return
+       /// Ok(_) if debug assertions are turned on or preconditions are met.
        pub fn get_update_fail_htlc<L: Deref>(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket, logger: &L) -> Result<Option<msgs::UpdateFailHTLC>, ChannelError> where L::Target: Logger {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
                        panic!("Was asked to fail an HTLC when channel was not in an operational state");
@@ -1365,8 +1412,11 @@ impl<Signer: Sign> Channel<Signer> {
                        if htlc.htlc_id == htlc_id_arg {
                                match htlc.state {
                                        InboundHTLCState::Committed => {},
-                                       InboundHTLCState::LocalRemoved(_) => {
-                                               debug_assert!(false, "Tried to fail an HTLC that was already fail/fulfilled");
+                                       InboundHTLCState::LocalRemoved(ref reason) => {
+                                               if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
+                                               } else {
+                                                       debug_assert!(false, "Tried to fail an HTLC that was already failed");
+                                               }
                                                return Ok(None);
                                        },
                                        _ => {
@@ -1378,7 +1428,11 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
                if pending_idx == core::usize::MAX {
-                       return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID".to_owned()));
+                       #[cfg(any(test, feature = "fuzztarget"))]
+                       // If we failed to find an HTLC to fail, make sure it was previously fulfilled and this
+                       // is simply a duplicate fail, not previously failed and we failed-back too early.
+                       debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
+                       return Ok(None);
                }
 
                // Now update local state:
@@ -1387,8 +1441,9 @@ impl<Signer: Sign> Channel<Signer> {
                                match pending_update {
                                        &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => {
                                                if htlc_id_arg == htlc_id {
-                                                       debug_assert!(false, "Tried to fail an HTLC that was already fulfilled");
-                                                       return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID".to_owned()));
+                                                       #[cfg(any(test, feature = "fuzztarget"))]
+                                                       debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
+                                                       return Ok(None);
                                                }
                                        },
                                        &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, .. } => {
@@ -1494,11 +1549,11 @@ impl<Signer: Sign> Channel<Signer> {
                                        // Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
                                        if script.len() == 0 {
                                                None
-                                       // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
-                                       } else if is_unsupported_shutdown_script(&their_features, script) {
-                                               return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
                                        } else {
-                                               Some(script.clone())
+                                               match ShutdownScript::try_from((script.clone(), &their_features)) {
+                                                       Ok(shutdown_script) => Some(shutdown_script.into_inner()),
+                                                       Err(_) => return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex()))),
+                                               }
                                        }
                                },
                                // Peer is signaling upfront shutdown but don't opt-out with correct mechanism (a.k.a 0-length script). Peer looks buggy, we fail the channel
@@ -1620,8 +1675,9 @@ impl<Signer: Sign> Channel<Signer> {
                let funding_redeemscript = self.get_funding_redeemscript();
                let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
                let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
+               let shutdown_script = self.shutdown_scriptpubkey.clone().map(|script| script.into_inner());
                let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_signer.clone(),
-                                                         &self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
+                                                         shutdown_script, self.get_holder_selected_contest_delay(),
                                                          &self.destination_script, (funding_txo, funding_txo_script.clone()),
                                                          &self.channel_transaction_parameters,
                                                          funding_redeemscript.clone(), self.channel_value_satoshis,
@@ -1693,8 +1749,9 @@ impl<Signer: Sign> Channel<Signer> {
                let funding_txo = self.get_funding_txo().unwrap();
                let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
                let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
+               let shutdown_script = self.shutdown_scriptpubkey.clone().map(|script| script.into_inner());
                let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_signer.clone(),
-                                                         &self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
+                                                         shutdown_script, self.get_holder_selected_contest_delay(),
                                                          &self.destination_script, (funding_txo, funding_txo_script),
                                                          &self.channel_transaction_parameters,
                                                          funding_redeemscript.clone(), self.channel_value_satoshis,
@@ -2435,24 +2492,28 @@ impl<Signer: Sign> Channel<Signer> {
                                                }
                                        },
                                        &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => {
-                                               match self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) {
-                                                       Ok((update_fulfill_msg_option, additional_monitor_update_opt)) => {
-                                                               update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap());
-                                                               if let Some(mut additional_monitor_update) = additional_monitor_update_opt {
-                                                                       monitor_update.updates.append(&mut additional_monitor_update.updates);
-                                                               }
-                                                       },
-                                                       Err(e) => {
-                                                               if let ChannelError::Ignore(_) = e {}
-                                                               else {
-                                                                       panic!("Got a non-IgnoreError action trying to fulfill holding cell HTLC");
-                                                               }
-                                                       }
-                                               }
+                                               // If an HTLC claim was previously added to the holding cell (via
+                                               // `get_update_fulfill_htlc`, then generating the claim message itself must
+                                               // not fail - any in between attempts to claim the HTLC will have resulted
+                                               // in it hitting the holding cell again and we cannot change the state of a
+                                               // holding cell HTLC from fulfill to anything else.
+                                               let (update_fulfill_msg_option, mut additional_monitor_update) =
+                                                       if let UpdateFulfillFetch::NewClaim { msg, monitor_update } = self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) {
+                                                               (msg, monitor_update)
+                                                       } else { unreachable!() };
+                                               update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap());
+                                               monitor_update.updates.append(&mut additional_monitor_update.updates);
                                        },
                                        &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, ref err_packet } => {
                                                match self.get_update_fail_htlc(htlc_id, err_packet.clone(), logger) {
-                                                       Ok(update_fail_msg_option) => update_fail_htlcs.push(update_fail_msg_option.unwrap()),
+                                                       Ok(update_fail_msg_option) => {
+                                                               // If an HTLC failure was previously added to the holding cell (via
+                                                               // `get_update_fail_htlc`) then generating the fail message itself
+                                                               // must not fail - we should never end up in a state where we
+                                                               // double-fail an HTLC or fail-then-claim an HTLC as it indicates
+                                                               // we didn't wait for a full revocation before failing.
+                                                               update_fail_htlcs.push(update_fail_msg_option.unwrap())
+                                                       },
                                                        Err(e) => {
                                                                if let ChannelError::Ignore(_) = e {}
                                                                else {
@@ -3169,16 +3230,17 @@ impl<Signer: Sign> Channel<Signer> {
                }
                assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
 
-               if is_unsupported_shutdown_script(&their_features, &msg.scriptpubkey) {
-                       return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex())));
-               }
+               let shutdown_scriptpubkey = match ShutdownScript::try_from((msg.scriptpubkey.clone(), their_features)) {
+                       Ok(script) => script.into_inner(),
+                       Err(_) => return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex()))),
+               };
 
                if self.counterparty_shutdown_scriptpubkey.is_some() {
-                       if Some(&msg.scriptpubkey) != self.counterparty_shutdown_scriptpubkey.as_ref() {
-                               return Err(ChannelError::Close(format!("Got shutdown request with a scriptpubkey ({}) which did not match their previous scriptpubkey.", msg.scriptpubkey.to_bytes().to_hex())));
+                       if Some(&shutdown_scriptpubkey) != self.counterparty_shutdown_scriptpubkey.as_ref() {
+                               return Err(ChannelError::Close(format!("Got shutdown request with a scriptpubkey ({}) which did not match their previous scriptpubkey.", shutdown_scriptpubkey.to_bytes().to_hex())));
                        }
                } else {
-                       self.counterparty_shutdown_scriptpubkey = Some(msg.scriptpubkey.clone());
+                       self.counterparty_shutdown_scriptpubkey = Some(shutdown_scriptpubkey);
                }
 
                // From here on out, we may not fail!
@@ -4425,24 +4487,6 @@ impl<Signer: Sign> Channel<Signer> {
        }
 }
 
-fn is_unsupported_shutdown_script(their_features: &InitFeatures, script: &Script) -> bool {
-       // We restrain shutdown scripts to standards forms to avoid transactions not propagating on the p2p tx-relay network
-
-       // BOLT 2 says we must only send a scriptpubkey of certain standard forms,
-       // which for a a BIP-141-compliant witness program is at max 42 bytes in length.
-       // So don't let the remote peer feed us some super fee-heavy script.
-       let is_script_too_long = script.len() > 42;
-       if is_script_too_long {
-               return true;
-       }
-
-       if their_features.supports_shutdown_anysegwit() && script.is_witness_program() && script.as_bytes()[0] != OP_PUSHBYTES_0.into_u8() {
-               return false;
-       }
-
-       return !script.is_p2pkh() && !script.is_p2sh() && !script.is_v0_p2wpkh() && !script.is_v0_p2wsh()
-}
-
 const SERIALIZATION_VERSION: u8 = 2;
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
@@ -4506,7 +4550,12 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
                (key_data.0.len() as u32).write(writer)?;
                writer.write_all(&key_data.0[..])?;
 
-               self.shutdown_pubkey.write(writer)?;
+               // Write out the old serialization for shutdown_pubkey for backwards compatibility, if
+               // deserialized from that format.
+               match self.shutdown_scriptpubkey.as_ref().and_then(|script| script.as_legacy_pubkey()) {
+                       Some(shutdown_pubkey) => shutdown_pubkey.write(writer)?,
+                       None => [0u8; PUBLIC_KEY_SIZE].write(writer)?,
+               }
                self.destination_script.write(writer)?;
 
                self.cur_holder_commitment_transaction_number.write(writer)?;
@@ -4684,6 +4733,13 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
 
                self.channel_update_status.write(writer)?;
 
+               #[cfg(any(test, feature = "fuzztarget"))]
+               (self.historical_inbound_htlc_fulfills.len() as u64).write(writer)?;
+               #[cfg(any(test, feature = "fuzztarget"))]
+               for htlc in self.historical_inbound_htlc_fulfills.iter() {
+                       htlc.write(writer)?;
+               }
+
                write_tlv_fields!(writer, {
                        (0, self.announcement_sigs, option),
                        // minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a
@@ -4695,6 +4751,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
                        (1, self.minimum_depth, option),
                        (3, self.counterparty_selected_channel_reserve_satoshis, option),
                        (5, self.config, required),
+                       (7, self.shutdown_scriptpubkey, option),
                });
 
                Ok(())
@@ -4738,7 +4795,12 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
                }
                let holder_signer = keys_source.read_chan_signer(&keys_data)?;
 
-               let shutdown_pubkey = Readable::read(reader)?;
+               // Read the old serialization for shutdown_pubkey, preferring it for shutdown_scriptpubkey
+               // over the TLV if valid.
+               let mut shutdown_scriptpubkey = match <PublicKey as Readable>::read(reader) {
+                       Ok(pubkey) => Some(ShutdownScript::new_p2wpkh_from_pubkey(pubkey)),
+                       Err(_) => None,
+               };
                let destination_script = Readable::read(reader)?;
 
                let cur_holder_commitment_transaction_number = Readable::read(reader)?;
@@ -4893,12 +4955,23 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
 
                let channel_update_status = Readable::read(reader)?;
 
+               #[cfg(any(test, feature = "fuzztarget"))]
+               let mut historical_inbound_htlc_fulfills = HashSet::new();
+               #[cfg(any(test, feature = "fuzztarget"))]
+               {
+                       let htlc_fulfills_len: u64 = Readable::read(reader)?;
+                       for _ in 0..htlc_fulfills_len {
+                               assert!(historical_inbound_htlc_fulfills.insert(Readable::read(reader)?));
+                       }
+               }
+
                let mut announcement_sigs = None;
                read_tlv_fields!(reader, {
                        (0, announcement_sigs, option),
                        (1, minimum_depth, option),
                        (3, counterparty_selected_channel_reserve_satoshis, option),
                        (5, config, option), // Note that if none is provided we will *not* overwrite the existing one.
+                       (7, shutdown_scriptpubkey, option),
                });
 
                let mut secp_ctx = Secp256k1::new();
@@ -4916,7 +4989,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
                        latest_monitor_update_id,
 
                        holder_signer,
-                       shutdown_pubkey,
+                       shutdown_scriptpubkey,
                        destination_script,
 
                        cur_holder_commitment_transaction_number,
@@ -4985,6 +5058,9 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
+
+                       #[cfg(any(test, feature = "fuzztarget"))]
+                       historical_inbound_htlc_fulfills,
                })
        }
 }
@@ -5006,6 +5082,7 @@ mod tests {
        use ln::channel::MAX_FUNDING_SATOSHIS;
        use ln::features::InitFeatures;
        use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate};
+       use ln::script::ShutdownScript;
        use ln::chan_utils;
        use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT};
        use chain::BestBlock;
@@ -5055,10 +5132,10 @@ mod tests {
                        Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&channel_monitor_claim_key_hash[..]).into_script()
                }
 
-               fn get_shutdown_pubkey(&self) -> PublicKey {
+               fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
                        let secp_ctx = Secp256k1::signing_only();
                        let channel_close_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap();
-                       PublicKey::from_secret_key(&secp_ctx, &channel_close_key)
+                       ShutdownScript::new_p2wpkh_from_pubkey(PublicKey::from_secret_key(&secp_ctx, &channel_close_key))
                }
 
                fn get_channel_signer(&self, _inbound: bool, _channel_value_satoshis: u64) -> InMemorySigner {