@@ -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,
@@ -4956,7 +4956,7 @@ pub(super) struct DualFundingChannelContext {
49564956pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
49574957 pub funding: FundingScope,
49584958 pending_funding: Vec<FundingScope>,
4959- commitment_signed_batch: Vec< msgs::CommitmentSigned>,
4959+ commitment_signed_batch: BTreeMap<Txid, msgs::CommitmentSigned>,
49604960 pub context: ChannelContext<SP>,
49614961 pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
49624962 holder_commitment_point: HolderCommitmentPoint,
@@ -5802,6 +5802,7 @@ impl<SP: Deref> FundedChannel<SP> where
58025802 // No pending splice
58035803 None => {
58045804 debug_assert!(self.pending_funding.is_empty());
5805+ debug_assert!(self.commitment_signed_batch.is_empty());
58055806 self.context
58065807 .validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)
58075808 .map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
@@ -5812,23 +5813,24 @@ impl<SP: Deref> FundedChannel<SP> where
58125813 },
58135814 // May or may not have a pending splice
58145815 Some(batch) => {
5815- self.commitment_signed_batch.push(msg.clone());
5816+ match self.commitment_signed_batch.entry(batch.funding_txid) {
5817+ btree_map::Entry::Vacant(entry) => { entry.insert(msg.clone()); },
5818+ btree_map::Entry::Occupied(entry) => {
5819+ return Err(ChannelError::close(format!("Peer sent commitment_signed with duplicate funding_txid {} in a batch", entry.key())));
5820+ },
5821+ }
5822+
58165823 if self.commitment_signed_batch.len() < batch.batch_size as usize {
58175824 return Ok(None);
58185825 }
58195826
58205827 // Any commitment_signed not associated with a FundingScope is ignored below if a
58215828 // pending splice transaction has confirmed since receiving the batch.
5822- let commitment_signed_batch: BTreeMap<_, _> = self.commitment_signed_batch
5823- .drain(..)
5824- .map(|msg| (msg.batch.as_ref().expect("commitment_signed should have a batch").funding_txid, msg))
5825- .collect();
5826-
58275829 core::iter::once(&self.funding)
58285830 .chain(self.pending_funding.iter())
58295831 .map(|funding| {
58305832 let funding_txid = funding.get_funding_txo().unwrap().txid;
5831- let msg = commitment_signed_batch
5833+ let msg = self. commitment_signed_batch
58325834 .get(&funding_txid)
58335835 .ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?;
58345836 self.context
@@ -5843,6 +5845,7 @@ impl<SP: Deref> FundedChannel<SP> where
58435845 .collect::<Result<Vec<_>, ChannelError>>()?
58445846 },
58455847 };
5848+ self.commitment_signed_batch.clear();
58465849
58475850 if self.holder_commitment_point.advance(&self.context.holder_signer, &self.context.secp_ctx, logger).is_err() {
58485851 // We only fail to advance our commitment point/number if we're currently
@@ -9605,7 +9608,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
96059608 let mut channel = FundedChannel {
96069609 funding: self.funding,
96079610 pending_funding: vec![],
9608- commitment_signed_batch: vec![] ,
9611+ commitment_signed_batch: BTreeMap::new() ,
96099612 context: self.context,
96109613 interactive_tx_signing_session: None,
96119614 is_v2_established: false,
@@ -9883,7 +9886,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
98839886 let mut channel = FundedChannel {
98849887 funding: self.funding,
98859888 pending_funding: vec![],
9886- commitment_signed_batch: vec![] ,
9889+ commitment_signed_batch: BTreeMap::new() ,
98879890 context: self.context,
98889891 interactive_tx_signing_session: None,
98899892 is_v2_established: false,
@@ -11150,7 +11153,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1115011153 funding_transaction,
1115111154 },
1115211155 pending_funding: pending_funding.unwrap(),
11153- commitment_signed_batch: vec![] ,
11156+ commitment_signed_batch: BTreeMap::new() ,
1115411157 context: ChannelContext {
1115511158 user_id,
1115611159
0 commit comments