@@ -66,6 +66,8 @@ 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;
70
+
69
71
use crate::io;
70
72
use crate::prelude::*;
71
73
use core::{cmp,mem,fmt};
@@ -1515,6 +1517,7 @@ impl<SP: Deref> Channel<SP> where
1515
1517
let mut funded_channel = FundedChannel {
1516
1518
funding: chan.funding,
1517
1519
pending_funding: vec![],
1520
+ commitment_signed_batch: vec![],
1518
1521
context: chan.context,
1519
1522
interactive_tx_signing_session: chan.interactive_tx_signing_session,
1520
1523
holder_commitment_point,
@@ -4953,6 +4956,7 @@ pub(super) struct DualFundingChannelContext {
4953
4956
pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
4954
4957
pub funding: FundingScope,
4955
4958
pending_funding: Vec<FundingScope>,
4959
+ commitment_signed_batch: Vec<msgs::CommitmentSigned>,
4956
4960
pub context: ChannelContext<SP>,
4957
4961
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
4958
4962
holder_commitment_point: HolderCommitmentPoint,
@@ -5785,7 +5789,53 @@ impl<SP: Deref> FundedChannel<SP> where
5785
5789
return Err(ChannelError::close("Peer sent commitment_signed after we'd started exchanging closing_signeds".to_owned()));
5786
5790
}
5787
5791
5788
- let commitment_tx_info = self.context.validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)?;
5792
+ if msg.batch.is_none() && !self.pending_funding.is_empty() {
5793
+ return Err(ChannelError::close("Peer sent commitment_signed without a batch when there's a pending splice".to_owned()));
5794
+ }
5795
+
5796
+ let mut updates = match &msg.batch {
5797
+ // No pending splice
5798
+ None => {
5799
+ debug_assert!(self.pending_funding.is_empty());
5800
+ self.context
5801
+ .validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)
5802
+ .map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
5803
+ vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5804
+ commitment_tx, htlc_outputs, claimed_htlcs: vec![], nondust_htlc_sources,
5805
+ }]
5806
+ )?
5807
+ },
5808
+ // May or may not have a pending splice
5809
+ Some(batch) => {
5810
+ self.commitment_signed_batch.push(msg.clone());
5811
+ if self.commitment_signed_batch.len() < batch.batch_size as usize {
5812
+ return Ok(None);
5813
+ }
5814
+
5815
+ let commitment_signed_batch: BTreeMap<_, _> = self.commitment_signed_batch
5816
+ .drain(..)
5817
+ .map(|msg| (msg.batch.as_ref().expect("commitment_signed should have a batch").funding_txid, msg))
5818
+ .collect();
5819
+
5820
+ core::iter::once(&self.funding)
5821
+ .chain(self.pending_funding.iter())
5822
+ .map(|funding| {
5823
+ let funding_txid = funding.get_funding_txo().unwrap().txid;
5824
+ let msg = commitment_signed_batch
5825
+ .get(&funding_txid)
5826
+ .ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?;
5827
+ self.context
5828
+ .validate_commitment_signed(funding, &self.holder_commitment_point, msg, logger)
5829
+ .map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
5830
+ ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5831
+ commitment_tx, htlc_outputs, claimed_htlcs: vec![], nondust_htlc_sources,
5832
+ }
5833
+ )
5834
+ }
5835
+ )
5836
+ .collect::<Result<Vec<_>, ChannelError>>()?
5837
+ },
5838
+ };
5789
5839
5790
5840
if self.holder_commitment_point.advance(&self.context.holder_signer, &self.context.secp_ctx, logger).is_err() {
5791
5841
// We only fail to advance our commitment point/number if we're currently
@@ -5840,18 +5890,21 @@ impl<SP: Deref> FundedChannel<SP> where
5840
5890
}
5841
5891
}
5842
5892
5843
- let LatestHolderCommitmentTXInfo {
5844
- commitment_tx, htlc_outputs, nondust_htlc_sources,
5845
- } = commitment_tx_info;
5893
+ for mut update in updates.iter_mut() {
5894
+ if let ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5895
+ claimed_htlcs: ref mut update_claimed_htlcs, ..
5896
+ } = &mut update {
5897
+ debug_assert!(update_claimed_htlcs.is_empty());
5898
+ *update_claimed_htlcs = claimed_htlcs.clone();
5899
+ } else {
5900
+ debug_assert!(false);
5901
+ }
5902
+ }
5903
+
5846
5904
self.context.latest_monitor_update_id += 1;
5847
5905
let mut monitor_update = ChannelMonitorUpdate {
5848
5906
update_id: self.context.latest_monitor_update_id,
5849
- updates: vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5850
- commitment_tx,
5851
- htlc_outputs,
5852
- claimed_htlcs,
5853
- nondust_htlc_sources,
5854
- }],
5907
+ updates,
5855
5908
channel_id: Some(self.context.channel_id()),
5856
5909
};
5857
5910
@@ -9545,6 +9598,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
9545
9598
let mut channel = FundedChannel {
9546
9599
funding: self.funding,
9547
9600
pending_funding: vec![],
9601
+ commitment_signed_batch: vec![],
9548
9602
context: self.context,
9549
9603
interactive_tx_signing_session: None,
9550
9604
is_v2_established: false,
@@ -9822,6 +9876,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
9822
9876
let mut channel = FundedChannel {
9823
9877
funding: self.funding,
9824
9878
pending_funding: vec![],
9879
+ commitment_signed_batch: vec![],
9825
9880
context: self.context,
9826
9881
interactive_tx_signing_session: None,
9827
9882
is_v2_established: false,
@@ -11088,6 +11143,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11088
11143
funding_transaction,
11089
11144
},
11090
11145
pending_funding: pending_funding.unwrap(),
11146
+ commitment_signed_batch: vec![],
11091
11147
context: ChannelContext {
11092
11148
user_id,
11093
11149
0 commit comments