From: Matt Corallo Date: Fri, 30 Nov 2018 21:06:28 +0000 (-0500) Subject: Return refs from build_commitment_transaction, removing clone()s X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=refs%2Fheads%2F2018-11-198-refs;p=rust-lightning Return refs from build_commitment_transaction, removing clone()s --- diff --git a/src/ln/channel.rs b/src/ln/channel.rs index c229622c0..44755c8e1 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -757,7 +757,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<(HTLCOutputInCommitment, Option)>) { + fn build_commitment_transaction(&self, commitment_number: u64, keys: &TxCreationKeys, local: bool, generated_by_local: bool, feerate_per_kw: u64) -> (Transaction, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>) { let obscured_commitment_transaction_number = self.get_commitment_transaction_number_obscure_factor() ^ (INITIAL_COMMITMENT_NUMBER - commitment_number); let txins = { @@ -771,7 +771,7 @@ 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 txouts: Vec<(TxOut, Option<(HTLCOutputInCommitment, Option<&HTLCSource>)>)> = Vec::with_capacity(self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len() + 2); let dust_limit_satoshis = if local { self.our_dust_limit_satoshis } else { self.their_dust_limit_satoshis }; let mut remote_htlc_total_msat = 0; @@ -836,7 +836,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 { @@ -907,7 +907,7 @@ impl Channel { transaction_utils::sort_outputs(&mut txouts); let mut outputs: Vec = Vec::with_capacity(txouts.len()); - let mut htlcs_used: Vec<(HTLCOutputInCommitment, Option)> = Vec::with_capacity(txouts.len()); + let mut htlcs_used: Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)> = Vec::with_capacity(txouts.len()); for (idx, out) in txouts.drain(..).enumerate() { outputs.push(out.0); if let Some(mut out_htlc) = out.1 { @@ -1688,7 +1688,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.1.drain(..).map(|htlc_pair| (htlc_pair.0, htlc_pair.1.map(|source| (*source).clone()))).collect(); + (commitment_tx.0, 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"); @@ -1712,19 +1716,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, ref htlc_source)) 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, htlc_source)) 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, (*htlc_source).clone())); + htlcs_and_sigs.push((htlc, msg.htlc_signatures[idx], htlc_sig, htlc_source)); } let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1)); @@ -3252,7 +3256,7 @@ impl Channel { } let remote_keys = self.build_remote_transaction_keys()?; - let remote_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, true, feerate_per_kw); + let mut remote_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, true, feerate_per_kw); let remote_commitment_txid = remote_commitment_tx.0.txid(); let remote_sighash = Message::from_slice(&bip143::SighashComponents::new(&remote_commitment_tx.0).sighash_all(&remote_commitment_tx.0.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap(); let our_sig = self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key); @@ -3267,11 +3271,12 @@ impl Channel { htlc_sigs.push(self.secp_ctx.sign(&htlc_sighash, &our_htlc_key)); } + let htlcs_no_ref = remote_commitment_tx.1.drain(..).map(|htlc_pair| (htlc_pair.0, htlc_pair.1.map(|source| source.clone()))).collect(); Ok((msgs::CommitmentSigned { channel_id: self.channel_id, signature: our_sig, htlc_signatures: htlc_sigs, - }, remote_commitment_tx)) + }, (remote_commitment_tx.0, htlcs_no_ref))) } /// Adds a pending outbound HTLC to this channel, and creates a signed commitment transaction @@ -3980,11 +3985,15 @@ mod tests { let htlc_basepoint = PublicKey::from_secret_key(&secp_ctx, &chan.local_keys.htlc_base_key); let keys = TxCreationKeys::new(&secp_ctx, &per_commitment_point, &delayed_payment_base, &htlc_basepoint, &chan.their_revocation_basepoint.unwrap(), &chan.their_payment_basepoint.unwrap(), &chan.their_htlc_basepoint.unwrap()).unwrap(); - let mut unsigned_tx: (Transaction, Vec<(HTLCOutputInCommitment, Option)>); + let mut unsigned_tx: (Transaction, Vec); macro_rules! test_commitment { ( $their_sig_hex: expr, $our_sig_hex: expr, $tx_hex: expr) => { - unsigned_tx = chan.build_commitment_transaction(0xffffffffffff - 42, &keys, true, false, chan.feerate_per_kw); + unsigned_tx = { + let mut tx = chan.build_commitment_transaction(0xffffffffffff - 42, &keys, true, false, chan.feerate_per_kw); + let htlcs = tx.1.drain(..).map(|htlc_pair| htlc_pair.0).collect(); + (tx.0, htlcs) + }; let their_signature = Signature::from_der(&secp_ctx, &hex::decode($their_sig_hex).unwrap()[..]).unwrap(); let sighash = Message::from_slice(&bip143::SighashComponents::new(&unsigned_tx.0).sighash_all(&unsigned_tx.0.input[0], &chan.get_funding_redeemscript(), chan.channel_value_satoshis)[..]).unwrap(); secp_ctx.verify(&sighash, &their_signature, &chan.their_funding_pubkey.unwrap()).unwrap(); @@ -4000,7 +4009,7 @@ mod tests { ( $htlc_idx: expr, $their_sig_hex: expr, $our_sig_hex: expr, $tx_hex: expr ) => { let remote_signature = Signature::from_der(&secp_ctx, &hex::decode($their_sig_hex).unwrap()[..]).unwrap(); - let (ref htlc, _) = unsigned_tx.1[$htlc_idx]; + let ref htlc = unsigned_tx.1[$htlc_idx]; let mut htlc_tx = chan.build_htlc_transaction(&unsigned_tx.0.txid(), &htlc, true, &keys, chan.feerate_per_kw); let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &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();