Skip to content

Commit 05e9da9

Browse files
committed
Track ChannelTransactionParameters in CounterpartyReceivedHTLCOutput
The `ChannelMonitor` and `OnchainTxHandler` have historically been tied together, often tracking some of the same state twice. As we introduce support for splices in the `ChannelMonitor`, we'd like to avoid leaking some of those details to the `OnchainTxHandler`. Ultimately, the `OnchainTxHandler` should stand on its own and support claiming funds from multiple `ChannelMonitor`s, allowing us to save on fees by batching aggregatable claims across multiple in-flight closing channels. Once splices are supported, we may run into cases where we are attempting to claim an output from a specific `FundingScope`, while also having an additional pending `FundingScope` for a splice. If the pending splice confirms over the output claim, we need to cancel the claim and re-offer it with the set of relevant parameters in the new `FundingScope`. This commit tracks the `ChannelTransactionParameters` for the specific `FundingScope` the `CounterpartyReceivedHTLCOutput` claim originated from. This allows us to remove the dependency on `OnchainTxHandler` when obtaining the current `ChannelTransactionParameters` and ensures any alternative state due to splicing does not leak into the `OnchainTxHandler`.
1 parent d87566f commit 05e9da9

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

lightning/src/chain/channelmonitor.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -3895,10 +3895,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38953895
preimage.unwrap(), htlc.clone(), self.channel_type_features().clone()))
38963896
} else {
38973897
PackageSolvingData::CounterpartyReceivedHTLCOutput(
3898-
CounterpartyReceivedHTLCOutput::build(*per_commitment_point,
3899-
self.counterparty_commitment_params.counterparty_delayed_payment_base_key,
3900-
self.counterparty_commitment_params.counterparty_htlc_base_key,
3901-
htlc.clone(), self.channel_type_features().clone()))
3898+
CounterpartyReceivedHTLCOutput::build(
3899+
*per_commitment_point, htlc.clone(),
3900+
self.funding.channel_parameters.clone(),
3901+
)
3902+
)
39023903
};
39033904
let counterparty_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc.cltv_expiry);
39043905
claimable_outpoints.push(counterparty_package);

lightning/src/chain/package.rs

+32-8
Original file line numberDiff line numberDiff line change
@@ -301,16 +301,26 @@ pub(crate) struct CounterpartyReceivedHTLCOutput {
301301
counterparty_htlc_base_key: HtlcBasepoint,
302302
htlc: HTLCOutputInCommitment,
303303
channel_type_features: ChannelTypeFeatures,
304+
channel_parameters: Option<ChannelTransactionParameters>,
304305
}
305306

306307
impl CounterpartyReceivedHTLCOutput {
307-
pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: DelayedPaymentBasepoint, counterparty_htlc_base_key: HtlcBasepoint, htlc: HTLCOutputInCommitment, channel_type_features: ChannelTypeFeatures) -> Self {
308-
CounterpartyReceivedHTLCOutput {
308+
pub(crate) fn build(
309+
per_commitment_point: PublicKey, htlc: HTLCOutputInCommitment,
310+
channel_parameters: ChannelTransactionParameters,
311+
) -> Self {
312+
let directed_params = channel_parameters.as_holder_broadcastable();
313+
let counterparty_keys = directed_params.countersignatory_pubkeys();
314+
let counterparty_delayed_payment_base_key = counterparty_keys.delayed_payment_basepoint;
315+
let counterparty_htlc_base_key = counterparty_keys.htlc_basepoint;
316+
let channel_type_features = channel_parameters.channel_type_features.clone();
317+
Self {
309318
per_commitment_point,
310319
counterparty_delayed_payment_base_key,
311320
counterparty_htlc_base_key,
312321
htlc,
313-
channel_type_features
322+
channel_type_features,
323+
channel_parameters: Some(channel_parameters),
314324
}
315325
}
316326
}
@@ -325,6 +335,7 @@ impl Writeable for CounterpartyReceivedHTLCOutput {
325335
(6, self.htlc, required),
326336
(8, legacy_deserialization_prevention_marker, option),
327337
(9, self.channel_type_features, required),
338+
(11, self.channel_parameters, option), // Added in 0.2.
328339
});
329340
Ok(())
330341
}
@@ -338,6 +349,7 @@ impl Readable for CounterpartyReceivedHTLCOutput {
338349
let mut htlc = RequiredWrapper(None);
339350
let mut _legacy_deserialization_prevention_marker: Option<()> = None;
340351
let mut channel_type_features = None;
352+
let mut channel_parameters = None;
341353

342354
read_tlv_fields!(reader, {
343355
(0, per_commitment_point, required),
@@ -346,16 +358,20 @@ impl Readable for CounterpartyReceivedHTLCOutput {
346358
(6, htlc, required),
347359
(8, _legacy_deserialization_prevention_marker, option),
348360
(9, channel_type_features, option),
361+
(11, channel_parameters, (option: ReadableArgs, None)), // Added in 0.2.
349362
});
350363

351364
verify_channel_type_features(&channel_type_features, None)?;
365+
let channel_type_features =
366+
channel_type_features.unwrap_or(ChannelTypeFeatures::only_static_remote_key());
352367

353368
Ok(Self {
354369
per_commitment_point: per_commitment_point.0.unwrap(),
355370
counterparty_delayed_payment_base_key: counterparty_delayed_payment_base_key.0.unwrap(),
356371
counterparty_htlc_base_key: counterparty_htlc_base_key.0.unwrap(),
357372
htlc: htlc.0.unwrap(),
358-
channel_type_features: channel_type_features.unwrap_or(ChannelTypeFeatures::only_static_remote_key())
373+
channel_type_features,
374+
channel_parameters,
359375
})
360376
}
361377
}
@@ -852,8 +868,8 @@ impl PackageSolvingData {
852868
}
853869
},
854870
PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => {
855-
let directed_parameters =
856-
&onchain_handler.channel_transaction_parameters.as_counterparty_broadcastable();
871+
let channel_parameters = outp.channel_parameters.as_ref().unwrap_or(channel_parameters);
872+
let directed_parameters = channel_parameters.as_counterparty_broadcastable();
857873
debug_assert_eq!(
858874
directed_parameters.broadcaster_pubkeys().delayed_payment_basepoint,
859875
outp.counterparty_delayed_payment_base_key,
@@ -866,7 +882,11 @@ impl PackageSolvingData {
866882
&outp.per_commitment_point, directed_parameters.broadcaster_pubkeys(),
867883
directed_parameters.countersignatory_pubkeys(), &onchain_handler.secp_ctx,
868884
);
869-
let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, &onchain_handler.channel_type_features(), &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
885+
let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(
886+
&outp.htlc, &channel_parameters.channel_type_features,
887+
&chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key,
888+
&chan_keys.revocation_key,
889+
);
870890

871891
if let Ok(sig) = onchain_handler.signer.sign_counterparty_htlc_transaction(channel_parameters, &bumped_tx, i, &outp.htlc.amount_msat / 1000, &outp.per_commitment_point, &outp.htlc, &onchain_handler.secp_ctx) {
872892
let mut ser_sig = sig.serialize_der().to_vec();
@@ -1646,7 +1666,11 @@ mod tests {
16461666
let dumb_point = PublicKey::from_secret_key(&secp_ctx, &dumb_scalar);
16471667
let hash = PaymentHash([1; 32]);
16481668
let htlc = HTLCOutputInCommitment { offered: true, amount_msat: $amt, cltv_expiry: $expiry, payment_hash: hash, transaction_output_index: None };
1649-
PackageSolvingData::CounterpartyReceivedHTLCOutput(CounterpartyReceivedHTLCOutput::build(dumb_point, DelayedPaymentBasepoint::from(dumb_point), HtlcBasepoint::from(dumb_point), htlc, $features))
1669+
let mut channel_parameters = ChannelTransactionParameters::test_dummy(0);
1670+
channel_parameters.channel_type_features = $features;
1671+
PackageSolvingData::CounterpartyReceivedHTLCOutput(
1672+
CounterpartyReceivedHTLCOutput::build(dumb_point, htlc, channel_parameters)
1673+
)
16501674
}
16511675
}
16521676
}

0 commit comments

Comments
 (0)