@@ -66,7 +66,7 @@ use crate::util::errors::APIError;
66
66
use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits, MaxDustHTLCExposure};
67
67
use crate::util::scid_utils::scid_from_parts;
68
68
69
- use alloc::collections::BTreeMap;
69
+ use alloc::collections::{btree_map, BTreeMap} ;
70
70
71
71
use crate::io;
72
72
use crate::prelude::*;
@@ -1517,7 +1517,7 @@ impl<SP: Deref> Channel<SP> where
1517
1517
let mut funded_channel = FundedChannel {
1518
1518
funding: chan.funding,
1519
1519
pending_funding: vec![],
1520
- commitment_signed_batch: vec![] ,
1520
+ commitment_signed_batch: BTreeMap::new() ,
1521
1521
context: chan.context,
1522
1522
interactive_tx_signing_session: chan.interactive_tx_signing_session,
1523
1523
holder_commitment_point,
@@ -4956,7 +4956,7 @@ pub(super) struct DualFundingChannelContext {
4956
4956
pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
4957
4957
pub funding: FundingScope,
4958
4958
pending_funding: Vec<FundingScope>,
4959
- commitment_signed_batch: Vec< msgs::CommitmentSigned>,
4959
+ commitment_signed_batch: BTreeMap<Txid, msgs::CommitmentSigned>,
4960
4960
pub context: ChannelContext<SP>,
4961
4961
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
4962
4962
holder_commitment_point: HolderCommitmentPoint,
@@ -5802,6 +5802,7 @@ impl<SP: Deref> FundedChannel<SP> where
5802
5802
// No pending splice
5803
5803
None => {
5804
5804
debug_assert!(self.pending_funding.is_empty());
5805
+ debug_assert!(self.commitment_signed_batch.is_empty());
5805
5806
self.context
5806
5807
.validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)
5807
5808
.map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
@@ -5812,23 +5813,24 @@ impl<SP: Deref> FundedChannel<SP> where
5812
5813
},
5813
5814
// May or may not have a pending splice
5814
5815
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
+
5816
5823
if self.commitment_signed_batch.len() < batch.batch_size as usize {
5817
5824
return Ok(None);
5818
5825
}
5819
5826
5820
5827
// Any commitment_signed not associated with a FundingScope is ignored below if a
5821
5828
// 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
-
5827
5829
core::iter::once(&self.funding)
5828
5830
.chain(self.pending_funding.iter())
5829
5831
.map(|funding| {
5830
5832
let funding_txid = funding.get_funding_txo().unwrap().txid;
5831
- let msg = commitment_signed_batch
5833
+ let msg = self. commitment_signed_batch
5832
5834
.get(&funding_txid)
5833
5835
.ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?;
5834
5836
self.context
@@ -5843,6 +5845,7 @@ impl<SP: Deref> FundedChannel<SP> where
5843
5845
.collect::<Result<Vec<_>, ChannelError>>()?
5844
5846
},
5845
5847
};
5848
+ self.commitment_signed_batch.clear();
5846
5849
5847
5850
if self.holder_commitment_point.advance(&self.context.holder_signer, &self.context.secp_ctx, logger).is_err() {
5848
5851
// 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 {
9605
9608
let mut channel = FundedChannel {
9606
9609
funding: self.funding,
9607
9610
pending_funding: vec![],
9608
- commitment_signed_batch: vec![] ,
9611
+ commitment_signed_batch: BTreeMap::new() ,
9609
9612
context: self.context,
9610
9613
interactive_tx_signing_session: None,
9611
9614
is_v2_established: false,
@@ -9883,7 +9886,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
9883
9886
let mut channel = FundedChannel {
9884
9887
funding: self.funding,
9885
9888
pending_funding: vec![],
9886
- commitment_signed_batch: vec![] ,
9889
+ commitment_signed_batch: BTreeMap::new() ,
9887
9890
context: self.context,
9888
9891
interactive_tx_signing_session: None,
9889
9892
is_v2_established: false,
@@ -11150,7 +11153,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11150
11153
funding_transaction,
11151
11154
},
11152
11155
pending_funding: pending_funding.unwrap(),
11153
- commitment_signed_batch: vec![] ,
11156
+ commitment_signed_batch: BTreeMap::new() ,
11154
11157
context: ChannelContext {
11155
11158
user_id,
11156
11159
0 commit comments