@@ -65,6 +65,8 @@ use crate::util::errors::APIError;
65
65
use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits, MaxDustHTLCExposure};
66
66
use crate::util::scid_utils::scid_from_parts;
67
67
68
+ use alloc::collections::BTreeMap;
69
+
68
70
use crate::io;
69
71
use crate::prelude::*;
70
72
use core::{cmp,mem,fmt};
@@ -1514,6 +1516,7 @@ impl<SP: Deref> Channel<SP> where
1514
1516
let mut funded_channel = FundedChannel {
1515
1517
funding: chan.funding,
1516
1518
pending_funding: vec![],
1519
+ commitment_signed_batch: vec![],
1517
1520
context: chan.context,
1518
1521
interactive_tx_signing_session: chan.interactive_tx_signing_session,
1519
1522
holder_commitment_point,
@@ -4846,6 +4849,7 @@ pub(super) struct DualFundingChannelContext {
4846
4849
pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
4847
4850
pub funding: FundingScope,
4848
4851
pending_funding: Vec<FundingScope>,
4852
+ commitment_signed_batch: Vec<msgs::CommitmentSigned>,
4849
4853
pub context: ChannelContext<SP>,
4850
4854
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
4851
4855
holder_commitment_point: HolderCommitmentPoint,
@@ -5675,7 +5679,53 @@ impl<SP: Deref> FundedChannel<SP> where
5675
5679
return Err(ChannelError::close("Peer sent commitment_signed after we'd started exchanging closing_signeds".to_owned()));
5676
5680
}
5677
5681
5678
- let commitment_tx_info = self.context.validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)?;
5682
+ if msg.batch.is_none() && !self.pending_funding.is_empty() {
5683
+ return Err(ChannelError::close("Peer sent commitment_signed without a batch when there's a pending splice".to_owned()));
5684
+ }
5685
+
5686
+ let mut updates = match &msg.batch {
5687
+ // No pending splice
5688
+ None => {
5689
+ debug_assert!(self.pending_funding.is_empty());
5690
+ self.context
5691
+ .validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)
5692
+ .map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
5693
+ vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5694
+ commitment_tx, htlc_outputs, claimed_htlcs: vec![], nondust_htlc_sources,
5695
+ }]
5696
+ )?
5697
+ },
5698
+ // May or may not have a pending splice
5699
+ Some(batch) => {
5700
+ self.commitment_signed_batch.push(msg.clone());
5701
+ if self.commitment_signed_batch.len() < batch.batch_size as usize {
5702
+ return Ok(None);
5703
+ }
5704
+
5705
+ let commitment_signed_batch: BTreeMap<_, _> = self.commitment_signed_batch
5706
+ .drain(..)
5707
+ .map(|msg| (msg.batch.as_ref().expect("commitment_signed should have a batch").funding_txid, msg))
5708
+ .collect();
5709
+
5710
+ core::iter::once(&self.funding)
5711
+ .chain(self.pending_funding.iter())
5712
+ .map(|funding| {
5713
+ let funding_txid = funding.get_funding_txo().unwrap().txid;
5714
+ let msg = commitment_signed_batch
5715
+ .get(&funding_txid)
5716
+ .ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?;
5717
+ self.context
5718
+ .validate_commitment_signed(funding, &self.holder_commitment_point, msg, logger)
5719
+ .map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
5720
+ ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5721
+ commitment_tx, htlc_outputs, claimed_htlcs: vec![], nondust_htlc_sources,
5722
+ }
5723
+ )
5724
+ }
5725
+ )
5726
+ .collect::<Result<Vec<_>, ChannelError>>()?
5727
+ },
5728
+ };
5679
5729
5680
5730
if self.holder_commitment_point.advance(&self.context.holder_signer, &self.context.secp_ctx, logger).is_err() {
5681
5731
// We only fail to advance our commitment point/number if we're currently
@@ -5730,19 +5780,22 @@ impl<SP: Deref> FundedChannel<SP> where
5730
5780
}
5731
5781
}
5732
5782
5733
- let LatestHolderCommitmentTXInfo {
5734
- commitment_tx, htlc_outputs, nondust_htlc_sources,
5735
- } = commitment_tx_info;
5783
+ for mut update in updates.iter_mut() {
5784
+ if let ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5785
+ claimed_htlcs: ref mut update_claimed_htlcs, ..
5786
+ } = &mut update {
5787
+ debug_assert!(update_claimed_htlcs.is_empty());
5788
+ *update_claimed_htlcs = claimed_htlcs.clone();
5789
+ } else {
5790
+ debug_assert!(false);
5791
+ }
5792
+ }
5793
+
5736
5794
self.context.latest_monitor_update_id += 1;
5737
5795
let mut monitor_update = ChannelMonitorUpdate {
5738
5796
update_id: self.context.latest_monitor_update_id,
5739
5797
counterparty_node_id: Some(self.context.counterparty_node_id),
5740
- updates: vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5741
- commitment_tx,
5742
- htlc_outputs,
5743
- claimed_htlcs,
5744
- nondust_htlc_sources,
5745
- }],
5798
+ updates,
5746
5799
channel_id: Some(self.context.channel_id()),
5747
5800
};
5748
5801
@@ -9305,6 +9358,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
9305
9358
let mut channel = FundedChannel {
9306
9359
funding: self.funding,
9307
9360
pending_funding: vec![],
9361
+ commitment_signed_batch: vec![],
9308
9362
context: self.context,
9309
9363
interactive_tx_signing_session: None,
9310
9364
is_v2_established: false,
@@ -9573,6 +9627,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
9573
9627
let mut channel = FundedChannel {
9574
9628
funding: self.funding,
9575
9629
pending_funding: vec![],
9630
+ commitment_signed_batch: vec![],
9576
9631
context: self.context,
9577
9632
interactive_tx_signing_session: None,
9578
9633
is_v2_established: false,
@@ -10818,6 +10873,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10818
10873
funding_transaction,
10819
10874
},
10820
10875
pending_funding: pending_funding.unwrap(),
10876
+ commitment_signed_batch: vec![],
10821
10877
context: ChannelContext {
10822
10878
user_id,
10823
10879
0 commit comments