@@ -1939,21 +1939,10 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
19391939 funding_inputs.push(prev_funding_input);
19401940 }
19411941
1942- let mut funding_inputs_prev_outputs: Vec<&TxOut> = Vec::with_capacity(funding_inputs.len());
1943- // Check that vouts exist for each TxIn in provided transactions.
1944- for (idx, (txin, tx)) in funding_inputs.iter().enumerate() {
1945- if let Some(output) = tx.as_transaction().output.get(txin.previous_output.vout as usize) {
1946- funding_inputs_prev_outputs.push(output);
1947- } else {
1948- return Err(APIError::APIMisuseError {
1949- err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
1950- tx.as_transaction().compute_txid(), txin.previous_output.vout, idx) });
1951- }
1952- }
1942+ let funding_inputs_prev_outputs = DualFundingChannelContext::txouts_from_input_prev_txs(&funding_inputs)
1943+ .map_err(|err| APIError::APIMisuseError { err: err.to_string() })?;
19531944
1954- let total_input_satoshis: u64 = funding_inputs.iter().map(
1955- |(txin, tx)| tx.as_transaction().output.get(txin.previous_output.vout as usize).map(|out| out.value.to_sat()).unwrap_or(0)
1956- ).sum();
1945+ let total_input_satoshis: u64 = funding_inputs_prev_outputs.iter().map(|txout| txout.value.to_sat()).sum();
19571946 if total_input_satoshis < self.dual_funding_context.our_funding_satoshis {
19581947 return Err(APIError::APIMisuseError {
19591948 err: format!("Total value of funding inputs must be at least funding amount. It was {} sats",
@@ -4513,6 +4502,33 @@ pub(super) struct DualFundingChannelContext {
45134502 pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
45144503}
45154504
4505+ impl DualFundingChannelContext {
4506+ /// Obtain prev outputs for each supplied input and matching transaction.
4507+ /// Can error when there a prev tx does not have an output for the specified vout number.
4508+ /// Also checks for matching of transaction IDs.
4509+ fn txouts_from_input_prev_txs(inputs: &Vec<(TxIn, TransactionU16LenLimited)>) -> Result<Vec<&TxOut>, ChannelError> {
4510+ let mut prev_outputs: Vec<&TxOut> = Vec::with_capacity(inputs.len());
4511+ // Check that vouts exist for each TxIn in provided transactions.
4512+ for (idx, (txin, tx)) in inputs.iter().enumerate() {
4513+ let txid = tx.as_transaction().compute_txid();
4514+ if txin.previous_output.txid != txid {
4515+ return Err(ChannelError::Warn(
4516+ format!("Transaction input txid mismatch, {} vs. {}, at index {}", txin.previous_output.txid, txid, idx)
4517+ ));
4518+ }
4519+ if let Some(output) = tx.as_transaction().output.get(txin.previous_output.vout as usize) {
4520+ prev_outputs.push(output);
4521+ } else {
4522+ return Err(ChannelError::Warn(
4523+ format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn, at index {}",
4524+ txid, txin.previous_output.vout, idx)
4525+ ));
4526+ }
4527+ }
4528+ Ok(prev_outputs)
4529+ }
4530+ }
4531+
45164532// Holder designates channel data owned for the benefit of the user client.
45174533// Counterparty designates channel data owned by the another channel participant entity.
45184534pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
@@ -9181,16 +9197,17 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
91819197 unfunded_channel_age_ticks: 0,
91829198 holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
91839199 };
9200+ let dual_funding_context = DualFundingChannelContext {
9201+ our_funding_satoshis: funding_satoshis,
9202+ their_funding_satoshis: None,
9203+ funding_tx_locktime,
9204+ funding_feerate_sat_per_1000_weight,
9205+ our_funding_inputs: funding_inputs,
9206+ };
91849207 let chan = Self {
91859208 context,
91869209 unfunded_context,
9187- dual_funding_context: DualFundingChannelContext {
9188- our_funding_satoshis: funding_satoshis,
9189- their_funding_satoshis: None,
9190- funding_tx_locktime,
9191- funding_feerate_sat_per_1000_weight,
9192- our_funding_inputs: funding_inputs,
9193- },
9210+ dual_funding_context,
91949211 interactive_tx_constructor: None,
91959212 };
91969213 Ok(chan)
0 commit comments