Skip to content

Commit 5959950

Browse files
committed
Track ChannelTransactionParameters in CounterpartyOfferedHTLCOutput
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 `CounterpartyOfferedHTLCOutput` 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 e0b4353 commit 5959950

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

Diff for: lightning/src/chain/channelmonitor.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -3889,10 +3889,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38893889
if preimage.is_some() || !htlc.offered {
38903890
let counterparty_htlc_outp = if htlc.offered {
38913891
PackageSolvingData::CounterpartyOfferedHTLCOutput(
3892-
CounterpartyOfferedHTLCOutput::build(*per_commitment_point,
3893-
self.counterparty_commitment_params.counterparty_delayed_payment_base_key,
3894-
self.counterparty_commitment_params.counterparty_htlc_base_key,
3895-
preimage.unwrap(), htlc.clone(), self.channel_type_features().clone()))
3892+
CounterpartyOfferedHTLCOutput::build(
3893+
*per_commitment_point, preimage.unwrap(), htlc.clone(),
3894+
self.funding.channel_parameters.clone(),
3895+
)
3896+
)
38963897
} else {
38973898
PackageSolvingData::CounterpartyReceivedHTLCOutput(
38983899
CounterpartyReceivedHTLCOutput::build(

Diff for: lightning/src/chain/package.rs

+28-6
Original file line numberDiff line numberDiff line change
@@ -224,17 +224,27 @@ pub(crate) struct CounterpartyOfferedHTLCOutput {
224224
preimage: PaymentPreimage,
225225
htlc: HTLCOutputInCommitment,
226226
channel_type_features: ChannelTypeFeatures,
227+
channel_parameters: Option<ChannelTransactionParameters>,
227228
}
228229

229230
impl CounterpartyOfferedHTLCOutput {
230-
pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: DelayedPaymentBasepoint, counterparty_htlc_base_key: HtlcBasepoint, preimage: PaymentPreimage, htlc: HTLCOutputInCommitment, channel_type_features: ChannelTypeFeatures) -> Self {
231+
pub(crate) fn build(
232+
per_commitment_point: PublicKey, preimage: PaymentPreimage, htlc: HTLCOutputInCommitment,
233+
channel_parameters: ChannelTransactionParameters,
234+
) -> Self {
235+
let directed_params = channel_parameters.as_counterparty_broadcastable();
236+
let counterparty_keys = directed_params.broadcaster_pubkeys();
237+
let counterparty_delayed_payment_base_key = counterparty_keys.delayed_payment_basepoint;
238+
let counterparty_htlc_base_key = counterparty_keys.htlc_basepoint;
239+
let channel_type_features = channel_parameters.channel_type_features.clone();
231240
CounterpartyOfferedHTLCOutput {
232241
per_commitment_point,
233242
counterparty_delayed_payment_base_key,
234243
counterparty_htlc_base_key,
235244
preimage,
236245
htlc,
237246
channel_type_features,
247+
channel_parameters: Some(channel_parameters),
238248
}
239249
}
240250
}
@@ -250,6 +260,7 @@ impl Writeable for CounterpartyOfferedHTLCOutput {
250260
(8, self.htlc, required),
251261
(10, legacy_deserialization_prevention_marker, option),
252262
(11, self.channel_type_features, required),
263+
(13, self.channel_parameters, option), // Added in 0.2.
253264
});
254265
Ok(())
255266
}
@@ -264,6 +275,7 @@ impl Readable for CounterpartyOfferedHTLCOutput {
264275
let mut htlc = RequiredWrapper(None);
265276
let mut _legacy_deserialization_prevention_marker: Option<()> = None;
266277
let mut channel_type_features = None;
278+
let mut channel_parameters = None;
267279

268280
read_tlv_fields!(reader, {
269281
(0, per_commitment_point, required),
@@ -273,17 +285,21 @@ impl Readable for CounterpartyOfferedHTLCOutput {
273285
(8, htlc, required),
274286
(10, _legacy_deserialization_prevention_marker, option),
275287
(11, channel_type_features, option),
288+
(13, channel_parameters, (option: ReadableArgs, None)), // Added in 0.2.
276289
});
277290

278291
verify_channel_type_features(&channel_type_features, None)?;
292+
let channel_type_features =
293+
channel_type_features.unwrap_or(ChannelTypeFeatures::only_static_remote_key());
279294

280295
Ok(Self {
281296
per_commitment_point: per_commitment_point.0.unwrap(),
282297
counterparty_delayed_payment_base_key: counterparty_delayed_payment_base_key.0.unwrap(),
283298
counterparty_htlc_base_key: counterparty_htlc_base_key.0.unwrap(),
284299
preimage: preimage.0.unwrap(),
285300
htlc: htlc.0.unwrap(),
286-
channel_type_features: channel_type_features.unwrap_or(ChannelTypeFeatures::only_static_remote_key())
301+
channel_type_features,
302+
channel_parameters,
287303
})
288304
}
289305
}
@@ -798,8 +814,8 @@ impl PackageSolvingData {
798814
} else { return false; }
799815
},
800816
PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => {
801-
let directed_parameters =
802-
&onchain_handler.channel_transaction_parameters.as_counterparty_broadcastable();
817+
let channel_parameters = outp.channel_parameters.as_ref().unwrap_or(channel_parameters);
818+
let directed_parameters = channel_parameters.as_counterparty_broadcastable();
803819
debug_assert_eq!(
804820
directed_parameters.broadcaster_pubkeys().delayed_payment_basepoint,
805821
outp.counterparty_delayed_payment_base_key,
@@ -812,7 +828,9 @@ impl PackageSolvingData {
812828
&outp.per_commitment_point, directed_parameters.broadcaster_pubkeys(),
813829
directed_parameters.countersignatory_pubkeys(), &onchain_handler.secp_ctx,
814830
);
815-
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);
831+
let witness_script = chan_utils::get_htlc_redeemscript(
832+
&outp.htlc, &channel_parameters.channel_type_features, &chan_keys,
833+
);
816834

817835
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) {
818836
let mut ser_sig = sig.serialize_der().to_vec();
@@ -1637,7 +1655,11 @@ mod tests {
16371655
let hash = PaymentHash([1; 32]);
16381656
let preimage = PaymentPreimage([2;32]);
16391657
let htlc = HTLCOutputInCommitment { offered: false, amount_msat: $amt, cltv_expiry: 0, payment_hash: hash, transaction_output_index: None };
1640-
PackageSolvingData::CounterpartyOfferedHTLCOutput(CounterpartyOfferedHTLCOutput::build(dumb_point, DelayedPaymentBasepoint::from(dumb_point), HtlcBasepoint::from(dumb_point), preimage, htlc, $features))
1658+
let mut channel_parameters = ChannelTransactionParameters::test_dummy(0);
1659+
channel_parameters.channel_type_features = $features;
1660+
PackageSolvingData::CounterpartyOfferedHTLCOutput(
1661+
CounterpartyOfferedHTLCOutput::build(dumb_point, preimage, htlc, channel_parameters)
1662+
)
16411663
}
16421664
}
16431665
}

0 commit comments

Comments
 (0)