Drop uneccessary clone() introduced in 16fba9fd664522ac8d24111547b4
[rust-lightning] / lightning / src / ln / channelmonitor.rs
index 560ace94b4215599313e7169cccc8af4e04e5d6c..950b50f3a386bbaa6c582bc2d550df7902b09960 100644 (file)
@@ -409,7 +409,6 @@ impl<ChanSigner: ChannelKeys> PartialEq for OnchainDetection<ChanSigner> {
 struct LocalSignedTx {
        /// txid of the transaction in tx, just used to make comparison faster
        txid: Sha256dHash,
-       tx: LocalCommitmentTransaction,
        revocation_key: PublicKey,
        a_htlc_key: PublicKey,
        b_htlc_key: PublicKey,
@@ -439,8 +438,6 @@ pub(crate) enum InputMaterial {
                locktime: u32,
        },
        LocalHTLC {
-               witness_script: Script,
-               sigs: (Signature, Signature),
                preimage: Option<PaymentPreimage>,
                amount: u64,
        },
@@ -468,11 +465,8 @@ impl Writeable for InputMaterial  {
                                writer.write_all(&byte_utils::be64_to_array(*amount))?;
                                writer.write_all(&byte_utils::be32_to_array(*locktime))?;
                        },
-                       &InputMaterial::LocalHTLC { ref witness_script, ref sigs, ref preimage, ref amount } => {
+                       &InputMaterial::LocalHTLC { ref preimage, ref amount } => {
                                writer.write_all(&[2; 1])?;
-                               witness_script.write(writer)?;
-                               sigs.0.write(writer)?;
-                               sigs.1.write(writer)?;
                                preimage.write(writer)?;
                                writer.write_all(&byte_utils::be64_to_array(*amount))?;
                        },
@@ -517,16 +511,11 @@ impl Readable for InputMaterial {
                                }
                        },
                        2 => {
-                               let witness_script = Readable::read(reader)?;
-                               let their_sig = Readable::read(reader)?;
-                               let our_sig = Readable::read(reader)?;
                                let preimage = Readable::read(reader)?;
                                let amount = Readable::read(reader)?;
                                InputMaterial::LocalHTLC {
-                                       witness_script,
-                                       sigs: (their_sig, our_sig),
                                        preimage,
-                                       amount
+                                       amount,
                                }
                        },
                        3 => {
@@ -805,6 +794,9 @@ pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
        #[cfg(not(test))]
        onchain_tx_handler: OnchainTxHandler<ChanSigner>,
 
+       // Used to detect programming bug due to unsafe monitor update sequence { ChannelForceClosed, LatestLocalCommitmentTXInfo }
+       lockdown_from_offchain: bool,
+
        // We simply modify last_block_hash 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
@@ -970,7 +962,7 @@ impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
 
                macro_rules! serialize_local_tx {
                        ($local_tx: expr) => {
-                               $local_tx.tx.write(writer)?;
+                               $local_tx.txid.write(writer)?;
                                writer.write_all(&$local_tx.revocation_key.serialize())?;
                                writer.write_all(&$local_tx.a_htlc_key.serialize())?;
                                writer.write_all(&$local_tx.b_htlc_key.serialize())?;
@@ -1064,6 +1056,8 @@ impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
                }
                self.onchain_tx_handler.write(writer)?;
 
+               self.lockdown_from_offchain.write(writer)?;
+
                Ok(())
        }
 
@@ -1104,7 +1098,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
 
                let onchain_detection = OnchainDetection {
                        keys: keys.clone(),
-                       funding_info: Some(funding_info.clone()),
+                       funding_info: Some(funding_info),
                        current_remote_commitment_txid: None,
                        prev_remote_commitment_txid: None,
                };
@@ -1145,7 +1139,9 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                        onchain_events_waiting_threshold_conf: HashMap::new(),
                        outputs_to_watch: HashMap::new(),
 
-                       onchain_tx_handler: OnchainTxHandler::new(destination_script.clone(), keys, funding_redeemscript, logger.clone()),
+                       onchain_tx_handler: OnchainTxHandler::new(destination_script.clone(), keys, funding_redeemscript, their_to_self_delay, logger.clone()),
+
+                       lockdown_from_offchain: false,
 
                        last_block_hash: Default::default(),
                        secp_ctx: Secp256k1::new(),
@@ -1261,30 +1257,39 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
        /// is important that any clones of this channel monitor (including remote clones) by kept
        /// up-to-date as our local commitment transaction is updated.
        /// Panics if set_their_to_self_delay has never been called.
-       pub(super) fn provide_latest_local_commitment_tx_info(&mut self, commitment_tx: LocalCommitmentTransaction, local_keys: chan_utils::TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>) -> Result<(), MonitorUpdateError> {
+       pub(super) fn provide_latest_local_commitment_tx_info(&mut self, mut commitment_tx: LocalCommitmentTransaction, local_keys: chan_utils::TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>) -> Result<(), MonitorUpdateError> {
                if self.their_to_self_delay.is_none() {
                        return Err(MonitorUpdateError("Got a local commitment tx info update before we'd set basic information about the channel"));
                }
+               let txid = commitment_tx.txid();
+               let sequence = commitment_tx.without_valid_witness().input[0].sequence as u64;
+               let locktime = commitment_tx.without_valid_witness().lock_time as u64;
+               let mut htlcs = Vec::with_capacity(htlc_outputs.len());
+               for htlc in htlc_outputs.clone() {
+                       if let Some(_) = htlc.0.transaction_output_index {
+                               htlcs.push((htlc.0, htlc.1, None));
+                       }
+               }
+               commitment_tx.set_htlc_cache(local_keys.clone(), feerate_per_kw, htlcs);
                // Returning a monitor error before updating tracking points means in case of using
                // a concurrent watchtower implementation for same channel, if this one doesn't
                // reject update as we do, you MAY have the latest local valid commitment tx onchain
                // for which you want to spend outputs. We're NOT robust again this scenario right
                // now but we should consider it later.
-               if let Err(_) = self.onchain_tx_handler.provide_latest_local_tx(commitment_tx.clone()) {
+               if let Err(_) = self.onchain_tx_handler.provide_latest_local_tx(commitment_tx) {
                        return Err(MonitorUpdateError("Local commitment signed has already been signed, no further update of LOCAL commitment transaction is allowed"));
                }
-               self.current_local_commitment_number = 0xffff_ffff_ffff - ((((commitment_tx.without_valid_witness().input[0].sequence as u64 & 0xffffff) << 3*8) | (commitment_tx.without_valid_witness().lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor);
+               self.current_local_commitment_number = 0xffff_ffff_ffff - ((((sequence & 0xffffff) << 3*8) | (locktime as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor);
                self.prev_local_signed_commitment_tx = self.current_local_signed_commitment_tx.take();
                self.current_local_signed_commitment_tx = Some(LocalSignedTx {
-                       txid: commitment_tx.txid(),
-                       tx: commitment_tx,
+                       txid,
                        revocation_key: local_keys.revocation_key,
                        a_htlc_key: local_keys.a_htlc_key,
                        b_htlc_key: local_keys.b_htlc_key,
                        delayed_payment_key: local_keys.a_delayed_payment_key,
                        per_commitment_point: local_keys.per_commitment_point,
                        feerate_per_kw,
-                       htlc_outputs,
+                       htlc_outputs: htlc_outputs,
                });
                Ok(())
        }
@@ -1307,8 +1312,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
        pub(super) fn update_monitor_ooo(&mut self, mut updates: ChannelMonitorUpdate) -> Result<(), MonitorUpdateError> {
                for update in updates.updates.drain(..) {
                        match update {
-                               ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } =>
-                                       self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?,
+                               ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => {
+                                       if self.lockdown_from_offchain { panic!(); }
+                                       self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?
+                               },
                                ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
                                        self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point),
                                ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
@@ -1336,8 +1343,10 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                }
                for update in updates.updates.drain(..) {
                        match update {
-                               ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } =>
-                                       self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?,
+                               ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => {
+                                       if self.lockdown_from_offchain { panic!(); }
+                                       self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)?
+                               },
                                ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } =>
                                        self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point),
                                ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } =>
@@ -1347,6 +1356,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                                ChannelMonitorUpdateStep::RescueRemoteCommitmentTXInfo { their_current_per_commitment_point } =>
                                        self.provide_rescue_remote_commitment_tx_info(their_current_per_commitment_point),
                                ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => {
+                                       self.lockdown_from_offchain = true;
                                        if should_broadcast {
                                                self.broadcast_latest_local_commitment_txn(broadcaster);
                                        } else {
@@ -1687,8 +1697,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                (claimable_outpoints, Some((htlc_txid, tx.output.clone())))
        }
 
-       fn broadcast_by_local_state(&self, commitment_tx: &Transaction, local_tx: &LocalSignedTx) -> (Vec<Transaction>, Vec<TxOut>, Option<(Script, SecretKey, Script)>) {
-               let mut res = Vec::with_capacity(local_tx.htlc_outputs.len());
+       fn broadcast_by_local_state(&self, commitment_tx: &Transaction, local_tx: &LocalSignedTx) -> (Vec<ClaimRequest>, Vec<TxOut>, Option<(Script, SecretKey, Script)>) {
+               let mut claim_requests = Vec::with_capacity(local_tx.htlc_outputs.len());
                let mut watch_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
 
                let redeemscript = chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.their_to_self_delay.unwrap(), &local_tx.delayed_payment_key);
@@ -1696,40 +1706,23 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                        Some((redeemscript.to_v0_p2wsh(), local_delayedkey, redeemscript))
                } else { None };
 
-               for &(ref htlc, ref sigs, _) in local_tx.htlc_outputs.iter() {
+               for &(ref htlc, _, _) in local_tx.htlc_outputs.iter() {
                        if let Some(transaction_output_index) = htlc.transaction_output_index {
-                               if let &Some(ref their_sig) = sigs {
-                                       if htlc.offered {
-                                               log_trace!(self, "Broadcasting HTLC-Timeout transaction against local commitment transactions");
-                                               let mut htlc_timeout_tx = chan_utils::build_htlc_transaction(&local_tx.txid, local_tx.feerate_per_kw, self.their_to_self_delay.unwrap(), htlc, &local_tx.delayed_payment_key, &local_tx.revocation_key);
-                                               self.onchain_detection.keys.sign_htlc_transaction(&mut htlc_timeout_tx, their_sig, &None, htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key, &local_tx.per_commitment_point, &self.secp_ctx);
-
-                                               log_trace!(self, "Outpoint {}:{} is being being claimed", htlc_timeout_tx.input[0].previous_output.vout, htlc_timeout_tx.input[0].previous_output.txid);
-                                               res.push(htlc_timeout_tx);
-                                       } else {
-                                               if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
-                                                       log_trace!(self, "Broadcasting HTLC-Success transaction against local commitment transactions");
-                                                       let mut htlc_success_tx = chan_utils::build_htlc_transaction(&local_tx.txid, local_tx.feerate_per_kw, self.their_to_self_delay.unwrap(), htlc, &local_tx.delayed_payment_key, &local_tx.revocation_key);
-                                                       self.onchain_detection.keys.sign_htlc_transaction(&mut htlc_success_tx, their_sig, &Some(*payment_preimage), htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key, &local_tx.per_commitment_point, &self.secp_ctx);
-
-                                                       log_trace!(self, "Outpoint {}:{} is being being claimed", htlc_success_tx.input[0].previous_output.vout, htlc_success_tx.input[0].previous_output.txid);
-                                                       res.push(htlc_success_tx);
-                                               }
-                                       }
-                                       watch_outputs.push(commitment_tx.output[transaction_output_index as usize].clone());
-                               } else { panic!("Should have sigs for non-dust local tx outputs!") }
+                               let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { Some(*preimage) } else { None };
+                               claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: local_tx.txid, vout: transaction_output_index as u32 }, witness_data: InputMaterial::LocalHTLC { preimage, amount: htlc.amount_msat / 1000 }});
+                               watch_outputs.push(commitment_tx.output[transaction_output_index as usize].clone());
                        }
                }
 
-               (res, watch_outputs, broadcasted_local_revokable_script)
+               (claim_requests, watch_outputs, broadcasted_local_revokable_script)
        }
 
        /// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet)
        /// revoked using data in local_claimable_outpoints.
        /// Should not be used if check_spend_revoked_transaction succeeds.
-       fn check_spend_local_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec<Transaction>, (Sha256dHash, Vec<TxOut>)) {
+       fn check_spend_local_transaction(&mut self, tx: &Transaction, height: u32) -> (Vec<ClaimRequest>, (Sha256dHash, Vec<TxOut>)) {
                let commitment_txid = tx.txid();
-               let mut local_txn = Vec::new();
+               let mut claim_requests = Vec::new();
                let mut watch_outputs = Vec::new();
 
                macro_rules! wait_threshold_conf {
@@ -1757,7 +1750,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
 
                macro_rules! append_onchain_update {
                        ($updates: expr) => {
-                               local_txn.append(&mut $updates.0);
+                               claim_requests = $updates.0;
                                watch_outputs.append(&mut $updates.1);
                                self.broadcasted_local_revokable_script = $updates.2;
                        }
@@ -1804,7 +1797,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                        }
                }
 
-               (local_txn, (commitment_txid, watch_outputs))
+               (claim_requests, (commitment_txid, watch_outputs))
        }
 
        /// Used by ChannelManager deserialization to broadcast the latest local state if its copy of
@@ -1819,10 +1812,17 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
        pub fn get_latest_local_commitment_txn(&mut self) -> Vec<Transaction> {
                log_trace!(self, "Getting signed latest local commitment transaction!");
                if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(self.channel_value_satoshis.unwrap()) {
+                       let txid = commitment_tx.txid();
                        let mut res = vec![commitment_tx];
                        if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
-                               let mut htlc_txn = self.broadcast_by_local_state(res.get(0).unwrap(), local_tx).0;
-                               res.append(&mut htlc_txn);
+                               for htlc in local_tx.htlc_outputs.iter() {
+                                       if let Some(htlc_index) = htlc.0.transaction_output_index {
+                                               let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None };
+                                               if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) {
+                                                       res.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_local_transaction if we get a confirmation.
                        }
@@ -1838,10 +1838,17 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
        pub fn unsafe_get_latest_local_commitment_txn(&mut self) -> Vec<Transaction> {
                log_trace!(self, "Getting signed copy of latest local commitment transaction!");
                if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx(self.channel_value_satoshis.unwrap()) {
+                       let txid = commitment_tx.txid();
                        let mut res = vec![commitment_tx];
                        if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
-                               let mut htlc_txn = self.broadcast_by_local_state(res.get(0).unwrap(), local_tx).0;
-                               res.append(&mut htlc_txn);
+                               for htlc in local_tx.htlc_outputs.iter() {
+                                       if let Some(htlc_index) = htlc.0.transaction_output_index {
+                                               let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None };
+                                               if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) {
+                                                       res.push(htlc_tx);
+                                               }
+                                       }
+                               }
                        }
                        return res
                }
@@ -1884,14 +1891,11 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                                                        watch_outputs.push(new_outputs);
                                                }
                                                if new_outpoints.is_empty() {
-                                                       let (local_txn, new_outputs) = self.check_spend_local_transaction(&tx, height);
-                                                       for tx in local_txn.iter() {
-                                                               log_trace!(self, "Broadcast onchain {}", log_tx!(tx));
-                                                               broadcaster.broadcast_transaction(tx);
-                                                       }
+                                                       let (mut new_outpoints, new_outputs) = self.check_spend_local_transaction(&tx, height);
                                                        if !new_outputs.1.is_empty() {
                                                                watch_outputs.push(new_outputs);
                                                        }
+                                                       claimable_outpoints.append(&mut new_outpoints);
                                                }
                                                claimable_outpoints.append(&mut new_outpoints);
                                        }
@@ -1921,14 +1925,11 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
                if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx {
                        if should_broadcast {
                                if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(self.channel_value_satoshis.unwrap()) {
-                                       let (txs, new_outputs, _) = self.broadcast_by_local_state(&commitment_tx, cur_local_tx);
+                                       let (mut new_outpoints, new_outputs, _) = self.broadcast_by_local_state(&commitment_tx, cur_local_tx);
                                        if !new_outputs.is_empty() {
                                                watch_outputs.push((cur_local_tx.txid.clone(), new_outputs));
                                        }
-                                       for tx in txs {
-                                               log_trace!(self, "Broadcast onchain {}", log_tx!(tx));
-                                               broadcaster.broadcast_transaction(&tx);
-                                       }
+                                       claimable_outpoints.append(&mut new_outpoints);
                                }
                        }
                }
@@ -2379,7 +2380,7 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
                macro_rules! read_local_tx {
                        () => {
                                {
-                                       let tx = <LocalCommitmentTransaction as Readable>::read(reader)?;
+                                       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)?;
@@ -2400,8 +2401,7 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
                                        }
 
                                        LocalSignedTx {
-                                               txid: tx.txid(),
-                                               tx,
+                                               txid,
                                                revocation_key, a_htlc_key, b_htlc_key, delayed_payment_key, per_commitment_point, feerate_per_kw,
                                                htlc_outputs: htlcs
                                        }
@@ -2497,6 +2497,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
                }
                let onchain_tx_handler = ReadableArgs::read(reader, logger.clone())?;
 
+               let lockdown_from_offchain = Readable::read(reader)?;
+
                Ok((last_block_hash.clone(), ChannelMonitor {
                        latest_update_id,
                        commitment_transaction_number_obscure_factor,
@@ -2535,6 +2537,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
 
                        onchain_tx_handler,
 
+                       lockdown_from_offchain,
+
                        last_block_hash,
                        secp_ctx: Secp256k1::new(),
                        logger,