Skip to content

Commit 7f1cb8e

Browse files
committed
Yield BumpHTLCResolution events
1 parent 9a86016 commit 7f1cb8e

File tree

3 files changed

+154
-10
lines changed

3 files changed

+154
-10
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable,
5353
use crate::util::byte_utils;
5454
use crate::util::events::Event;
5555
#[cfg(anchors)]
56-
use crate::util::events::{AnchorDescriptor, BumpTransactionEvent};
56+
use crate::util::events::{AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent};
5757

5858
use crate::prelude::*;
5959
use core::{cmp, mem};
@@ -2394,7 +2394,27 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23942394
pending_htlcs,
23952395
}));
23962396
},
2397-
_ => {},
2397+
ClaimEvent::BumpHTLC {
2398+
target_feerate_sat_per_1000_weight, htlcs,
2399+
} => {
2400+
let mut htlc_descriptors = Vec::with_capacity(htlcs.len());
2401+
for htlc in htlcs {
2402+
htlc_descriptors.push(HTLCDescriptor {
2403+
channel_keys_id: self.channel_keys_id,
2404+
channel_value_satoshis: self.channel_value_satoshis,
2405+
channel_parameters: self.onchain_tx_handler.channel_transaction_parameters.clone(),
2406+
commitment_txid: htlc.commitment_txid,
2407+
per_commitment_number: htlc.per_commitment_number,
2408+
htlc: htlc.htlc,
2409+
preimage: htlc.preimage,
2410+
counterparty_sig: htlc.counterparty_sig,
2411+
});
2412+
}
2413+
ret.push(Event::BumpTransaction(BumpTransactionEvent::HTLCResolution {
2414+
target_feerate_sat_per_1000_weight,
2415+
htlc_descriptors,
2416+
}));
2417+
}
23982418
}
23992419
}
24002420
ret

lightning/src/ln/chan_utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ impl_writeable_tlv_based!(TxCreationKeys, {
445445
});
446446

447447
/// One counterparty's public keys which do not change over the life of a channel.
448-
#[derive(Clone, PartialEq, Eq)]
448+
#[derive(Clone, Debug, PartialEq, Eq)]
449449
pub struct ChannelPublicKeys {
450450
/// The public key which is used to sign all commitment transactions, as it appears in the
451451
/// on-chain channel lock-in 2-of-2 multisig output.
@@ -794,7 +794,7 @@ pub fn build_anchor_input_witness(funding_key: &PublicKey, funding_sig: &Signatu
794794
///
795795
/// Normally, this is converted to the broadcaster/countersignatory-organized DirectedChannelTransactionParameters
796796
/// before use, via the as_holder_broadcastable and as_counterparty_broadcastable functions.
797-
#[derive(Clone)]
797+
#[derive(Clone, Debug)]
798798
pub struct ChannelTransactionParameters {
799799
/// Holder public keys
800800
pub holder_pubkeys: ChannelPublicKeys,
@@ -818,7 +818,7 @@ pub struct ChannelTransactionParameters {
818818
}
819819

820820
/// Late-bound per-channel counterparty data used to build transactions.
821-
#[derive(Clone)]
821+
#[derive(Clone, Debug)]
822822
pub struct CounterpartyChannelTransactionParameters {
823823
/// Counter-party public keys
824824
pub pubkeys: ChannelPublicKeys,

lightning/src/util/events.rs

Lines changed: 129 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
1717
use crate::chain::keysinterface::SpendableOutputDescriptor;
1818
#[cfg(anchors)]
19-
use crate::ln::chan_utils::HTLCOutputInCommitment;
19+
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment};
2020
use crate::ln::channelmanager::PaymentId;
2121
use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
2222
use crate::ln::features::ChannelTypeFeatures;
@@ -29,11 +29,15 @@ use crate::routing::router::{RouteHop, RouteParameters};
2929

3030
use bitcoin::{PackedLockTime, Transaction};
3131
#[cfg(anchors)]
32-
use bitcoin::OutPoint;
32+
use bitcoin::{OutPoint, Txid, TxIn, TxOut, Witness};
3333
use bitcoin::blockdata::script::Script;
3434
use bitcoin::hashes::Hash;
3535
use bitcoin::hashes::sha256::Hash as Sha256;
3636
use bitcoin::secp256k1::PublicKey;
37+
#[cfg(anchors)]
38+
use bitcoin::secp256k1::{self, Secp256k1};
39+
#[cfg(anchors)]
40+
use bitcoin::secp256k1::ecdsa::Signature;
3741
use crate::io;
3842
use crate::prelude::*;
3943
use core::time::Duration;
@@ -228,6 +232,87 @@ pub struct AnchorDescriptor {
228232
pub outpoint: OutPoint,
229233
}
230234

235+
#[cfg(anchors)]
236+
/// A descriptor used to sign for a commitment transaction's HTLC output.
237+
#[derive(Clone, Debug)]
238+
pub struct HTLCDescriptor {
239+
/// A unique identifier used along with `channel_value_satoshis` to re-derive the
240+
/// [`InMemorySigner`] required to sign `input`.
241+
///
242+
/// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
243+
pub channel_keys_id: [u8; 32],
244+
/// The value in satoshis of the channel we're attempting to spend the anchor output of. This is
245+
/// used along with `channel_keys_id` to re-derive the [`InMemorySigner`] required to sign
246+
/// `input`.
247+
///
248+
/// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
249+
pub channel_value_satoshis: u64,
250+
/// The necessary channel parameters that need to be provided to the re-derived signer.
251+
pub channel_parameters: ChannelTransactionParameters,
252+
/// The txid of the commitment transaction in which the HTLC output lives.
253+
pub commitment_txid: Txid,
254+
/// The number of the commitment transaction in which the HTLC output lives.
255+
pub per_commitment_number: u64,
256+
/// The details of the HTLC as it appears in a commitment transaction.
257+
pub htlc: HTLCOutputInCommitment,
258+
/// The preimage, if one exists, to claim the HTLC output with.
259+
pub preimage: Option<PaymentPreimage>,
260+
/// The counterparty's signature required to spend the HTLC output.
261+
pub counterparty_sig: Signature
262+
}
263+
264+
#[cfg(anchors)]
265+
impl HTLCDescriptor {
266+
pub fn unsigned_tx_input(&self) -> TxIn {
267+
chan_utils::build_htlc_input(&self.commitment_txid, &self.htlc, true /* opt_anchors */)
268+
}
269+
270+
pub fn tx_output<C: secp256k1::Signing + secp256k1::Verification>(
271+
&self, per_commitment_point: &PublicKey, secp: &Secp256k1<C>
272+
) -> Result<TxOut, ()> {
273+
let channel_params = self.channel_parameters.as_holder_broadcastable();
274+
let broadcaster_keys = channel_params.broadcaster_pubkeys();
275+
let counterparty_keys = channel_params.countersignatory_pubkeys();
276+
let broadcaster_delayed_key = chan_utils::derive_public_key(
277+
secp, per_commitment_point, &broadcaster_keys.delayed_payment_basepoint
278+
).map_err(|_| ())?;
279+
let counterparty_revocation_key = chan_utils::derive_public_revocation_key(
280+
secp, per_commitment_point, &counterparty_keys.revocation_basepoint
281+
).map_err(|_| ())?;
282+
Ok(chan_utils::build_htlc_output(
283+
0 /* feerate_per_kw */, channel_params.contest_delay(), &self.htlc, true /* opt_anchors */,
284+
false /* use_non_zero_fee_anchors */, &broadcaster_delayed_key, &counterparty_revocation_key
285+
))
286+
}
287+
288+
pub fn witness_script<C: secp256k1::Signing + secp256k1::Verification>(
289+
&self, per_commitment_point: &PublicKey, secp: &Secp256k1<C>
290+
) -> Result<Script, ()> {
291+
let channel_params = self.channel_parameters.as_holder_broadcastable();
292+
let broadcaster_keys = channel_params.broadcaster_pubkeys();
293+
let counterparty_keys = channel_params.countersignatory_pubkeys();
294+
let broadcaster_htlc_key = chan_utils::derive_public_key(
295+
secp, per_commitment_point, &broadcaster_keys.htlc_basepoint
296+
).map_err(|_| ())?;
297+
let counterparty_htlc_key = chan_utils::derive_public_key(
298+
secp, per_commitment_point, &counterparty_keys.htlc_basepoint
299+
).map_err(|_| ())?;
300+
let counterparty_revocation_key = chan_utils::derive_public_revocation_key(
301+
secp, per_commitment_point, &counterparty_keys.revocation_basepoint
302+
).map_err(|_| ())?;
303+
Ok(chan_utils::get_htlc_redeemscript_with_explicit_keys(
304+
&self.htlc, true /* opt_anchors */, &broadcaster_htlc_key, &counterparty_htlc_key,
305+
&counterparty_revocation_key,
306+
))
307+
}
308+
309+
pub fn tx_input_witness(&self, signature: &Signature, witness_script: &Script) -> Witness {
310+
chan_utils::build_htlc_input_witness(
311+
signature, &self.counterparty_sig, &self.preimage, witness_script, true /* opt_anchors */
312+
)
313+
}
314+
}
315+
231316
#[cfg(anchors)]
232317
/// Represents the different types of transactions, originating from LDK, to be bumped.
233318
#[derive(Clone, Debug)]
@@ -247,7 +332,10 @@ pub enum BumpTransactionEvent {
247332
/// The consumer should be able to sign for any of the additional inputs included within the
248333
/// child anchor transaction. To sign its anchor input, an [`InMemorySigner`] should be
249334
/// re-derived through [`KeysManager::derive_channel_keys`] with the help of
250-
/// [`AnchorDescriptor::channel_keys_id`] and [`AnchorDescriptor::channel_value_satoshis`].
335+
/// [`AnchorDescriptor::channel_keys_id`] and [`AnchorDescriptor::channel_value_satoshis`]. The
336+
/// anchor input signature can be computed with [`InMemorySigner::sign_holder_anchor_input`],
337+
/// which can then be provided to [`build_anchor_input_witness`] along with the `funding_pubkey`
338+
/// to obtain the full witness required to spend.
251339
///
252340
/// It is possible to receive more than one instance of this event if a valid child anchor
253341
/// transaction is never broadcast or is but not with a sufficient fee to be mined. Care should
@@ -268,6 +356,8 @@ pub enum BumpTransactionEvent {
268356
///
269357
/// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
270358
/// [`KeysManager::derive_channel_keys`]: crate::chain::keysinterface::KeysManager::derive_channel_keys
359+
/// [`InMemorySigner::sign_holder_anchor_input`]: crate::chain::keysinterface::InMemorySigner::sign_holder_anchor_input
360+
/// [`build_anchor_input_witness`]: crate::ln::chan_utils::build_anchor_input_witness
271361
ChannelClose {
272362
/// The target feerate that the transaction package, which consists of the commitment
273363
/// transaction and the to-be-crafted child anchor transaction, must meet.
@@ -286,6 +376,39 @@ pub enum BumpTransactionEvent {
286376
/// commitment transaction confirms.
287377
pending_htlcs: Vec<HTLCOutputInCommitment>,
288378
},
379+
/// Indicates that a channel featuring anchor outputs has HTLC(s) that need to be resolved
380+
/// onchain. With the zero-HTLC-transaction-fee variant of anchor outputs, the pre-signed HTLC
381+
/// transactions have a zero fee, thus requiring additional inputs and/or outputs to be attached
382+
/// for a timely confirmation within the chain. These additional inputs and/or outputs must be
383+
/// appended to the enclosed `tx_template` to meet the target feerate. Failure to meet the
384+
/// target feerate decreases the confirmation odds of the transaction, possibly resulting in a
385+
/// loss of funds. Once the transaction is amended to meet the target feerate, it must be signed
386+
/// for and broadcast by the consumer of the event.
387+
///
388+
/// The consumer should be able to sign for any of the additional inputs added to `tx_template`.
389+
/// To sign HTLC inputs, an [`InMemorySigner`] should be re-derived through
390+
/// [`KeysManager::derive_channel_keys`] with the help of `channel_keys_id` and
391+
/// `channel_value_satoshis`. Each HTLC input's signature can be computed with
392+
/// [`InMemorySigner::sign_holder_htlc_transaction`], which can then be provided to
393+
/// [`build_htlc_input_witness`] along with the enclosed [`HTLCDescriptor`] to obtain the full
394+
/// witness required to spend.
395+
///
396+
/// It is possible to receive more than one instance of this event if a valid HTLC transaction
397+
/// is never broadcast or is but not with a sufficient fee to be mined. Care should be taken by
398+
/// the consumer of the event to ensure any future iterations of the HTLC transaction adhere to
399+
/// the [Replace-By-Fee rules](https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md)
400+
/// for fee bumps to be accepted into the mempool, and eventually the chain. As the frequency of
401+
/// these events is not user-controlled, users may ignore/drop the event if they are no longer
402+
/// able to commit external confirmed funds to the HTLC transaction.
403+
///
404+
/// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
405+
/// [`KeysManager::derive_channel_keys`]: crate::chain::keysinterface::KeysManager::derive_channel_keys
406+
/// [`InMemorySigner::sign_holder_htlc_transaction`]: crate::chain::keysinterface::InMemorySigner::sign_holder_htlc_transaction
407+
/// [`build_htlc_input_witness`]: crate::ln::chan_utils::build_htlc_input_witness
408+
HTLCResolution {
409+
target_feerate_sat_per_1000_weight: u32,
410+
htlc_descriptors: Vec<HTLCDescriptor>,
411+
},
289412
}
290413

291414
/// An Event which you should probably take some action in response to.
@@ -890,9 +1013,10 @@ impl Writeable for Event {
8901013
&Event::BumpTransaction(ref event)=> {
8911014
27u8.write(writer)?;
8921015
match event {
893-
// We never write the ChannelClose events as they'll be replayed upon restarting
894-
// anyway if the commitment transaction remains unconfirmed.
1016+
// We never write the ChannelClose|HTLCResolution events as they'll be replayed
1017+
// upon restarting anyway if they remain unresolved.
8951018
BumpTransactionEvent::ChannelClose { .. } => {}
1019+
BumpTransactionEvent::HTLCResolution { .. } => {}
8961020
}
8971021
}
8981022
&Event::ChannelReady { ref channel_id, ref user_channel_id, ref counterparty_node_id, ref channel_type } => {

0 commit comments

Comments
 (0)