Skip to content

Commit 8ac0358

Browse files
committed
Produce a single monitor update per commitment number
Such updates will contain a single HTLC-source table for that commitment number, together with a vector of commitment transactions created at that commitment number. This vector will grow with the number of pending splices for a channel. The HTLC-source table produced by channel will stop storing information on which HTLCs were assigned which output index. Instead, this information will be stored in each commitment transaction in the monitor update. This commit deduplicates the `HTLCSource` collection for each commitment number, but `HTLCOutputData` would store information already stored in each `CommitmentTransaction` in a monitor update. This is a partial rework of b8a03cd. That commit has not been shipped in a release yet.
1 parent 83e9e80 commit 8ac0358

File tree

3 files changed

+106
-41
lines changed

3 files changed

+106
-41
lines changed

lightning/src/chain/channelmonitor.rs

+65-20
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use crate::types::features::ChannelTypeFeatures;
3838
use crate::types::payment::{PaymentHash, PaymentPreimage};
3939
use crate::ln::msgs::DecodeError;
4040
use crate::ln::channel_keys::{DelayedPaymentKey, DelayedPaymentBasepoint, HtlcBasepoint, HtlcKey, RevocationKey, RevocationBasepoint};
41-
use crate::ln::chan_utils::{self,CommitmentTransaction, CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction};
41+
use crate::ln::chan_utils::{self,CommitmentTransaction, CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction, HTLCOutputData};
4242
use crate::ln::channelmanager::{HTLCSource, SentHTLCId, PaymentClaimDetails};
4343
use crate::chain;
4444
use crate::chain::{BestBlock, WatchedOutput};
@@ -591,11 +591,18 @@ pub(crate) enum ChannelMonitorUpdateStep {
591591
to_broadcaster_value_sat: Option<u64>,
592592
to_countersignatory_value_sat: Option<u64>,
593593
},
594-
LatestCounterpartyCommitmentTX {
594+
LatestHolderCommitmentTXs {
595595
// The dust and non-dust htlcs for that commitment
596-
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
596+
htlc_data: Vec<(HTLCOutputData, Option<Box<HTLCSource>>)>,
597+
// Contains only the non-dust htlcs
598+
commitment_txs: Vec<HolderCommitmentTransaction>,
599+
claimed_htlcs: Vec<(SentHTLCId, PaymentPreimage)>,
600+
},
601+
LatestCounterpartyCommitmentTXs {
602+
// The dust and non-dust htlcs for that commitment
603+
htlc_data: Vec<(HTLCOutputData, Option<Box<HTLCSource>>)>,
597604
// Contains only the non-dust htlcs
598-
commitment_tx: CommitmentTransaction,
605+
commitment_txs: Vec<CommitmentTransaction>,
599606
},
600607
PaymentPreimage {
601608
payment_preimage: PaymentPreimage,
@@ -624,7 +631,8 @@ impl ChannelMonitorUpdateStep {
624631
match self {
625632
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo",
626633
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo",
627-
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. } => "LatestCounterpartyCommitmentTX",
634+
ChannelMonitorUpdateStep::LatestHolderCommitmentTXs { .. } => "LatestHolderCommitmentTXs",
635+
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXs { .. } => "LatestCounterpartyCommitmentTXs",
628636
ChannelMonitorUpdateStep::PaymentPreimage { .. } => "PaymentPreimage",
629637
ChannelMonitorUpdateStep::CommitmentSecret { .. } => "CommitmentSecret",
630638
ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
@@ -663,9 +671,14 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
663671
(5, ShutdownScript) => {
664672
(0, scriptpubkey, required),
665673
},
666-
(6, LatestCounterpartyCommitmentTX) => {
667-
(0, htlc_outputs, required_vec),
668-
(2, commitment_tx, required),
674+
(6, LatestHolderCommitmentTXs) => { // Added in 0.2
675+
(1, htlc_data, required_vec),
676+
(3, commitment_txs, required_vec),
677+
(5, claimed_htlcs, required_vec),
678+
},
679+
(8, LatestCounterpartyCommitmentTXs) => { // Added in 0.2
680+
(1, htlc_data, required_vec),
681+
(3, commitment_txs, required_vec),
669682
},
670683
);
671684

@@ -3084,6 +3097,19 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
30843097
}
30853098
}
30863099

3100+
// This is the sibling of `provide_latest_counterparty_commitment_tx`, but updated for a world
3101+
// in which the HTLC-source table passed from channel does NOT store dust-vs-nondust and
3102+
// index HTLC data.
3103+
fn provide_latest_counterparty_commitment_data<L: Deref>(
3104+
&mut self,
3105+
_htlc_data: Vec<(HTLCOutputData, Option<Box<HTLCSource>>)>,
3106+
_txs: &Vec<CommitmentTransaction>,
3107+
_logger: &WithChannelMonitor<L>,
3108+
) where L::Target: Logger {
3109+
// TODO(splicing, 0.2): Populate this monitor's data structures
3110+
todo!();
3111+
}
3112+
30873113
/// Informs this monitor of the latest holder (ie broadcastable) commitment transaction. The
30883114
/// monitor watches for timeouts and may broadcast it if we approach such a timeout. Thus, it
30893115
/// is important that any clones of this channel monitor (including remote clones) by kept
@@ -3175,6 +3201,19 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
31753201
}
31763202
}
31773203

3204+
// This is the sibling of `provide_latest_holder_commitment_tx`, but updated for a world
3205+
// in which the HTLC-source table passed from channel does NOT store dust-vs-nondust and
3206+
// index HTLC data.
3207+
fn provide_latest_holder_commitment_data(
3208+
&mut self,
3209+
_htlc_data: Vec<(HTLCOutputData, Option<Box<HTLCSource>>)>,
3210+
_holder_commitment_txs: Vec<HolderCommitmentTransaction>,
3211+
_claimed_htlcs: &[(SentHTLCId, PaymentPreimage)],
3212+
) {
3213+
// TODO(splicing, 0.2): Populate this monitor's data structures
3214+
todo!();
3215+
}
3216+
31783217
/// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all
31793218
/// commitment_tx_infos which contain the payment hash have been revoked.
31803219
///
@@ -3392,16 +3431,21 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33923431
if self.lockdown_from_offchain { panic!(); }
33933432
self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone(), &claimed_htlcs, nondust_htlc_sources.clone());
33943433
}
3395-
// Soon we will drop the `LatestCounterpartyCommitmentTXInfo` variant in favor of `LatestCounterpartyCommitmentTX`.
3434+
// Soon we will drop the `LatestCounterpartyCommitmentTXInfo` variant in favor of `LatestCounterpartyCommitmentTXs`.
33963435
// For now we just add the code to handle the new updates.
3397-
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
3436+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTXs` variant.
33983437
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => {
33993438
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
34003439
self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger)
34013440
},
3402-
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs, commitment_tx } => {
3403-
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
3404-
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), htlc_outputs.clone(), commitment_tx.commitment_number(), commitment_tx.per_commitment_point(), logger)
3441+
ChannelMonitorUpdateStep::LatestHolderCommitmentTXs { htlc_data, commitment_txs, claimed_htlcs } => {
3442+
log_trace!(logger, "Updating ChannelMonitor with latest holder commitment transaction(s)");
3443+
if self.lockdown_from_offchain { panic!(); }
3444+
self.provide_latest_holder_commitment_data(htlc_data.clone(), commitment_txs.clone(), claimed_htlcs)
3445+
}
3446+
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXs { htlc_data, commitment_txs } => {
3447+
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction(s)");
3448+
self.provide_latest_counterparty_commitment_data(htlc_data.clone(), commitment_txs, logger)
34053449
},
34063450
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage, payment_info } => {
34073451
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
@@ -3465,7 +3509,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34653509
match update {
34663510
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. }
34673511
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. }
3468-
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. }
3512+
|ChannelMonitorUpdateStep::LatestHolderCommitmentTXs { .. }
3513+
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXs { .. }
34693514
|ChannelMonitorUpdateStep::ShutdownScript { .. }
34703515
|ChannelMonitorUpdateStep::CommitmentSecret { .. } =>
34713516
is_pre_close_update = true,
@@ -3620,7 +3665,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
36203665
update.updates.iter().filter_map(|update| {
36213666
// Soon we will drop the first branch here in favor of the second.
36223667
// In preparation, we just add the second branch without deleting the first.
3623-
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
3668+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTXs` variant.
36243669
match update {
36253670
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid,
36263671
ref htlc_outputs, commitment_number, their_per_commitment_point,
@@ -3638,16 +3683,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
36383683

36393684
debug_assert_eq!(commitment_tx.trust().txid(), commitment_txid);
36403685

3641-
Some(commitment_tx)
3686+
Some(vec![commitment_tx])
36423687
},
3643-
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX {
3644-
htlc_outputs: _, ref commitment_tx,
3688+
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXs {
3689+
htlc_data: _, ref commitment_txs,
36453690
} => {
3646-
Some(commitment_tx.clone())
3691+
Some(commitment_txs.clone())
36473692
},
36483693
_ => None,
36493694
}
3650-
}).collect()
3695+
}).flatten().collect()
36513696
}
36523697

36533698
fn sign_to_local_justice_tx(

lightning/src/ln/chan_utils.rs

+19
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,25 @@ pub fn get_counterparty_payment_script(channel_type_features: &ChannelTypeFeatur
586586
}
587587
}
588588

589+
/// The subset of the fields in `HTLCOutputInCommitment` that is constant across multiple
590+
/// commitment transactions for a commitment number (ie. splices). Therefore, this struct does not
591+
/// store information on whether the HTLC is dust or non-dust, and if non-dust, which index in the
592+
/// commitment transaction the HTLC got assigned to.
593+
#[derive(Clone, Debug, PartialEq, Eq)]
594+
pub(crate) struct HTLCOutputData {
595+
pub(crate) offered: bool,
596+
pub(crate) amount_msat: u64,
597+
pub(crate) cltv_expiry: u32,
598+
pub(crate) payment_hash: PaymentHash,
599+
}
600+
601+
impl_writeable_tlv_based!(HTLCOutputData, {
602+
(1, offered, required),
603+
(3, amount_msat, required),
604+
(5, cltv_expiry, required),
605+
(7, payment_hash, required),
606+
});
607+
589608
/// Information about an HTLC as it appears in a commitment transaction
590609
#[derive(Clone, Debug, PartialEq, Eq)]
591610
pub struct HTLCOutputInCommitment {

lightning/src/ln/channel.rs

+22-21
Original file line numberDiff line numberDiff line change
@@ -9013,31 +9013,32 @@ impl<SP: Deref> FundedChannel<SP> where
90139013
}
90149014
self.context.resend_order = RAACommitmentOrder::RevokeAndACKFirst;
90159015

9016-
let mut updates = Vec::with_capacity(self.pending_funding.len() + 1);
9017-
for funding in core::iter::once(&self.funding).chain(self.pending_funding.iter()) {
9016+
// Even in the pending splices case, we will send a single update for each commitment number.
9017+
// In that case, the update will contain multiple commitment transactions.
9018+
let mut updates = vec![];
9019+
if self.pending_funding.is_empty() {
90189020
let (htlcs_ref, counterparty_commitment_tx) =
9019-
self.build_commitment_no_state_update(funding, logger);
9021+
self.build_commitment_no_state_update(&self.funding, logger);
90209022
let htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)> =
90219023
htlcs_ref.into_iter().map(|(htlc, htlc_source)| (htlc, htlc_source.map(|source_ref| Box::new(source_ref.clone())))).collect();
90229024

9023-
if self.pending_funding.is_empty() {
9024-
// Soon, we will switch this to `LatestCounterpartyCommitmentTX`,
9025-
// and provide the full commit tx instead of the information needed to rebuild it.
9026-
updates.push(ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo {
9027-
commitment_txid: counterparty_commitment_tx.trust().txid(),
9028-
htlc_outputs,
9029-
commitment_number: self.context.cur_counterparty_commitment_transaction_number,
9030-
their_per_commitment_point: self.context.counterparty_cur_commitment_point.unwrap(),
9031-
feerate_per_kw: Some(counterparty_commitment_tx.feerate_per_kw()),
9032-
to_broadcaster_value_sat: Some(counterparty_commitment_tx.to_broadcaster_value_sat()),
9033-
to_countersignatory_value_sat: Some(counterparty_commitment_tx.to_countersignatory_value_sat()),
9034-
});
9035-
} else {
9036-
updates.push(ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX {
9037-
htlc_outputs,
9038-
commitment_tx: counterparty_commitment_tx,
9039-
});
9040-
}
9025+
// Soon, we will switch this to `LatestCounterpartyCommitmentTXs`,
9026+
// and provide the full commit tx instead of the information needed to rebuild it.
9027+
updates.push(ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo {
9028+
commitment_txid: counterparty_commitment_tx.trust().txid(),
9029+
htlc_outputs,
9030+
commitment_number: self.context.cur_counterparty_commitment_transaction_number,
9031+
their_per_commitment_point: self.context.counterparty_cur_commitment_point.unwrap(),
9032+
feerate_per_kw: Some(counterparty_commitment_tx.feerate_per_kw()),
9033+
to_broadcaster_value_sat: Some(counterparty_commitment_tx.to_broadcaster_value_sat()),
9034+
to_countersignatory_value_sat: Some(counterparty_commitment_tx.to_countersignatory_value_sat()),
9035+
});
9036+
} else {
9037+
// TODO(splicing): Build the HTLC-source table once per commitment number, and then
9038+
// build all the commitment transactions for that commitment number against that same
9039+
// table. Use `LatestCounterpartyCommitmentTXs` and `LatestHolderCommitmentTXs` to
9040+
// communicate these to `ChannelMonitor`.
9041+
todo!();
90419042
}
90429043

90439044
if self.context.announcement_sigs_state == AnnouncementSigsState::MessageSent {

0 commit comments

Comments
 (0)