@@ -2143,21 +2143,10 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
2143
2143
funding_inputs.push(prev_funding_input);
2144
2144
}
2145
2145
2146
- let mut funding_inputs_prev_outputs: Vec<&TxOut> = Vec::with_capacity(funding_inputs.len());
2147
- // Check that vouts exist for each TxIn in provided transactions.
2148
- for (idx, (txin, tx)) in funding_inputs.iter().enumerate() {
2149
- if let Some(output) = tx.as_transaction().output.get(txin.previous_output.vout as usize) {
2150
- funding_inputs_prev_outputs.push(output);
2151
- } else {
2152
- return Err(APIError::APIMisuseError {
2153
- err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
2154
- tx.as_transaction().compute_txid(), txin.previous_output.vout, idx) });
2155
- }
2156
- }
2146
+ let funding_inputs_prev_outputs = DualFundingChannelContext::txouts_from_input_prev_txs(&funding_inputs)
2147
+ .map_err(|err| APIError::APIMisuseError { err: err.to_string() })?;
2157
2148
2158
- let total_input_satoshis: u64 = funding_inputs.iter().map(
2159
- |(txin, tx)| tx.as_transaction().output.get(txin.previous_output.vout as usize).map(|out| out.value.to_sat()).unwrap_or(0)
2160
- ).sum();
2149
+ let total_input_satoshis: u64 = funding_inputs_prev_outputs.iter().map(|txout| txout.value.to_sat()).sum();
2161
2150
if total_input_satoshis < self.dual_funding_context.our_funding_satoshis {
2162
2151
return Err(APIError::APIMisuseError {
2163
2152
err: format!("Total value of funding inputs must be at least funding amount. It was {} sats",
@@ -4771,6 +4760,33 @@ pub(super) struct DualFundingChannelContext {
4771
4760
pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
4772
4761
}
4773
4762
4763
+ impl DualFundingChannelContext {
4764
+ /// Obtain prev outputs for each supplied input and matching transaction.
4765
+ /// Can error when there a prev tx does not have an output for the specified vout number.
4766
+ /// Also checks for matching of transaction IDs.
4767
+ fn txouts_from_input_prev_txs(inputs: &Vec<(TxIn, TransactionU16LenLimited)>) -> Result<Vec<&TxOut>, ChannelError> {
4768
+ let mut prev_outputs: Vec<&TxOut> = Vec::with_capacity(inputs.len());
4769
+ // Check that vouts exist for each TxIn in provided transactions.
4770
+ for (idx, (txin, tx)) in inputs.iter().enumerate() {
4771
+ let txid = tx.as_transaction().compute_txid();
4772
+ if txin.previous_output.txid != txid {
4773
+ return Err(ChannelError::Warn(
4774
+ format!("Transaction input txid mismatch, {} vs. {}, at index {}", txin.previous_output.txid, txid, idx)
4775
+ ));
4776
+ }
4777
+ if let Some(output) = tx.as_transaction().output.get(txin.previous_output.vout as usize) {
4778
+ prev_outputs.push(output);
4779
+ } else {
4780
+ return Err(ChannelError::Warn(
4781
+ format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn, at index {}",
4782
+ txid, txin.previous_output.vout, idx)
4783
+ ));
4784
+ }
4785
+ }
4786
+ Ok(prev_outputs)
4787
+ }
4788
+ }
4789
+
4774
4790
// Holder designates channel data owned for the benefit of the user client.
4775
4791
// Counterparty designates channel data owned by the another channel participant entity.
4776
4792
pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
@@ -9688,17 +9704,18 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
9688
9704
unfunded_channel_age_ticks: 0,
9689
9705
holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
9690
9706
};
9707
+ let dual_funding_context = DualFundingChannelContext {
9708
+ our_funding_satoshis: funding_satoshis,
9709
+ their_funding_satoshis: None,
9710
+ funding_tx_locktime,
9711
+ funding_feerate_sat_per_1000_weight,
9712
+ our_funding_inputs: funding_inputs,
9713
+ };
9691
9714
let chan = Self {
9692
9715
funding,
9693
9716
context,
9694
9717
unfunded_context,
9695
- dual_funding_context: DualFundingChannelContext {
9696
- our_funding_satoshis: funding_satoshis,
9697
- their_funding_satoshis: None,
9698
- funding_tx_locktime,
9699
- funding_feerate_sat_per_1000_weight,
9700
- our_funding_inputs: funding_inputs,
9701
- },
9718
+ dual_funding_context,
9702
9719
interactive_tx_constructor: None,
9703
9720
};
9704
9721
Ok(chan)
0 commit comments