From 3b7ef49ef6a3193f0a8a5202f2ac203ace5ebcf9 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 30 Nov 2018 16:06:28 -0500 Subject: [PATCH] Return refs from build_commitment_transaction, removing clone()s --- src/ln/channel.rs | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/ln/channel.rs b/src/ln/channel.rs index de6588e7a..0eef7fbce 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -751,7 +751,7 @@ impl Channel { /// generated by the peer which proposed adding the HTLCs, and thus we need to understand both /// which peer generated this transaction and "to whom" this transaction flows. #[inline] - fn build_commitment_transaction(&self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, feerate_per_kw: u64) -> (Transaction, Vec, Vec<([u8; 32], HTLCSource, Option)>) { + fn build_commitment_transaction(&self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, feerate_per_kw: u64) -> (Transaction, Vec, Vec<([u8; 32], &HTLCSource, Option)>) { let obscured_commitment_transaction_number = self.get_commitment_transaction_number_obscure_factor() ^ (INITIAL_COMMITMENT_NUMBER - commitment_number); let txins = { @@ -765,8 +765,8 @@ impl Channel { ins }; - let mut txouts: Vec<(TxOut, Option<(HTLCOutputInCommitment, Option)>)> = Vec::with_capacity(self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len() + 2); - let mut unincluded_htlc_sources: Vec<([u8; 32], HTLCSource, Option)> = Vec::new(); + let mut txouts: Vec<(TxOut, Option<(HTLCOutputInCommitment, Option<&HTLCSource>)>)> = Vec::with_capacity(self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len() + 2); + let mut unincluded_htlc_sources: Vec<([u8; 32], &HTLCSource, Option)> = Vec::new(); let dust_limit_satoshis = if local { self.our_dust_limit_satoshis } else { self.their_dust_limit_satoshis }; let mut remote_htlc_total_msat = 0; @@ -839,7 +839,7 @@ impl Channel { }; if include { - add_htlc_output!(htlc, true, Some(htlc.source.clone())); + add_htlc_output!(htlc, true, Some(&htlc.source)); local_htlc_total_msat += htlc.amount_msat; } else { match htlc.state { @@ -911,7 +911,7 @@ impl Channel { let mut outputs: Vec = Vec::with_capacity(txouts.len()); let mut htlcs_included: Vec = Vec::with_capacity(txouts.len()); - let mut htlc_sources: Vec<([u8; 32], HTLCSource, Option)> = Vec::with_capacity(txouts.len() + unincluded_htlc_sources.len()); + let mut htlc_sources: Vec<([u8; 32], &HTLCSource, Option)> = Vec::with_capacity(txouts.len() + unincluded_htlc_sources.len()); for (idx, out) in txouts.drain(..).enumerate() { outputs.push(out.0); if let Some((mut htlc, source_option)) = out.1 { @@ -1682,7 +1682,11 @@ impl Channel { self.feerate_per_kw }; - let mut local_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, feerate_per_kw); + let mut local_commitment_tx = { + let mut commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, feerate_per_kw); + let htlcs_cloned: Vec<_> = commitment_tx.2.drain(..).map(|htlc_source| (htlc_source.0, htlc_source.1.clone(), htlc_source.2)).collect(); + (commitment_tx.0, commitment_tx.1, htlcs_cloned) + }; let local_commitment_txid = local_commitment_tx.0.txid(); let local_sighash = Message::from_slice(&bip143::SighashComponents::new(&local_commitment_tx.0).sighash_all(&local_commitment_tx.0.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap(); secp_check!(self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey.unwrap()), "Invalid commitment tx signature from peer"); @@ -1706,19 +1710,19 @@ impl Channel { new_local_commitment_txn.push(local_commitment_tx.0.clone()); let mut htlcs_and_sigs = Vec::with_capacity(local_commitment_tx.1.len()); - for (idx, ref htlc) in local_commitment_tx.1.iter().enumerate() { - let mut htlc_tx = self.build_htlc_transaction(&local_commitment_txid, htlc, true, &local_keys, feerate_per_kw); + for (idx, htlc) in local_commitment_tx.1.drain(..).enumerate() { + let mut htlc_tx = self.build_htlc_transaction(&local_commitment_txid, &htlc, true, &local_keys, feerate_per_kw); let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &local_keys); let htlc_sighash = Message::from_slice(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]).unwrap(); secp_check!(self.secp_ctx.verify(&htlc_sighash, &msg.htlc_signatures[idx], &local_keys.b_htlc_key), "Invalid HTLC tx signature from peer"); let htlc_sig = if htlc.offered { - let htlc_sig = self.sign_htlc_transaction(&mut htlc_tx, &msg.htlc_signatures[idx], &None, htlc, &local_keys)?; + let htlc_sig = self.sign_htlc_transaction(&mut htlc_tx, &msg.htlc_signatures[idx], &None, &htlc, &local_keys)?; new_local_commitment_txn.push(htlc_tx); htlc_sig } else { - self.create_htlc_tx_signature(&htlc_tx, htlc, &local_keys)?.1 + self.create_htlc_tx_signature(&htlc_tx, &htlc, &local_keys)?.1 }; - htlcs_and_sigs.push(((*htlc).clone(), msg.htlc_signatures[idx], htlc_sig)); + htlcs_and_sigs.push((htlc, msg.htlc_signatures[idx], htlc_sig)); } let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1)); @@ -3240,20 +3244,23 @@ impl Channel { } } - match self.send_commitment_no_state_update() { - Ok((res, remote_commitment_tx)) => { + let (res, remote_commitment_tx, htlcs, htlc_sources) = match self.send_commitment_no_state_update() { + Ok((res, (remote_commitment_tx, htlcs, mut htlc_sources))) => { // Update state now that we've passed all the can-fail calls... - self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_commitment_tx.0, remote_commitment_tx.1, remote_commitment_tx.2, self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap()); - self.channel_state |= ChannelState::AwaitingRemoteRevoke as u32; - Ok((res, self.channel_monitor.clone())) + let htlc_sources_no_ref = htlc_sources.drain(..).map(|htlc_source| (htlc_source.0, htlc_source.1.clone(), htlc_source.2)).collect(); + (res, remote_commitment_tx, htlcs, htlc_sources_no_ref) }, - Err(e) => Err(e), - } + Err(e) => return Err(e), + }; + + self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_commitment_tx, htlcs, htlc_sources, self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap()); + self.channel_state |= ChannelState::AwaitingRemoteRevoke as u32; + Ok((res, self.channel_monitor.clone())) } /// Only fails in case of bad keys. Used for channel_reestablish commitment_signed generation /// when we shouldn't change HTLC/channel state. - fn send_commitment_no_state_update(&self) -> Result<(msgs::CommitmentSigned, (Transaction, Vec, Vec<([u8; 32], HTLCSource, Option)>)), ChannelError> { + fn send_commitment_no_state_update(&self) -> Result<(msgs::CommitmentSigned, (Transaction, Vec, Vec<([u8; 32], &HTLCSource, Option)>)), ChannelError> { let funding_script = self.get_funding_redeemscript(); let mut feerate_per_kw = self.feerate_per_kw; -- 2.39.5