@@ -2046,21 +2046,10 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
20462046 funding_inputs.push(prev_funding_input);
20472047 }
20482048
2049- let mut funding_inputs_prev_outputs: Vec<&TxOut> = Vec::with_capacity(funding_inputs.len());
2050- // Check that vouts exist for each TxIn in provided transactions.
2051- for (idx, (txin, tx)) in funding_inputs.iter().enumerate() {
2052- if let Some(output) = tx.as_transaction().output.get(txin.previous_output.vout as usize) {
2053- funding_inputs_prev_outputs.push(output);
2054- } else {
2055- return Err(APIError::APIMisuseError {
2056- err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
2057- tx.as_transaction().compute_txid(), txin.previous_output.vout, idx) });
2058- }
2059- }
2049+ let funding_inputs_prev_outputs = DualFundingChannelContext::txouts_from_input_prev_txs(&funding_inputs)
2050+ .map_err(|err| APIError::APIMisuseError { err: err.to_string() })?;
20602051
2061- let total_input_satoshis: u64 = funding_inputs.iter().map(
2062- |(txin, tx)| tx.as_transaction().output.get(txin.previous_output.vout as usize).map(|out| out.value.to_sat()).unwrap_or(0)
2063- ).sum();
2052+ let total_input_satoshis: u64 = funding_inputs_prev_outputs.iter().map(|txout| txout.value.to_sat()).sum();
20642053 if total_input_satoshis < self.dual_funding_context.our_funding_satoshis {
20652054 return Err(APIError::APIMisuseError {
20662055 err: format!("Total value of funding inputs must be at least funding amount. It was {} sats",
@@ -4636,6 +4625,33 @@ pub(super) struct DualFundingChannelContext {
46364625 pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
46374626}
46384627
4628+ impl DualFundingChannelContext {
4629+ /// Obtain prev outputs for each supplied input and matching transaction.
4630+ /// Can error when there a prev tx does not have an output for the specified vout number.
4631+ /// Also checks for matching of transaction IDs.
4632+ fn txouts_from_input_prev_txs(inputs: &Vec<(TxIn, TransactionU16LenLimited)>) -> Result<Vec<&TxOut>, ChannelError> {
4633+ let mut prev_outputs: Vec<&TxOut> = Vec::with_capacity(inputs.len());
4634+ // Check that vouts exist for each TxIn in provided transactions.
4635+ for (idx, (txin, tx)) in inputs.iter().enumerate() {
4636+ let txid = tx.as_transaction().compute_txid();
4637+ if txin.previous_output.txid != txid {
4638+ return Err(ChannelError::Warn(
4639+ format!("Transaction input txid mismatch, {} vs. {}, at index {}", txin.previous_output.txid, txid, idx)
4640+ ));
4641+ }
4642+ if let Some(output) = tx.as_transaction().output.get(txin.previous_output.vout as usize) {
4643+ prev_outputs.push(output);
4644+ } else {
4645+ return Err(ChannelError::Warn(
4646+ format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn, at index {}",
4647+ txid, txin.previous_output.vout, idx)
4648+ ));
4649+ }
4650+ }
4651+ Ok(prev_outputs)
4652+ }
4653+ }
4654+
46394655// Holder designates channel data owned for the benefit of the user client.
46404656// Counterparty designates channel data owned by the another channel participant entity.
46414657pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
@@ -9269,16 +9285,17 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
92699285 unfunded_channel_age_ticks: 0,
92709286 holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
92719287 };
9288+ let dual_funding_context = DualFundingChannelContext {
9289+ our_funding_satoshis: funding_satoshis,
9290+ their_funding_satoshis: None,
9291+ funding_tx_locktime,
9292+ funding_feerate_sat_per_1000_weight,
9293+ our_funding_inputs: funding_inputs,
9294+ };
92729295 let chan = Self {
92739296 context,
92749297 unfunded_context,
9275- dual_funding_context: DualFundingChannelContext {
9276- our_funding_satoshis: funding_satoshis,
9277- their_funding_satoshis: None,
9278- funding_tx_locktime,
9279- funding_feerate_sat_per_1000_weight,
9280- our_funding_inputs: funding_inputs,
9281- },
9298+ dual_funding_context,
92829299 interactive_tx_constructor: None,
92839300 };
92849301 Ok(chan)
0 commit comments