Skip to content

Commit ca8c728

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 switches to providing the fully built transaction. We take care to make this change both forward and backward compatible, so we still provide the former fields of `LatestCounterpartyCommitmentTXInfo`.
1 parent 1610854 commit ca8c728

File tree

2 files changed

+53
-32
lines changed

2 files changed

+53
-32
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ pub(crate) enum ChannelMonitorUpdateStep {
548548
feerate_per_kw: Option<u32>,
549549
to_broadcaster_value_sat: Option<u64>,
550550
to_countersignatory_value_sat: Option<u64>,
551+
commitment_tx: Option<CommitmentTransaction>,
551552
},
552553
PaymentPreimage {
553554
payment_preimage: PaymentPreimage,
@@ -599,6 +600,7 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
599600
(4, their_per_commitment_point, required),
600601
(5, to_countersignatory_value_sat, option),
601602
(6, htlc_outputs, required_vec),
603+
(7, commitment_tx, option),
602604
},
603605
(2, PaymentPreimage) => {
604606
(0, payment_preimage, required),
@@ -1027,6 +1029,10 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
10271029
/// Ordering of tuple data: (their_per_commitment_point, feerate_per_kw, to_broadcaster_sats,
10281030
/// to_countersignatory_sats)
10291031
initial_counterparty_commitment_info: Option<(PublicKey, u32, u64, u64)>,
1032+
/// Initial counterparty commitment transaction
1033+
///
1034+
/// We previously used the field above to re-build the transaction, we now provide it outright.
1035+
initial_counterparty_commitment_tx: Option<CommitmentTransaction>,
10301036

10311037
/// The first block height at which we had no remaining claimable balances.
10321038
balances_empty_height: Option<u32>,
@@ -1250,6 +1256,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
12501256
(23, self.holder_pays_commitment_tx_fee, option),
12511257
(25, self.payment_preimages, required),
12521258
(27, self.first_confirmed_funding_txo, required),
1259+
(29, self.initial_counterparty_commitment_tx, option),
12531260
});
12541261

12551262
Ok(())
@@ -1461,6 +1468,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
14611468
best_block,
14621469
counterparty_node_id: Some(counterparty_node_id),
14631470
initial_counterparty_commitment_info: None,
1471+
initial_counterparty_commitment_tx: None,
14641472
balances_empty_height: None,
14651473

14661474
failed_back_htlc_ids: new_hash_set(),
@@ -1500,17 +1508,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
15001508
/// This is used to provide the counterparty commitment information directly to the monitor
15011509
/// before the initial persistence of a new channel.
15021510
pub(crate) fn provide_initial_counterparty_commitment_tx<L: Deref>(
1503-
&self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
1504-
commitment_number: u64, their_cur_per_commitment_point: PublicKey, feerate_per_kw: u32,
1505-
to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, logger: &L,
1511+
&self, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
1512+
commitment_tx: CommitmentTransaction, logger: &L,
15061513
)
15071514
where L::Target: Logger
15081515
{
15091516
let mut inner = self.inner.lock().unwrap();
15101517
let logger = WithChannelMonitor::from_impl(logger, &*inner, None);
1511-
inner.provide_initial_counterparty_commitment_tx(txid,
1512-
htlc_outputs, commitment_number, their_cur_per_commitment_point, feerate_per_kw,
1513-
to_broadcaster_value_sat, to_countersignatory_value_sat, &logger);
1518+
inner.provide_initial_counterparty_commitment_tx(htlc_outputs, commitment_tx, &logger);
15141519
}
15151520

15161521
/// Informs this monitor of the latest counterparty (ie non-broadcastable) commitment transaction.
@@ -2878,20 +2883,22 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
28782883
}
28792884

28802885
fn provide_initial_counterparty_commitment_tx<L: Deref>(
2881-
&mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
2882-
commitment_number: u64, their_per_commitment_point: PublicKey, feerate_per_kw: u32,
2883-
to_broadcaster_value: u64, to_countersignatory_value: u64, logger: &WithChannelMonitor<L>,
2886+
&mut self, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
2887+
commitment_tx: CommitmentTransaction, logger: &WithChannelMonitor<L>,
28842888
) where L::Target: Logger {
2885-
self.initial_counterparty_commitment_info = Some((their_per_commitment_point.clone(),
2886-
feerate_per_kw, to_broadcaster_value, to_countersignatory_value));
2889+
// We populate this field for downgrades
2890+
self.initial_counterparty_commitment_info = Some((commitment_tx.per_commitment_point(),
2891+
commitment_tx.feerate_per_kw(), commitment_tx.to_broadcaster_value_sat(), commitment_tx.to_countersignatory_value_sat()));
28872892

28882893
#[cfg(debug_assertions)] {
28892894
let rebuilt_commitment_tx = self.initial_counterparty_commitment_tx().unwrap();
2890-
debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), txid);
2895+
debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), commitment_tx.trust().txid());
28912896
}
28922897

2893-
self.provide_latest_counterparty_commitment_tx(txid, htlc_outputs, commitment_number,
2894-
their_per_commitment_point, logger);
2898+
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), htlc_outputs, commitment_tx.commitment_number(),
2899+
commitment_tx.per_commitment_point(), logger);
2900+
// Soon, we will only populate this field
2901+
self.initial_counterparty_commitment_tx = Some(commitment_tx);
28952902
}
28962903

28972904
fn provide_latest_counterparty_commitment_tx<L: Deref>(
@@ -3442,15 +3449,20 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34423449
ret
34433450
}
34443451

3445-
fn initial_counterparty_commitment_tx(&mut self) -> Option<CommitmentTransaction> {
3446-
let (their_per_commitment_point, feerate_per_kw, to_broadcaster_value,
3447-
to_countersignatory_value) = self.initial_counterparty_commitment_info?;
3448-
let htlc_outputs = vec![];
3452+
fn initial_counterparty_commitment_tx(&self) -> Option<CommitmentTransaction> {
3453+
// This provides forward compatibility; an old monitor will not contain the full transaction; only enough
3454+
// information to rebuild it
3455+
if let Some((their_per_commitment_point, feerate_per_kw, to_broadcaster_value,
3456+
to_countersignatory_value)) = self.initial_counterparty_commitment_info {
3457+
let htlc_outputs = vec![];
34493458

3450-
let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
3451-
&their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
3452-
feerate_per_kw, htlc_outputs);
3453-
Some(commitment_tx)
3459+
let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
3460+
&their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
3461+
feerate_per_kw, htlc_outputs);
3462+
Some(commitment_tx)
3463+
} else {
3464+
self.initial_counterparty_commitment_tx.clone()
3465+
}
34543466
}
34553467

34563468
fn build_counterparty_commitment_tx(
@@ -3479,11 +3491,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34793491
fn counterparty_commitment_txs_from_update(&self, update: &ChannelMonitorUpdate) -> Vec<CommitmentTransaction> {
34803492
update.updates.iter().filter_map(|update| {
34813493
match update {
3494+
// Provided for forward compatibility; old updates won't contain the full transaction
34823495
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid,
34833496
ref htlc_outputs, commitment_number, their_per_commitment_point,
34843497
feerate_per_kw: Some(feerate_per_kw),
34853498
to_broadcaster_value_sat: Some(to_broadcaster_value),
3486-
to_countersignatory_value_sat: Some(to_countersignatory_value) } => {
3499+
to_countersignatory_value_sat: Some(to_countersignatory_value),
3500+
commitment_tx: None } => {
34873501

34883502
let nondust_htlcs = htlc_outputs.iter().filter_map(|(htlc, _)| {
34893503
htlc.transaction_output_index.map(|_| (htlc.clone(), None))
@@ -3497,6 +3511,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34973511

34983512
Some(commitment_tx)
34993513
},
3514+
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid: _,
3515+
htlc_outputs: _, commitment_number: _, their_per_commitment_point: _,
3516+
feerate_per_kw: _,
3517+
to_broadcaster_value_sat: _,
3518+
to_countersignatory_value_sat: _,
3519+
commitment_tx: Some(ref commitment_tx) } => {
3520+
3521+
Some(commitment_tx.clone())
3522+
},
35003523
_ => None,
35013524
}
35023525
}).collect()
@@ -5079,6 +5102,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50795102
let mut spendable_txids_confirmed = Some(Vec::new());
50805103
let mut counterparty_fulfilled_htlcs = Some(new_hash_map());
50815104
let mut initial_counterparty_commitment_info = None;
5105+
let mut initial_counterparty_commitment_tx = None;
50825106
let mut balances_empty_height = None;
50835107
let mut channel_id = None;
50845108
let mut holder_pays_commitment_tx_fee = None;
@@ -5099,6 +5123,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50995123
(23, holder_pays_commitment_tx_fee, option),
51005124
(25, payment_preimages_with_info, option),
51015125
(27, first_confirmed_funding_txo, (default_value, funding_info.0)),
5126+
(29, initial_counterparty_commitment_tx, option),
51025127
});
51035128
if let Some(payment_preimages_with_info) = payment_preimages_with_info {
51045129
if payment_preimages_with_info.len() != payment_preimages.len() {
@@ -5195,6 +5220,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
51955220
best_block,
51965221
counterparty_node_id,
51975222
initial_counterparty_commitment_info,
5223+
initial_counterparty_commitment_tx,
51985224
balances_empty_height,
51995225
failed_back_htlc_ids: new_hash_set(),
52005226
})))

lightning/src/ln/channel.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,7 +1985,7 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
19851985

19861986
fn initial_commitment_signed<L: Deref>(
19871987
&mut self, channel_id: ChannelId, counterparty_signature: Signature, holder_commitment_point: &mut HolderCommitmentPoint,
1988-
counterparty_commitment_number: u64, best_block: BestBlock, signer_provider: &SP, logger: &L,
1988+
_counterparty_commitment_number: u64, best_block: BestBlock, signer_provider: &SP, logger: &L,
19891989
) -> Result<(ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>, CommitmentTransaction), ChannelError>
19901990
where
19911991
L::Target: Logger
@@ -2063,14 +2063,7 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
20632063
funding_redeemscript.clone(), self.funding().channel_value_satoshis,
20642064
obscure_factor,
20652065
holder_commitment_tx, best_block, context.counterparty_node_id, context.channel_id());
2066-
channel_monitor.provide_initial_counterparty_commitment_tx(
2067-
counterparty_initial_bitcoin_tx.txid, Vec::new(),
2068-
counterparty_commitment_number,
2069-
context.counterparty_cur_commitment_point.unwrap(),
2070-
counterparty_initial_commitment_tx.feerate_per_kw(),
2071-
counterparty_initial_commitment_tx.to_broadcaster_value_sat(),
2072-
counterparty_initial_commitment_tx.to_countersignatory_value_sat(),
2073-
logger);
2066+
channel_monitor.provide_initial_counterparty_commitment_tx(Vec::new(), counterparty_initial_commitment_tx.clone(), logger);
20742067

20752068
self.context_mut().cur_counterparty_commitment_transaction_number -= 1;
20762069

@@ -8469,6 +8462,8 @@ impl<SP: Deref> FundedChannel<SP> where
84698462
feerate_per_kw: Some(counterparty_commitment_tx.feerate_per_kw()),
84708463
to_broadcaster_value_sat: Some(counterparty_commitment_tx.to_broadcaster_value_sat()),
84718464
to_countersignatory_value_sat: Some(counterparty_commitment_tx.to_countersignatory_value_sat()),
8465+
// This is everything we need, but we still provide all the above fields for downgrades
8466+
commitment_tx: Some(counterparty_commitment_tx),
84728467
}],
84738468
channel_id: Some(self.context.channel_id()),
84748469
};

0 commit comments

Comments
 (0)