@@ -2246,26 +2246,27 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
22462246 ) -> Result<Option<InteractiveTxMessageSend>, APIError>
22472247 where ES::Target: EntropySource
22482248 {
2249- let mut funding_inputs = self.dual_funding_context.our_funding_inputs.take().unwrap_or_else(|| vec![]);
2249+ let mut funding_inputs = Vec::new();
2250+ mem::swap(&mut self.dual_funding_context.our_funding_inputs, &mut funding_inputs);
22502251
22512252 if let Some(prev_funding_input) = prev_funding_input {
22522253 funding_inputs.push(prev_funding_input);
22532254 }
22542255
2255- let mut funding_inputs_prev_outputs: Vec<TxOut> = Vec::with_capacity(funding_inputs.len());
2256+ let mut funding_inputs_prev_outputs: Vec<& TxOut> = Vec::with_capacity(funding_inputs.len());
22562257 // Check that vouts exist for each TxIn in provided transactions.
2257- for (idx, input ) in funding_inputs.iter().enumerate() {
2258- if let Some(output) = input.1. as_transaction().output.get(input.0 .previous_output.vout as usize) {
2259- funding_inputs_prev_outputs.push(output.clone() );
2258+ for (idx, (txin, tx) ) in funding_inputs.iter().enumerate() {
2259+ if let Some(output) = tx. as_transaction().output.get(txin .previous_output.vout as usize) {
2260+ funding_inputs_prev_outputs.push(output);
22602261 } else {
22612262 return Err(APIError::APIMisuseError {
22622263 err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
2263- input.1. as_transaction().compute_txid(), input.0 .previous_output.vout, idx) });
2264+ tx. as_transaction().compute_txid(), txin .previous_output.vout, idx) });
22642265 }
22652266 }
22662267
22672268 let total_input_satoshis: u64 = funding_inputs.iter().map(
2268- |input| input.1. as_transaction().output.get(input.0 .previous_output.vout as usize).map(|out| out.value.to_sat()).unwrap_or(0)
2269+ |(txin, tx)| tx. as_transaction().output.get(txin .previous_output.vout as usize).map(|out| out.value.to_sat()).unwrap_or(0)
22692270 ).sum();
22702271 if total_input_satoshis < self.dual_funding_context.our_funding_satoshis {
22712272 return Err(APIError::APIMisuseError {
@@ -2307,8 +2308,14 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
23072308 |err| APIError::APIMisuseError {
23082309 err: format!("Failed to get change script as new destination script, {:?}", err),
23092310 })?;
2310- add_funding_change_output(change_value, change_script,
2311- &mut funding_outputs, self.dual_funding_context.funding_feerate_sat_per_1000_weight);
2311+ let mut change_output = TxOut {
2312+ value: Amount::from_sat(change_value),
2313+ script_pubkey: change_script,
2314+ };
2315+ let change_output_weight = get_output_weight(&change_output.script_pubkey).to_wu();
2316+ let change_output_fee = fee_for_weight(self.dual_funding_context.funding_feerate_sat_per_1000_weight, change_output_weight);
2317+ change_output.value = Amount::from_sat(change_value.saturating_sub(change_output_fee));
2318+ funding_outputs.push(OutputOwned::Single(change_output));
23122319 }
23132320
23142321 let constructor_args = InteractiveTxConstructorArgs {
@@ -2327,7 +2334,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
23272334 .map_err(|_| APIError::APIMisuseError { err: "Incorrect shared output provided".into() })?;
23282335 let msg = tx_constructor.take_initiator_first_message();
23292336
2330- self.interactive_tx_constructor.replace (tx_constructor);
2337+ self.interactive_tx_constructor = Some (tx_constructor);
23312338
23322339 Ok(msg)
23332340 }
@@ -5041,8 +5048,10 @@ pub(super) struct DualFundingChannelContext {
50415048 /// Note that the `our_funding_satoshis` field is equal to the total value of `our_funding_inputs`
50425049 /// minus any fees paid for our contributed weight. This means that change will never be generated
50435050 /// and the maximum value possible will go towards funding the channel.
5051+ ///
5052+ /// Note that this field may be emptied once the interactive negotiation has been started.
50445053 #[allow(dead_code)] // TODO(dual_funding): Remove once contribution to V2 channels is enabled.
5045- pub our_funding_inputs: Option< Vec<(TxIn, TransactionU16LenLimited)> >,
5054+ pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
50465055}
50475056
50485057// Holder designates channel data owned for the benefit of the user client.
@@ -10034,7 +10043,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
1003410043 their_funding_satoshis: None,
1003510044 funding_tx_locktime,
1003610045 funding_feerate_sat_per_1000_weight,
10037- our_funding_inputs: Some( funding_inputs) ,
10046+ our_funding_inputs: funding_inputs,
1003810047 },
1003910048 interactive_tx_constructor: None,
1004010049 interactive_tx_signing_session: None,
@@ -10180,7 +10189,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
1018010189 their_funding_satoshis: Some(msg.common_fields.funding_satoshis),
1018110190 funding_tx_locktime: LockTime::from_consensus(msg.locktime),
1018210191 funding_feerate_sat_per_1000_weight: msg.funding_feerate_sat_per_1000_weight,
10183- our_funding_inputs: Some( our_funding_inputs.clone() ),
10192+ our_funding_inputs: our_funding_inputs.clone(),
1018410193 };
1018510194
1018610195 let interactive_tx_constructor = Some(InteractiveTxConstructor::new(
0 commit comments