Merge branch '2022-02-fix-multi-hop-hint-panic' into 2022-02-0.0.105-sec
[rust-lightning] / lightning / src / chain / channelmonitor.rs
index 2ae4bd3de1d042f638e353ca1c680476efbe1b27..91544f11334e4eb5bcf4683da632262cfd7dce82 100644 (file)
@@ -59,7 +59,7 @@ 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 {
@@ -115,14 +115,6 @@ impl Readable for ChannelMonitorUpdate {
        }
 }
 
-/// 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 {
@@ -449,7 +441,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
 
 );
 
-#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
+#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq))]
 #[derive(Clone)]
 pub(crate) enum ChannelMonitorUpdateStep {
        LatestHolderCommitmentTXInfo {
@@ -481,6 +473,19 @@ pub(crate) enum ChannelMonitorUpdateStep {
        },
 }
 
+impl ChannelMonitorUpdateStep {
+       fn variant_name(&self) -> &'static str {
+               match self {
+                       ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo",
+                       ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo",
+                       ChannelMonitorUpdateStep::PaymentPreimage { .. } => "PaymentPreimage",
+                       ChannelMonitorUpdateStep::CommitmentSecret { .. } => "CommitmentSecret",
+                       ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
+                       ChannelMonitorUpdateStep::ShutdownScript { .. } => "ShutdownScript",
+               }
+       }
+}
+
 impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
        (0, LatestHolderCommitmentTXInfo) => {
                (0, commitment_tx, required),
@@ -719,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();
@@ -730,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 ||
@@ -1052,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)
        }
 
@@ -1074,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)]
@@ -1120,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,
@@ -1695,9 +1698,9 @@ 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
@@ -1789,7 +1792,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();
@@ -1812,7 +1815,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                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(())
        }
@@ -1876,21 +1879,26 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                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!");
                }
@@ -1902,8 +1910,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        if self.lockdown_from_offchain { panic!(); }
                                        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.0);
-                                               ret = Err(e);
+                                               log_error!(logger, "    {}", e);
+                                               ret = Err(());
                                        }
                                }
                                ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_revocation_point } => {
@@ -1918,8 +1926,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        log_trace!(logger, "Updating ChannelMonitor with commitment 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.0);
-                                               ret = Err(e);
+                                               log_error!(logger, "    {}", e);
+                                               ret = Err(());
                                        }
                                },
                                ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => {
@@ -1947,9 +1955,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                self.latest_update_id = updates.update_id;
 
                if ret.is_ok() && self.funding_spend_seen {
-                       ret = Err(MonitorUpdateError("Counterparty attempted to update commitment after funding was spent"));
-               }
-               ret
+                       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 {
@@ -2051,7 +2059,7 @@ 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 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());
+                                               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);
                                        }
@@ -3317,7 +3325,7 @@ mod tests {
        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::package::{weight_offered_htlc, weight_received_htlc, weight_revoked_offered_htlc, weight_revoked_received_htlc, WEIGHT_REVOKED_OUTPUT};
        use chain::transaction::OutPoint;
        use chain::keysinterface::InMemorySigner;
        use ln::{PaymentPreimage, PaymentHash};
@@ -3489,6 +3497,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]
@@ -3574,12 +3583,11 @@ 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, $weight: expr, $sum_actual_sigs: expr, $opt_anchors: expr) => {
                                let htlc = HTLCOutputInCommitment {
-                                       offered: if *$weight == WEIGHT_REVOKED_OFFERED_HTLC || *$weight == WEIGHT_OFFERED_HTLC { 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]),
@@ -3590,12 +3598,12 @@ mod tests {
                                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();
+                               $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 *$weight == WEIGHT_REVOKED_OFFERED_HTLC || *$weight == WEIGHT_REVOKED_RECEIVED_HTLC {
+                               } 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 *$weight == WEIGHT_RECEIVED_HTLC {
+                               } 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());
@@ -3611,83 +3619,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_weight = vec![WEIGHT_REVOKED_OUTPUT, WEIGHT_REVOKED_OFFERED_HTLC, WEIGHT_REVOKED_OFFERED_HTLC, WEIGHT_REVOKED_RECEIVED_HTLC];
-               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, false);
-                               inputs_total_weight += inp;
+                       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 + inputs_total_weight as usize,  claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_weight.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_weight = vec![WEIGHT_OFFERED_HTLC, WEIGHT_RECEIVED_HTLC, WEIGHT_RECEIVED_HTLC, WEIGHT_RECEIVED_HTLC];
-               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, false);
-                               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
-               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_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, false);
-                               inputs_total_weight += inp;
+                       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 + inputs_total_weight as usize, claim_tx.get_weight() + /* max_length_isg */ (73 * inputs_weight.len() - sum_actual_sigs));
        }
 
        // Further testing is done in the ChannelManager integration tests.