@@ -1515,7 +1515,8 @@ impl<SP: Deref> Channel<SP> where
1515
1515
};
1516
1516
let mut funded_channel = FundedChannel {
1517
1517
funding: chan.funding,
1518
- pending_funding: BTreeMap::new(),
1518
+ pending_funding: vec![],
1519
+ commitment_signed_batch: vec![],
1519
1520
context: chan.context,
1520
1521
interactive_tx_signing_session: chan.interactive_tx_signing_session,
1521
1522
holder_commitment_point,
@@ -4823,7 +4824,8 @@ pub(super) struct DualFundingChannelContext {
4823
4824
// Counterparty designates channel data owned by the another channel participant entity.
4824
4825
pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
4825
4826
pub funding: FundingScope,
4826
- pending_funding: BTreeMap<Txid, FundingScope>,
4827
+ pending_funding: Vec<FundingScope>,
4828
+ commitment_signed_batch: Vec<msgs::CommitmentSigned>,
4827
4829
pub context: ChannelContext<SP>,
4828
4830
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
4829
4831
holder_commitment_point: HolderCommitmentPoint,
@@ -5653,7 +5655,53 @@ impl<SP: Deref> FundedChannel<SP> where
5653
5655
return Err(ChannelError::close("Peer sent commitment_signed after we'd started exchanging closing_signeds".to_owned()));
5654
5656
}
5655
5657
5656
- let commitment_tx_info = self.context.validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)?;
5658
+ if msg.batch.is_none() && !self.pending_funding.is_empty() {
5659
+ return Err(ChannelError::close("Peer sent commitment_signed without a batch when there's a pending splice".to_owned()));
5660
+ }
5661
+
5662
+ let mut updates = match &msg.batch {
5663
+ // No pending splice
5664
+ None => {
5665
+ debug_assert!(self.pending_funding.is_empty());
5666
+ self.context
5667
+ .validate_commitment_signed(&self.funding, &self.holder_commitment_point, msg, logger)
5668
+ .map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
5669
+ vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5670
+ commitment_tx, htlc_outputs, claimed_htlcs: vec![], nondust_htlc_sources,
5671
+ }]
5672
+ )?
5673
+ },
5674
+ // May or may not have a pending splice
5675
+ Some(batch) => {
5676
+ self.commitment_signed_batch.push(msg.clone());
5677
+ if self.commitment_signed_batch.len() < batch.batch_size as usize {
5678
+ return Ok(None);
5679
+ }
5680
+
5681
+ let commitment_signed_batch: BTreeMap<_, _> = self.commitment_signed_batch
5682
+ .drain(..)
5683
+ .map(|msg| (msg.batch.as_ref().expect("commitment_signed should have a batch").funding_txid, msg))
5684
+ .collect();
5685
+
5686
+ core::iter::once(&self.funding)
5687
+ .chain(self.pending_funding.iter())
5688
+ .map(|funding| {
5689
+ let funding_txid = funding.get_funding_txo().unwrap().txid;
5690
+ let msg = commitment_signed_batch
5691
+ .get(&funding_txid)
5692
+ .ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?;
5693
+ self.context
5694
+ .validate_commitment_signed(funding, &self.holder_commitment_point, msg, logger)
5695
+ .map(|LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, nondust_htlc_sources }|
5696
+ ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5697
+ commitment_tx, htlc_outputs, claimed_htlcs: vec![], nondust_htlc_sources,
5698
+ }
5699
+ )
5700
+ }
5701
+ )
5702
+ .collect::<Result<Vec<_>, ChannelError>>()?
5703
+ },
5704
+ };
5657
5705
5658
5706
if self.holder_commitment_point.advance(&self.context.holder_signer, &self.context.secp_ctx, logger).is_err() {
5659
5707
// We only fail to advance our commitment point/number if we're currently
@@ -5708,19 +5756,22 @@ impl<SP: Deref> FundedChannel<SP> where
5708
5756
}
5709
5757
}
5710
5758
5711
- let LatestHolderCommitmentTXInfo {
5712
- commitment_tx, htlc_outputs, nondust_htlc_sources,
5713
- } = commitment_tx_info;
5759
+ for mut update in updates.iter_mut() {
5760
+ if let ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5761
+ claimed_htlcs: ref mut update_claimed_htlcs, ..
5762
+ } = &mut update {
5763
+ debug_assert!(update_claimed_htlcs.is_empty());
5764
+ *update_claimed_htlcs = claimed_htlcs.clone();
5765
+ } else {
5766
+ debug_assert!(false);
5767
+ }
5768
+ }
5769
+
5714
5770
self.context.latest_monitor_update_id += 1;
5715
5771
let mut monitor_update = ChannelMonitorUpdate {
5716
5772
update_id: self.context.latest_monitor_update_id,
5717
5773
counterparty_node_id: Some(self.context.counterparty_node_id),
5718
- updates: vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
5719
- commitment_tx,
5720
- htlc_outputs,
5721
- claimed_htlcs,
5722
- nondust_htlc_sources,
5723
- }],
5774
+ updates,
5724
5775
channel_id: Some(self.context.channel_id()),
5725
5776
};
5726
5777
@@ -9282,7 +9333,8 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
9282
9333
9283
9334
let mut channel = FundedChannel {
9284
9335
funding: self.funding,
9285
- pending_funding: BTreeMap::new(),
9336
+ pending_funding: vec![],
9337
+ commitment_signed_batch: vec![],
9286
9338
context: self.context,
9287
9339
interactive_tx_signing_session: None,
9288
9340
is_v2_established: false,
@@ -9550,7 +9602,8 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
9550
9602
// `ChannelMonitor`.
9551
9603
let mut channel = FundedChannel {
9552
9604
funding: self.funding,
9553
- pending_funding: BTreeMap::new(),
9605
+ pending_funding: vec![],
9606
+ commitment_signed_batch: vec![],
9554
9607
context: self.context,
9555
9608
interactive_tx_signing_session: None,
9556
9609
is_v2_established: false,
@@ -10791,7 +10844,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10791
10844
channel_transaction_parameters: channel_parameters,
10792
10845
funding_transaction,
10793
10846
},
10794
- pending_funding: BTreeMap::new(),
10847
+ pending_funding: vec![],
10848
+ commitment_signed_batch: vec![],
10795
10849
context: ChannelContext {
10796
10850
user_id,
10797
10851
0 commit comments