Skip to content

Commit 51b6064

Browse files
committed
Track ChannelTransactionParameters in RevokedHTLCOutput
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 `RevokedHTLCOutput` 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 c631d53 commit 51b6064

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

lightning/src/chain/channelmonitor.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -3762,11 +3762,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37623762
return (claimable_outpoints, to_counterparty_output_info);
37633763
}
37643764
let revk_htlc_outp = RevokedHTLCOutput::build(
3765-
per_commitment_point,
3766-
self.counterparty_commitment_params.counterparty_delayed_payment_base_key,
3767-
self.counterparty_commitment_params.counterparty_htlc_base_key,
3768-
per_commitment_key, htlc.amount_msat / 1000, htlc.clone(),
3769-
self.channel_type_features(),
3765+
per_commitment_point, per_commitment_key, htlc.clone(),
3766+
self.funding.channel_parameters.clone(),
37703767
);
37713768
let counterparty_spendable_height = if htlc.offered {
37723769
htlc.cltv_expiry

lightning/src/chain/package.rs

+31-8
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,32 @@ pub(crate) struct RevokedHTLCOutput {
181181
weight: u64,
182182
amount: u64,
183183
htlc: HTLCOutputInCommitment,
184+
channel_parameters: Option<ChannelTransactionParameters>,
184185
}
185186

186187
impl RevokedHTLCOutput {
187-
pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: DelayedPaymentBasepoint, counterparty_htlc_base_key: HtlcBasepoint, per_commitment_key: SecretKey, amount: u64, htlc: HTLCOutputInCommitment, channel_type_features: &ChannelTypeFeatures) -> Self {
188-
let weight = if htlc.offered { weight_revoked_offered_htlc(channel_type_features) } else { weight_revoked_received_htlc(channel_type_features) };
188+
pub(crate) fn build(
189+
per_commitment_point: PublicKey, per_commitment_key: SecretKey,
190+
htlc: HTLCOutputInCommitment, channel_parameters: ChannelTransactionParameters,
191+
) -> Self {
192+
let weight = if htlc.offered {
193+
weight_revoked_offered_htlc(&channel_parameters.channel_type_features)
194+
} else {
195+
weight_revoked_received_htlc(&channel_parameters.channel_type_features)
196+
};
197+
let directed_params = channel_parameters.as_holder_broadcastable();
198+
let counterparty_keys = directed_params.countersignatory_pubkeys();
199+
let counterparty_delayed_payment_base_key = counterparty_keys.delayed_payment_basepoint;
200+
let counterparty_htlc_base_key = counterparty_keys.htlc_basepoint;
189201
RevokedHTLCOutput {
190202
per_commitment_point,
191203
counterparty_delayed_payment_base_key,
192204
counterparty_htlc_base_key,
193205
per_commitment_key,
194206
weight,
195-
amount,
196-
htlc
207+
amount: htlc.amount_msat / 1000,
208+
htlc,
209+
channel_parameters: Some(channel_parameters),
197210
}
198211
}
199212
}
@@ -206,6 +219,7 @@ impl_writeable_tlv_based!(RevokedHTLCOutput, {
206219
(8, weight, required),
207220
(10, amount, required),
208221
(12, htlc, required),
222+
(13, channel_parameters, (option: ReadableArgs, None)), // Added in 0.2.
209223
});
210224

211225
/// A struct to describe a HTLC output on a counterparty commitment transaction.
@@ -834,8 +848,8 @@ impl PackageSolvingData {
834848
} else { return false; }
835849
},
836850
PackageSolvingData::RevokedHTLCOutput(ref outp) => {
837-
let directed_parameters =
838-
&onchain_handler.channel_transaction_parameters.as_counterparty_broadcastable();
851+
let channel_parameters = outp.channel_parameters.as_ref().unwrap_or(channel_parameters);
852+
let directed_parameters = channel_parameters.as_counterparty_broadcastable();
839853
debug_assert_eq!(
840854
directed_parameters.broadcaster_pubkeys().delayed_payment_basepoint,
841855
outp.counterparty_delayed_payment_base_key,
@@ -848,7 +862,11 @@ impl PackageSolvingData {
848862
&outp.per_commitment_point, directed_parameters.broadcaster_pubkeys(),
849863
directed_parameters.countersignatory_pubkeys(), &onchain_handler.secp_ctx,
850864
);
851-
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);
865+
let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(
866+
&outp.htlc, &channel_parameters.channel_type_features,
867+
&chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key,
868+
&chan_keys.revocation_key,
869+
);
852870
//TODO: should we panic on signer failure ?
853871
if let Ok(sig) = onchain_handler.signer.sign_justice_revoked_htlc(channel_parameters, &bumped_tx, i, outp.amount, &outp.per_commitment_key, &outp.htlc, &onchain_handler.secp_ctx) {
854872
let mut ser_sig = sig.serialize_der().to_vec();
@@ -1673,7 +1691,12 @@ mod tests {
16731691
let dumb_point = PublicKey::from_secret_key(&secp_ctx, &dumb_scalar);
16741692
let hash = PaymentHash([1; 32]);
16751693
let htlc = HTLCOutputInCommitment { offered: false, amount_msat: 1_000_000, cltv_expiry: 0, payment_hash: hash, transaction_output_index: None };
1676-
PackageSolvingData::RevokedHTLCOutput(RevokedHTLCOutput::build(dumb_point, DelayedPaymentBasepoint::from(dumb_point), HtlcBasepoint::from(dumb_point), dumb_scalar, 1_000_000 / 1_000, htlc, &ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies()))
1694+
let mut channel_parameters = ChannelTransactionParameters::test_dummy(0);
1695+
channel_parameters.channel_type_features =
1696+
ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
1697+
PackageSolvingData::RevokedHTLCOutput(RevokedHTLCOutput::build(
1698+
dumb_point, dumb_scalar, htlc, channel_parameters
1699+
))
16771700
}
16781701
}
16791702
}

0 commit comments

Comments
 (0)