Skip to content

Commit ad98735

Browse files
committed
Provide built counterparty commitment transactions to ChannelMonitor
Prior to this commit, `LatestCounterpartyCommitmentTXInfo` provided `ChannelMonitor` with the data it needed to build counterparty commitment transactions, instead of the fully built transaction. This was an unnecessary optimization, as the data still included all the htlcs. This meant that the size of `LatestCounterpartyCommitmentTXInfo` scaled with the number of htlcs, just like a fully built transaction. This commit adds a new variant to `ChannelMonitorUpdateStep` called `LatestCounterpartyCommitmentTX`, which will provide the commitment transaction, together with the dust and non-dust htlcs for that commitment. We add code to handle this new variant, but refrain from immediately setting it. This will allow downgrades when the variant is set in the future.
1 parent e6267d3 commit ad98735

File tree

2 files changed

+71
-39
lines changed

2 files changed

+71
-39
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,12 @@ pub(crate) enum ChannelMonitorUpdateStep {
544544
to_broadcaster_value_sat: Option<u64>,
545545
to_countersignatory_value_sat: Option<u64>,
546546
},
547+
LatestCounterpartyCommitmentTX {
548+
// The dust and non-dust htlcs for that commitment
549+
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
550+
// Contains only the non-dust htlcs
551+
commitment_tx: CommitmentTransaction,
552+
},
547553
PaymentPreimage {
548554
payment_preimage: PaymentPreimage,
549555
/// If this preimage was from an inbound payment claim, information about the claim should
@@ -571,6 +577,7 @@ impl ChannelMonitorUpdateStep {
571577
match self {
572578
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo",
573579
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo",
580+
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. } => "LatestCounterpartyCommitmentTX",
574581
ChannelMonitorUpdateStep::PaymentPreimage { .. } => "PaymentPreimage",
575582
ChannelMonitorUpdateStep::CommitmentSecret { .. } => "CommitmentSecret",
576583
ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
@@ -609,6 +616,10 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
609616
(5, ShutdownScript) => {
610617
(0, scriptpubkey, required),
611618
},
619+
(6, LatestCounterpartyCommitmentTX) => {
620+
(0, htlc_outputs, required_vec),
621+
(2, commitment_tx, required),
622+
},
612623
);
613624

614625
/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1019,6 +1030,11 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
10191030
/// Ordering of tuple data: (their_per_commitment_point, feerate_per_kw, to_broadcaster_sats,
10201031
/// to_countersignatory_sats)
10211032
initial_counterparty_commitment_info: Option<(PublicKey, u32, u64, u64)>,
1033+
/// Initial counterparty commitment transaction
1034+
///
1035+
/// We previously used the field above to re-build the counterparty commitment transaction,
1036+
/// we now provide the transaction outright.
1037+
initial_counterparty_commitment_tx: Option<CommitmentTransaction>,
10221038

10231039
/// The first block height at which we had no remaining claimable balances.
10241040
balances_empty_height: Option<u32>,
@@ -1242,6 +1258,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
12421258
(23, self.holder_pays_commitment_tx_fee, option),
12431259
(25, self.payment_preimages, required),
12441260
(27, self.first_confirmed_funding_txo, required),
1261+
(29, self.initial_counterparty_commitment_tx, option),
12451262
});
12461263

12471264
Ok(())
@@ -1454,6 +1471,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
14541471
best_block,
14551472
counterparty_node_id: counterparty_node_id,
14561473
initial_counterparty_commitment_info: None,
1474+
initial_counterparty_commitment_tx: None,
14571475
balances_empty_height: None,
14581476

14591477
failed_back_htlc_ids: new_hash_set(),
@@ -1493,17 +1511,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
14931511
/// This is used to provide the counterparty commitment information directly to the monitor
14941512
/// before the initial persistence of a new channel.
14951513
pub(crate) fn provide_initial_counterparty_commitment_tx<L: Deref>(
1496-
&self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
1497-
commitment_number: u64, their_cur_per_commitment_point: PublicKey, feerate_per_kw: u32,
1498-
to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, logger: &L,
1499-
)
1500-
where L::Target: Logger
1514+
&self, commitment_tx: CommitmentTransaction, logger: &L,
1515+
) where L::Target: Logger
15011516
{
15021517
let mut inner = self.inner.lock().unwrap();
15031518
let logger = WithChannelMonitor::from_impl(logger, &*inner, None);
1504-
inner.provide_initial_counterparty_commitment_tx(txid,
1505-
htlc_outputs, commitment_number, their_cur_per_commitment_point, feerate_per_kw,
1506-
to_broadcaster_value_sat, to_countersignatory_value_sat, &logger);
1519+
inner.provide_initial_counterparty_commitment_tx(commitment_tx, &logger);
15071520
}
15081521

15091522
/// Informs this monitor of the latest counterparty (ie non-broadcastable) commitment transaction.
@@ -2872,20 +2885,21 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
28722885
}
28732886

28742887
fn provide_initial_counterparty_commitment_tx<L: Deref>(
2875-
&mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
2876-
commitment_number: u64, their_per_commitment_point: PublicKey, feerate_per_kw: u32,
2877-
to_broadcaster_value: u64, to_countersignatory_value: u64, logger: &WithChannelMonitor<L>,
2888+
&mut self, commitment_tx: CommitmentTransaction, logger: &WithChannelMonitor<L>,
28782889
) where L::Target: Logger {
2879-
self.initial_counterparty_commitment_info = Some((their_per_commitment_point.clone(),
2880-
feerate_per_kw, to_broadcaster_value, to_countersignatory_value));
2890+
// We populate this field for downgrades
2891+
self.initial_counterparty_commitment_info = Some((commitment_tx.per_commitment_point(),
2892+
commitment_tx.feerate_per_kw(), commitment_tx.to_broadcaster_value_sat(), commitment_tx.to_countersignatory_value_sat()));
28812893

28822894
#[cfg(debug_assertions)] {
28832895
let rebuilt_commitment_tx = self.initial_counterparty_commitment_tx().unwrap();
2884-
debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), txid);
2896+
debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), commitment_tx.trust().txid());
28852897
}
28862898

2887-
self.provide_latest_counterparty_commitment_tx(txid, htlc_outputs, commitment_number,
2888-
their_per_commitment_point, logger);
2899+
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), Vec::new(), commitment_tx.commitment_number(),
2900+
commitment_tx.per_commitment_point(), logger);
2901+
// Soon, we will only populate this field
2902+
self.initial_counterparty_commitment_tx = Some(commitment_tx);
28892903
}
28902904

28912905
fn provide_latest_counterparty_commitment_tx<L: Deref>(
@@ -3223,10 +3237,17 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32233237
if self.lockdown_from_offchain { panic!(); }
32243238
self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone(), &claimed_htlcs, nondust_htlc_sources.clone());
32253239
}
3240+
// Soon we will drop the `LatestCounterpartyCommitmentTXInfo` variant in favor of `LatestCounterpartyCommitmentTX`.
3241+
// For now we just add the code to handle the new updates.
3242+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
32263243
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => {
32273244
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
32283245
self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger)
32293246
},
3247+
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs, commitment_tx } => {
3248+
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
3249+
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), htlc_outputs.clone(), commitment_tx.commitment_number(), commitment_tx.per_commitment_point(), logger)
3250+
},
32303251
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage, payment_info } => {
32313252
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
32323253
self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array()), &payment_preimage, payment_info, broadcaster, &bounded_fee_estimator, logger)
@@ -3289,6 +3310,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32893310
match update {
32903311
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. }
32913312
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. }
3313+
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. }
32923314
|ChannelMonitorUpdateStep::ShutdownScript { .. }
32933315
|ChannelMonitorUpdateStep::CommitmentSecret { .. } =>
32943316
is_pre_close_update = true,
@@ -3419,14 +3441,21 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34193441
}
34203442

34213443
fn initial_counterparty_commitment_tx(&mut self) -> Option<CommitmentTransaction> {
3422-
let (their_per_commitment_point, feerate_per_kw, to_broadcaster_value,
3423-
to_countersignatory_value) = self.initial_counterparty_commitment_info?;
3424-
let htlc_outputs = vec![];
3425-
3426-
let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
3427-
&their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
3428-
feerate_per_kw, htlc_outputs);
3429-
Some(commitment_tx)
3444+
self.initial_counterparty_commitment_tx.clone().or_else(|| {
3445+
// This provides forward compatibility; an old monitor will not contain the full
3446+
// transaction; only enough information to rebuild it
3447+
self.initial_counterparty_commitment_info
3448+
.map(|(their_per_commitment_point, feerate_per_kw, to_broadcaster_value, to_countersignatory_value)| {
3449+
let htlc_outputs = vec![];
3450+
3451+
let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
3452+
&their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
3453+
feerate_per_kw, htlc_outputs);
3454+
// Take the opportunity to populate this recently introduced field
3455+
self.initial_counterparty_commitment_tx = Some(commitment_tx.clone());
3456+
commitment_tx
3457+
})
3458+
})
34303459
}
34313460

34323461
fn build_counterparty_commitment_tx(
@@ -3454,6 +3483,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34543483

34553484
fn counterparty_commitment_txs_from_update(&self, update: &ChannelMonitorUpdate) -> Vec<CommitmentTransaction> {
34563485
update.updates.iter().filter_map(|update| {
3486+
// Soon we will drop the first branch here in favor of the second.
3487+
// In preparation, we just add the second branch without deleting the first.
3488+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
34573489
match update {
34583490
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid,
34593491
ref htlc_outputs, commitment_number, their_per_commitment_point,
@@ -3473,6 +3505,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34733505

34743506
Some(commitment_tx)
34753507
},
3508+
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs: _,
3509+
ref commitment_tx,
3510+
} => {
3511+
Some(commitment_tx.clone())
3512+
},
34763513
_ => None,
34773514
}
34783515
}).collect()
@@ -5043,6 +5080,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50435080
let mut spendable_txids_confirmed = Some(Vec::new());
50445081
let mut counterparty_fulfilled_htlcs = Some(new_hash_map());
50455082
let mut initial_counterparty_commitment_info = None;
5083+
let mut initial_counterparty_commitment_tx = None;
50465084
let mut balances_empty_height = None;
50475085
let mut channel_id = None;
50485086
let mut holder_pays_commitment_tx_fee = None;
@@ -5063,6 +5101,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50635101
(23, holder_pays_commitment_tx_fee, option),
50645102
(25, payment_preimages_with_info, option),
50655103
(27, first_confirmed_funding_txo, (default_value, funding_info.0)),
5104+
(29, initial_counterparty_commitment_tx, option),
50665105
});
50675106
if let Some(payment_preimages_with_info) = payment_preimages_with_info {
50685107
if payment_preimages_with_info.len() != payment_preimages.len() {
@@ -5166,6 +5205,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
51665205
best_block,
51675206
counterparty_node_id: counterparty_node_id.unwrap(),
51685207
initial_counterparty_commitment_info,
5208+
initial_counterparty_commitment_tx,
51695209
balances_empty_height,
51705210
failed_back_htlc_ids: new_hash_set(),
51715211
})))

lightning/src/ln/channel.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,7 +2053,7 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
20532053

20542054
fn initial_commitment_signed<L: Deref>(
20552055
&mut self, channel_id: ChannelId, counterparty_signature: Signature, holder_commitment_point: &mut HolderCommitmentPoint,
2056-
counterparty_commitment_number: u64, best_block: BestBlock, signer_provider: &SP, logger: &L,
2056+
best_block: BestBlock, signer_provider: &SP, logger: &L,
20572057
) -> Result<(ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>, CommitmentTransaction), ChannelError>
20582058
where
20592059
L::Target: Logger
@@ -2131,14 +2131,7 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
21312131
funding_redeemscript.clone(), funding.get_value_satoshis(),
21322132
obscure_factor,
21332133
holder_commitment_tx, best_block, context.counterparty_node_id, context.channel_id());
2134-
channel_monitor.provide_initial_counterparty_commitment_tx(
2135-
counterparty_initial_bitcoin_tx.txid, Vec::new(),
2136-
counterparty_commitment_number,
2137-
context.counterparty_cur_commitment_point.unwrap(),
2138-
counterparty_initial_commitment_tx.feerate_per_kw(),
2139-
counterparty_initial_commitment_tx.to_broadcaster_value_sat(),
2140-
counterparty_initial_commitment_tx.to_countersignatory_value_sat(),
2141-
logger);
2134+
channel_monitor.provide_initial_counterparty_commitment_tx(counterparty_initial_commitment_tx.clone(), logger);
21422135

21432136
self.context_mut().cur_counterparty_commitment_transaction_number -= 1;
21442137

@@ -5615,8 +5608,7 @@ impl<SP: Deref> FundedChannel<SP> where
56155608
self.context.assert_no_commitment_advancement(holder_commitment_point.transaction_number(), "initial commitment_signed");
56165609

56175610
let (channel_monitor, _) = self.initial_commitment_signed(
5618-
self.context.channel_id(), msg.signature, holder_commitment_point,
5619-
self.context.cur_counterparty_commitment_transaction_number, best_block, signer_provider, logger)?;
5611+
self.context.channel_id(), msg.signature, holder_commitment_point, best_block, signer_provider, logger)?;
56205612
self.holder_commitment_point = *holder_commitment_point;
56215613

56225614
log_info!(logger, "Received initial commitment_signed from peer for channel {}", &self.context.channel_id());
@@ -8542,6 +8534,8 @@ impl<SP: Deref> FundedChannel<SP> where
85428534
self.context.latest_monitor_update_id += 1;
85438535
let monitor_update = ChannelMonitorUpdate {
85448536
update_id: self.context.latest_monitor_update_id,
8537+
// Soon, we will switch this to `LatestCounterpartyCommitmentTX`,
8538+
// and provide the full commit tx instead of the information needed to rebuild it.
85458539
updates: vec![ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo {
85468540
commitment_txid: counterparty_commitment_txid,
85478541
htlc_outputs: htlcs.clone(),
@@ -9264,8 +9258,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
92649258

92659259
let (channel_monitor, _) = match self.initial_commitment_signed(
92669260
self.context.channel_id(), msg.signature,
9267-
&mut holder_commitment_point, self.context.cur_counterparty_commitment_transaction_number,
9268-
best_block, signer_provider, logger
9261+
&mut holder_commitment_point, best_block, signer_provider, logger
92699262
) {
92709263
Ok(channel_monitor) => channel_monitor,
92719264
Err(err) => return Err((self, err)),
@@ -9532,8 +9525,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
95329525

95339526
let (channel_monitor, counterparty_initial_commitment_tx) = match self.initial_commitment_signed(
95349527
ChannelId::v1_from_funding_outpoint(funding_txo), msg.signature,
9535-
&mut holder_commitment_point, self.context.cur_counterparty_commitment_transaction_number,
9536-
best_block, signer_provider, logger
9528+
&mut holder_commitment_point, best_block, signer_provider, logger
95379529
) {
95389530
Ok(channel_monitor) => channel_monitor,
95399531
Err(err) => return Err((self, err)),

0 commit comments

Comments
 (0)