@@ -2244,26 +2244,27 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
2244
2244
) -> Result<Option<InteractiveTxMessageSend>, APIError>
2245
2245
where ES::Target: EntropySource
2246
2246
{
2247
- let mut funding_inputs = self.dual_funding_context.our_funding_inputs.take().unwrap_or_else(|| vec![]);
2247
+ let mut funding_inputs = Vec::new();
2248
+ mem::swap(&mut self.dual_funding_context.our_funding_inputs, &mut funding_inputs);
2248
2249
2249
2250
if let Some(prev_funding_input) = prev_funding_input {
2250
2251
funding_inputs.push(prev_funding_input);
2251
2252
}
2252
2253
2253
- let mut funding_inputs_prev_outputs: Vec<TxOut> = Vec::with_capacity(funding_inputs.len());
2254
+ let mut funding_inputs_prev_outputs: Vec<& TxOut> = Vec::with_capacity(funding_inputs.len());
2254
2255
// Check that vouts exist for each TxIn in provided transactions.
2255
- for (idx, input ) in funding_inputs.iter().enumerate() {
2256
- if let Some(output) = input.1. as_transaction().output.get(input.0 .previous_output.vout as usize) {
2257
- funding_inputs_prev_outputs.push(output.clone() );
2256
+ for (idx, (txin, tx) ) in funding_inputs.iter().enumerate() {
2257
+ if let Some(output) = tx. as_transaction().output.get(txin .previous_output.vout as usize) {
2258
+ funding_inputs_prev_outputs.push(output);
2258
2259
} else {
2259
2260
return Err(APIError::APIMisuseError {
2260
2261
err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
2261
- input.1. as_transaction().compute_txid(), input.0 .previous_output.vout, idx) });
2262
+ tx. as_transaction().compute_txid(), txin .previous_output.vout, idx) });
2262
2263
}
2263
2264
}
2264
2265
2265
2266
let total_input_satoshis: u64 = funding_inputs.iter().map(
2266
- |input| input.1. as_transaction().output.get(input.0 .previous_output.vout as usize).map(|out| out.value.to_sat()).unwrap_or(0)
2267
+ |(txin, tx)| tx. as_transaction().output.get(txin .previous_output.vout as usize).map(|out| out.value.to_sat()).unwrap_or(0)
2267
2268
).sum();
2268
2269
if total_input_satoshis < self.dual_funding_context.our_funding_satoshis {
2269
2270
return Err(APIError::APIMisuseError {
@@ -2305,8 +2306,14 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
2305
2306
|err| APIError::APIMisuseError {
2306
2307
err: format!("Failed to get change script as new destination script, {:?}", err),
2307
2308
})?;
2308
- add_funding_change_output(change_value, change_script,
2309
- &mut funding_outputs, self.dual_funding_context.funding_feerate_sat_per_1000_weight);
2309
+ let mut change_output = TxOut {
2310
+ value: Amount::from_sat(change_value),
2311
+ script_pubkey: change_script,
2312
+ };
2313
+ let change_output_weight = get_output_weight(&change_output.script_pubkey).to_wu();
2314
+ let change_output_fee = fee_for_weight(self.dual_funding_context.funding_feerate_sat_per_1000_weight, change_output_weight);
2315
+ change_output.value = Amount::from_sat(change_value.saturating_sub(change_output_fee));
2316
+ funding_outputs.push(OutputOwned::Single(change_output));
2310
2317
}
2311
2318
2312
2319
let constructor_args = InteractiveTxConstructorArgs {
@@ -2325,7 +2332,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
2325
2332
.map_err(|_| APIError::APIMisuseError { err: "Incorrect shared output provided".into() })?;
2326
2333
let msg = tx_constructor.take_initiator_first_message();
2327
2334
2328
- self.interactive_tx_constructor.replace (tx_constructor);
2335
+ self.interactive_tx_constructor = Some (tx_constructor);
2329
2336
2330
2337
Ok(msg)
2331
2338
}
@@ -4999,8 +5006,10 @@ pub(super) struct DualFundingChannelContext {
4999
5006
/// Note that the `our_funding_satoshis` field is equal to the total value of `our_funding_inputs`
5000
5007
/// minus any fees paid for our contributed weight. This means that change will never be generated
5001
5008
/// and the maximum value possible will go towards funding the channel.
5009
+ ///
5010
+ /// Note that this field may be emptied once the interactive negotiation has been started.
5002
5011
#[allow(dead_code)] // TODO(dual_funding): Remove once contribution to V2 channels is enabled.
5003
- pub our_funding_inputs: Option< Vec<(TxIn, TransactionU16LenLimited)> >,
5012
+ pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
5004
5013
}
5005
5014
5006
5015
// Holder designates channel data owned for the benefit of the user client.
@@ -9996,7 +10005,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
9996
10005
their_funding_satoshis: None,
9997
10006
funding_tx_locktime,
9998
10007
funding_feerate_sat_per_1000_weight,
9999
- our_funding_inputs: Some( funding_inputs) ,
10008
+ our_funding_inputs: funding_inputs,
10000
10009
},
10001
10010
interactive_tx_constructor: None,
10002
10011
interactive_tx_signing_session: None,
@@ -10142,7 +10151,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
10142
10151
their_funding_satoshis: Some(msg.common_fields.funding_satoshis),
10143
10152
funding_tx_locktime: LockTime::from_consensus(msg.locktime),
10144
10153
funding_feerate_sat_per_1000_weight: msg.funding_feerate_sat_per_1000_weight,
10145
- our_funding_inputs: Some( our_funding_inputs.clone() ),
10154
+ our_funding_inputs: our_funding_inputs.clone(),
10146
10155
};
10147
10156
10148
10157
let interactive_tx_constructor = Some(InteractiveTxConstructor::new(
0 commit comments