@@ -66,7 +66,7 @@ use crate::util::errors::APIError;
6666use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits, MaxDustHTLCExposure};
6767use crate::util::scid_utils::scid_from_parts;
6868
69- use alloc::collections::BTreeMap;
69+ use alloc::collections::{btree_map, BTreeMap} ;
7070
7171use crate::io;
7272use crate::prelude::*;
@@ -1517,7 +1517,7 @@ impl<SP: Deref> Channel<SP> where
15171517 let mut funded_channel = FundedChannel {
15181518 funding: chan.funding,
15191519 pending_funding: vec![],
1520- commitment_signed_batch: vec![] ,
1520+ commitment_signed_batch: BTreeMap::new() ,
15211521 context: chan.context,
15221522 interactive_tx_signing_session: chan.interactive_tx_signing_session,
15231523 holder_commitment_point,
@@ -4952,7 +4952,7 @@ pub(super) struct DualFundingChannelContext {
49524952pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
49534953 pub funding: FundingScope,
49544954 pending_funding: Vec<FundingScope>,
4955- commitment_signed_batch: Vec< msgs::CommitmentSigned>,
4955+ commitment_signed_batch: BTreeMap<Txid, msgs::CommitmentSigned>,
49564956 pub context: ChannelContext<SP>,
49574957 pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
49584958 holder_commitment_point: HolderCommitmentPoint,
@@ -5798,6 +5798,7 @@ impl<SP: Deref> FundedChannel<SP> where
57985798 // No pending splice
57995799 None => {
58005800 debug_assert!(self.pending_funding.is_empty());
5801+ debug_assert!(self.commitment_signed_batch.is_empty());
58015802 self.context
58025803 .validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)
58035804 .map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
@@ -5808,23 +5809,24 @@ impl<SP: Deref> FundedChannel<SP> where
58085809 },
58095810 // May or may not have a pending splice
58105811 Some(batch) => {
5811- self.commitment_signed_batch.push(msg.clone());
5812+ match self.commitment_signed_batch.entry(batch.funding_txid) {
5813+ btree_map::Entry::Vacant(entry) => { entry.insert(msg.clone()); },
5814+ btree_map::Entry::Occupied(entry) => {
5815+ return Err(ChannelError::close(format!("Peer sent commitment_signed with duplicate funding_txid {} in a batch", entry.key())));
5816+ },
5817+ }
5818+
58125819 if self.commitment_signed_batch.len() < batch.batch_size as usize {
58135820 return Ok(None);
58145821 }
58155822
58165823 // Any commitment_signed not associated with a FundingScope is ignored below if a
58175824 // pending splice transaction has confirmed since receiving the batch.
5818- let commitment_signed_batch: BTreeMap<_, _> = self.commitment_signed_batch
5819- .drain(..)
5820- .map(|msg| (msg.batch.as_ref().expect("commitment_signed should have a batch").funding_txid, msg))
5821- .collect();
5822-
58235825 core::iter::once(&self.funding)
58245826 .chain(self.pending_funding.iter())
58255827 .map(|funding| {
58265828 let funding_txid = funding.get_funding_txo().unwrap().txid;
5827- let msg = commitment_signed_batch
5829+ let msg = self. commitment_signed_batch
58285830 .get(&funding_txid)
58295831 .ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?;
58305832 self.context
@@ -5839,6 +5841,7 @@ impl<SP: Deref> FundedChannel<SP> where
58395841 .collect::<Result<Vec<_>, ChannelError>>()?
58405842 },
58415843 };
5844+ self.commitment_signed_batch.clear();
58425845
58435846 if self.holder_commitment_point.advance(&self.context.holder_signer, &self.context.secp_ctx, logger).is_err() {
58445847 // We only fail to advance our commitment point/number if we're currently
@@ -9601,7 +9604,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
96019604 let mut channel = FundedChannel {
96029605 funding: self.funding,
96039606 pending_funding: vec![],
9604- commitment_signed_batch: vec![] ,
9607+ commitment_signed_batch: BTreeMap::new() ,
96059608 context: self.context,
96069609 interactive_tx_signing_session: None,
96079610 is_v2_established: false,
@@ -9879,7 +9882,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
98799882 let mut channel = FundedChannel {
98809883 funding: self.funding,
98819884 pending_funding: vec![],
9882- commitment_signed_batch: vec![] ,
9885+ commitment_signed_batch: BTreeMap::new() ,
98839886 context: self.context,
98849887 interactive_tx_signing_session: None,
98859888 is_v2_established: false,
@@ -11146,7 +11149,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1114611149 funding_transaction,
1114711150 },
1114811151 pending_funding: pending_funding.unwrap(),
11149- commitment_signed_batch: vec![] ,
11152+ commitment_signed_batch: BTreeMap::new() ,
1115011153 context: ChannelContext {
1115111154 user_id,
1115211155
0 commit comments