@@ -1695,21 +1695,10 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
1695
1695
funding_inputs.push(prev_funding_input);
1696
1696
}
1697
1697
1698
- let mut funding_inputs_prev_outputs: Vec<&TxOut> = Vec::with_capacity(funding_inputs.len());
1699
- // Check that vouts exist for each TxIn in provided transactions.
1700
- for (idx, (txin, tx)) in funding_inputs.iter().enumerate() {
1701
- if let Some(output) = tx.as_transaction().output.get(txin.previous_output.vout as usize) {
1702
- funding_inputs_prev_outputs.push(output);
1703
- } else {
1704
- return Err(APIError::APIMisuseError {
1705
- err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
1706
- tx.as_transaction().compute_txid(), txin.previous_output.vout, idx) });
1707
- }
1708
- }
1698
+ let funding_inputs_prev_outputs = DualFundingChannelContext::txouts_from_input_prev_txs(&funding_inputs)
1699
+ .map_err(|err| APIError::APIMisuseError { err: err.to_string() })?;
1709
1700
1710
- let total_input_satoshis: u64 = funding_inputs.iter().map(
1711
- |(txin, tx)| tx.as_transaction().output.get(txin.previous_output.vout as usize).map(|out| out.value.to_sat()).unwrap_or(0)
1712
- ).sum();
1701
+ let total_input_satoshis: u64 = funding_inputs_prev_outputs.iter().map(|txout| txout.value.to_sat()).sum();
1713
1702
if total_input_satoshis < self.dual_funding_context.our_funding_satoshis {
1714
1703
return Err(APIError::APIMisuseError {
1715
1704
err: format!("Total value of funding inputs must be at least funding amount. It was {} sats",
@@ -4269,6 +4258,33 @@ pub(super) struct DualFundingChannelContext {
4269
4258
pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
4270
4259
}
4271
4260
4261
+ impl DualFundingChannelContext {
4262
+ /// Obtain prev outputs for each supplied input and matching transaction.
4263
+ /// Can error when there a prev tx does not have an output for the specified vout number.
4264
+ /// Also checks for matching of transaction IDs.
4265
+ fn txouts_from_input_prev_txs(inputs: &Vec<(TxIn, TransactionU16LenLimited)>) -> Result<Vec<&TxOut>, ChannelError> {
4266
+ let mut prev_outputs: Vec<&TxOut> = Vec::with_capacity(inputs.len());
4267
+ // Check that vouts exist for each TxIn in provided transactions.
4268
+ for (idx, (txin, tx)) in inputs.iter().enumerate() {
4269
+ let txid = tx.as_transaction().compute_txid();
4270
+ if txin.previous_output.txid != txid {
4271
+ return Err(ChannelError::Warn(
4272
+ format!("Transaction input txid mismatch, {} vs. {}, at index {}", txin.previous_output.txid, txid, idx)
4273
+ ));
4274
+ }
4275
+ if let Some(output) = tx.as_transaction().output.get(txin.previous_output.vout as usize) {
4276
+ prev_outputs.push(output);
4277
+ } else {
4278
+ return Err(ChannelError::Warn(
4279
+ format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn, at index {}",
4280
+ txid, txin.previous_output.vout, idx)
4281
+ ));
4282
+ }
4283
+ }
4284
+ Ok(prev_outputs)
4285
+ }
4286
+ }
4287
+
4272
4288
// Holder designates channel data owned for the benefit of the user client.
4273
4289
// Counterparty designates channel data owned by the another channel participant entity.
4274
4290
pub(super) struct Channel<SP: Deref> where SP::Target: SignerProvider {
@@ -8934,16 +8950,17 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
8934
8950
unfunded_channel_age_ticks: 0,
8935
8951
holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
8936
8952
};
8953
+ let dual_funding_context = DualFundingChannelContext {
8954
+ our_funding_satoshis: funding_satoshis,
8955
+ their_funding_satoshis: None,
8956
+ funding_tx_locktime,
8957
+ funding_feerate_sat_per_1000_weight,
8958
+ our_funding_inputs: funding_inputs,
8959
+ };
8937
8960
let chan = Self {
8938
8961
context,
8939
8962
unfunded_context,
8940
- dual_funding_context: DualFundingChannelContext {
8941
- our_funding_satoshis: funding_satoshis,
8942
- their_funding_satoshis: None,
8943
- funding_tx_locktime,
8944
- funding_feerate_sat_per_1000_weight,
8945
- our_funding_inputs: funding_inputs,
8946
- },
8963
+ dual_funding_context,
8947
8964
interactive_tx_constructor: None,
8948
8965
};
8949
8966
Ok(chan)
0 commit comments