Skip to content

Commit 2668642

Browse files
committed
Provide built 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, as this would otherwise double the size of our updates.
1 parent 7188d5b commit 2668642

File tree

2 files changed

+70
-34
lines changed

2 files changed

+70
-34
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 66 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,12 @@ pub(crate) enum ChannelMonitorUpdateStep {
549549
to_broadcaster_value_sat: Option<u64>,
550550
to_countersignatory_value_sat: Option<u64>,
551551
},
552+
LatestCounterpartyCommitmentTX {
553+
// The dust and non-dust htlcs for that commitment
554+
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
555+
// Contains only the non-dust htlcs
556+
commitment_tx: CommitmentTransaction,
557+
},
552558
PaymentPreimage {
553559
payment_preimage: PaymentPreimage,
554560
/// If this preimage was from an inbound payment claim, information about the claim should
@@ -576,6 +582,7 @@ impl ChannelMonitorUpdateStep {
576582
match self {
577583
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo",
578584
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo",
585+
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. } => "LatestCounterpartyCommitmentTX",
579586
ChannelMonitorUpdateStep::PaymentPreimage { .. } => "PaymentPreimage",
580587
ChannelMonitorUpdateStep::CommitmentSecret { .. } => "CommitmentSecret",
581588
ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
@@ -614,6 +621,10 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
614621
(5, ShutdownScript) => {
615622
(0, scriptpubkey, required),
616623
},
624+
(6, LatestCounterpartyCommitmentTX) => {
625+
(0, htlc_outputs, required_vec),
626+
(2, commitment_tx, required),
627+
},
617628
);
618629

619630
/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1024,6 +1035,11 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
10241035
/// Ordering of tuple data: (their_per_commitment_point, feerate_per_kw, to_broadcaster_sats,
10251036
/// to_countersignatory_sats)
10261037
initial_counterparty_commitment_info: Option<(PublicKey, u32, u64, u64)>,
1038+
/// Initial counterparty commitment transaction
1039+
///
1040+
/// We previously used the field above to re-build the counterparty commitment transaction,
1041+
/// we now provide the transaction outright.
1042+
initial_counterparty_commitment_tx: Option<CommitmentTransaction>,
10271043

10281044
/// The first block height at which we had no remaining claimable balances.
10291045
balances_empty_height: Option<u32>,
@@ -1247,6 +1263,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
12471263
(23, self.holder_pays_commitment_tx_fee, option),
12481264
(25, self.payment_preimages, required),
12491265
(27, self.first_confirmed_funding_txo, required),
1266+
(29, self.initial_counterparty_commitment_tx, option),
12501267
});
12511268

12521269
Ok(())
@@ -1458,6 +1475,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
14581475
best_block,
14591476
counterparty_node_id: Some(counterparty_node_id),
14601477
initial_counterparty_commitment_info: None,
1478+
initial_counterparty_commitment_tx: None,
14611479
balances_empty_height: None,
14621480

14631481
failed_back_htlc_ids: new_hash_set(),
@@ -1497,17 +1515,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
14971515
/// This is used to provide the counterparty commitment information directly to the monitor
14981516
/// before the initial persistence of a new channel.
14991517
pub(crate) fn provide_initial_counterparty_commitment_tx<L: Deref>(
1500-
&self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
1501-
commitment_number: u64, their_cur_per_commitment_point: PublicKey, feerate_per_kw: u32,
1502-
to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, logger: &L,
1503-
)
1504-
where L::Target: Logger
1518+
&self, commitment_tx: CommitmentTransaction, logger: &L,
1519+
) where L::Target: Logger
15051520
{
15061521
let mut inner = self.inner.lock().unwrap();
15071522
let logger = WithChannelMonitor::from_impl(logger, &*inner, None);
1508-
inner.provide_initial_counterparty_commitment_tx(txid,
1509-
htlc_outputs, commitment_number, their_cur_per_commitment_point, feerate_per_kw,
1510-
to_broadcaster_value_sat, to_countersignatory_value_sat, &logger);
1523+
inner.provide_initial_counterparty_commitment_tx(commitment_tx, &logger);
15111524
}
15121525

15131526
/// Informs this monitor of the latest counterparty (ie non-broadcastable) commitment transaction.
@@ -2879,20 +2892,21 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
28792892
}
28802893

28812894
fn provide_initial_counterparty_commitment_tx<L: Deref>(
2882-
&mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
2883-
commitment_number: u64, their_per_commitment_point: PublicKey, feerate_per_kw: u32,
2884-
to_broadcaster_value: u64, to_countersignatory_value: u64, logger: &WithChannelMonitor<L>,
2895+
&mut self, commitment_tx: CommitmentTransaction, logger: &WithChannelMonitor<L>,
28852896
) where L::Target: Logger {
2886-
self.initial_counterparty_commitment_info = Some((their_per_commitment_point.clone(),
2887-
feerate_per_kw, to_broadcaster_value, to_countersignatory_value));
2897+
// We populate this field for downgrades
2898+
self.initial_counterparty_commitment_info = Some((commitment_tx.per_commitment_point(),
2899+
commitment_tx.feerate_per_kw(), commitment_tx.to_broadcaster_value_sat(), commitment_tx.to_countersignatory_value_sat()));
28882900

28892901
#[cfg(debug_assertions)] {
28902902
let rebuilt_commitment_tx = self.initial_counterparty_commitment_tx().unwrap();
2891-
debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), txid);
2903+
debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), commitment_tx.trust().txid());
28922904
}
28932905

2894-
self.provide_latest_counterparty_commitment_tx(txid, htlc_outputs, commitment_number,
2895-
their_per_commitment_point, logger);
2906+
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), Vec::new(), commitment_tx.commitment_number(),
2907+
commitment_tx.per_commitment_point(), logger);
2908+
// Soon, we will only populate this field
2909+
self.initial_counterparty_commitment_tx = Some(commitment_tx);
28962910
}
28972911

28982912
fn provide_latest_counterparty_commitment_tx<L: Deref>(
@@ -3238,10 +3252,17 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32383252
if self.lockdown_from_offchain { panic!(); }
32393253
self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone(), &claimed_htlcs, nondust_htlc_sources.clone());
32403254
}
3255+
// Soon we will drop the `LatestCounterpartyCommitmentTXInfo` variant in favor of `LatestCounterpartyCommitmentTX`.
3256+
// For now we just add the code to handle the new updates.
3257+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
32413258
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => {
32423259
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
32433260
self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger)
32443261
},
3262+
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs, commitment_tx } => {
3263+
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
3264+
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), htlc_outputs.clone(), commitment_tx.commitment_number(), commitment_tx.per_commitment_point(), logger)
3265+
},
32453266
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage, payment_info } => {
32463267
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
32473268
self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array()), &payment_preimage, payment_info, broadcaster, &bounded_fee_estimator, logger)
@@ -3304,6 +3325,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33043325
match update {
33053326
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. }
33063327
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. }
3328+
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. }
33073329
|ChannelMonitorUpdateStep::ShutdownScript { .. }
33083330
|ChannelMonitorUpdateStep::CommitmentSecret { .. } =>
33093331
is_pre_close_update = true,
@@ -3440,14 +3462,21 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34403462
}
34413463

34423464
fn initial_counterparty_commitment_tx(&mut self) -> Option<CommitmentTransaction> {
3443-
let (their_per_commitment_point, feerate_per_kw, to_broadcaster_value,
3444-
to_countersignatory_value) = self.initial_counterparty_commitment_info?;
3445-
let htlc_outputs = vec![];
3446-
3447-
let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
3448-
&their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
3449-
feerate_per_kw, htlc_outputs);
3450-
Some(commitment_tx)
3465+
self.initial_counterparty_commitment_tx.clone().or_else(|| {
3466+
// This provides forward compatibility; an old monitor will not contain the full
3467+
// transaction; only enough information to rebuild it
3468+
self.initial_counterparty_commitment_info
3469+
.map(|(their_per_commitment_point, feerate_per_kw, to_broadcaster_value, to_countersignatory_value)| {
3470+
let htlc_outputs = vec![];
3471+
3472+
let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
3473+
&their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
3474+
feerate_per_kw, htlc_outputs);
3475+
// Take the opportunity to populate this recently introduced field
3476+
self.initial_counterparty_commitment_tx = Some(commitment_tx.clone());
3477+
commitment_tx
3478+
})
3479+
})
34513480
}
34523481

34533482
fn build_counterparty_commitment_tx(
@@ -3475,12 +3504,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34753504

34763505
fn counterparty_commitment_txs_from_update(&self, update: &ChannelMonitorUpdate) -> Vec<CommitmentTransaction> {
34773506
update.updates.iter().filter_map(|update| {
3507+
// Soon we will drop the first branch here in favor of the second.
3508+
// In preparation, we just add the second branch without deleting the first.
3509+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
34783510
match update {
34793511
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid,
34803512
ref htlc_outputs, commitment_number, their_per_commitment_point,
34813513
feerate_per_kw: Some(feerate_per_kw),
34823514
to_broadcaster_value_sat: Some(to_broadcaster_value),
3483-
to_countersignatory_value_sat: Some(to_countersignatory_value) } => {
3515+
to_countersignatory_value_sat: Some(to_countersignatory_value)
3516+
} => {
34843517

34853518
let nondust_htlcs = htlc_outputs.iter().filter_map(|(htlc, _)| {
34863519
htlc.transaction_output_index.map(|_| (htlc.clone(), None))
@@ -3494,6 +3527,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34943527

34953528
Some(commitment_tx)
34963529
},
3530+
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs: _,
3531+
ref commitment_tx,
3532+
} => {
3533+
Some(commitment_tx.clone())
3534+
},
34973535
_ => None,
34983536
}
34993537
}).collect()
@@ -5076,6 +5114,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50765114
let mut spendable_txids_confirmed = Some(Vec::new());
50775115
let mut counterparty_fulfilled_htlcs = Some(new_hash_map());
50785116
let mut initial_counterparty_commitment_info = None;
5117+
let mut initial_counterparty_commitment_tx = None;
50795118
let mut balances_empty_height = None;
50805119
let mut channel_id = None;
50815120
let mut holder_pays_commitment_tx_fee = None;
@@ -5096,6 +5135,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50965135
(23, holder_pays_commitment_tx_fee, option),
50975136
(25, payment_preimages_with_info, option),
50985137
(27, first_confirmed_funding_txo, (default_value, funding_info.0)),
5138+
(29, initial_counterparty_commitment_tx, option),
50995139
});
51005140
if let Some(payment_preimages_with_info) = payment_preimages_with_info {
51015141
if payment_preimages_with_info.len() != payment_preimages.len() {
@@ -5192,6 +5232,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
51925232
best_block,
51935233
counterparty_node_id,
51945234
initial_counterparty_commitment_info,
5235+
initial_counterparty_commitment_tx,
51955236
balances_empty_height,
51965237
failed_back_htlc_ids: new_hash_set(),
51975238
})))

lightning/src/ln/channel.rs

Lines changed: 4 additions & 9 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+
_counterparty_commitment_number: u64, 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

@@ -8507,6 +8500,8 @@ impl<SP: Deref> FundedChannel<SP> where
85078500
let monitor_update = ChannelMonitorUpdate {
85088501
update_id: self.context.latest_monitor_update_id,
85098502
counterparty_node_id: Some(self.context.counterparty_node_id),
8503+
// Soon, we will switch this to `LatestCounterpartyCommitmentTX`,
8504+
// and provide the full commit tx instead of the information needed to rebuild it.
85108505
updates: vec![ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo {
85118506
commitment_txid: counterparty_commitment_txid,
85128507
htlc_outputs: htlcs.clone(),

0 commit comments

Comments
 (0)