Skip to content

Commit 594ad2a

Browse files
committed
Yield channel close bump events
1 parent 9aa564c commit 594ad2a

File tree

3 files changed

+194
-16
lines changed

3 files changed

+194
-16
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 83 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
//! ChannelMonitors to get out of the HSM and onto monitoring devices.
2222
2323
use bitcoin::blockdata::block::BlockHeader;
24-
use bitcoin::blockdata::transaction::{TxOut,Transaction};
25-
use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
24+
use bitcoin::blockdata::transaction::{OutPoint as BitcoinOutPoint, TxOut, Transaction};
2625
use bitcoin::blockdata::script::{Script, Builder};
2726
use bitcoin::blockdata::opcodes;
2827

@@ -44,13 +43,13 @@ use chain::{BestBlock, WatchedOutput};
4443
use chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
4544
use chain::transaction::{OutPoint, TransactionData};
4645
use chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, Sign, KeysInterface};
47-
use chain::onchaintx::OnchainTxHandler;
46+
use chain::onchaintx::{ClaimEvent, OnchainTxHandler};
4847
use chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
4948
use chain::Filter;
5049
use util::logger::Logger;
5150
use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48, OptionDeserWrapper};
5251
use util::byte_utils;
53-
use util::events::Event;
52+
use util::events::{AnchorDescriptor, CommitmentPendingHTLC, BumpTransaction, Event};
5453

5554
use prelude::*;
5655
use core::{cmp, mem};
@@ -1219,7 +1218,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
12191218
B::Target: BroadcasterInterface,
12201219
L::Target: Logger,
12211220
{
1222-
self.inner.lock().unwrap().broadcast_latest_holder_commitment_txn(broadcaster, logger)
1221+
self.inner.lock().unwrap().broadcast_latest_holder_commitment_txn(broadcaster, logger);
12231222
}
12241223

12251224
/// Updates a ChannelMonitor on the basis of some new information provided by the Channel
@@ -2190,6 +2189,41 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21902189
self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0));
21912190
}
21922191

2192+
fn construct_bump_channel_close_event(
2193+
&self, target_feerate_sat_per_1000_weight: u32, commitment_tx: Transaction, anchor_output_idx: u32,
2194+
) -> Event {
2195+
let commitment_txid = commitment_tx.txid();
2196+
debug_assert_eq!(self.current_holder_commitment_tx.txid, commitment_txid);
2197+
let pending_htlcs = self.current_holder_commitment_tx.htlc_outputs.iter()
2198+
.filter_map(|(htlc, _, _)| {
2199+
if let Some(_) = htlc.transaction_output_index {
2200+
Some(htlc)
2201+
} else {
2202+
None
2203+
}
2204+
})
2205+
.map(|htlc| CommitmentPendingHTLC {
2206+
outbound: htlc.offered,
2207+
amount_sat: htlc.amount_msat / 1000,
2208+
expiry: htlc.cltv_expiry,
2209+
output_index: htlc.transaction_output_index.unwrap(),
2210+
})
2211+
.collect();
2212+
Event::BumpTransaction(BumpTransaction::ChannelClose {
2213+
target_feerate_sat_per_1000_weight,
2214+
commitment_tx,
2215+
anchor_descriptor: AnchorDescriptor {
2216+
channel_keys_id: self.channel_keys_id,
2217+
channel_value_satoshis: self.channel_value_satoshis,
2218+
outpoint: BitcoinOutPoint {
2219+
txid: commitment_txid,
2220+
vout: anchor_output_idx,
2221+
},
2222+
},
2223+
pending_htlcs,
2224+
})
2225+
}
2226+
21932227
pub fn update_monitor<B: Deref, F: Deref, L: Deref>(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: F, logger: &L) -> Result<(), ()>
21942228
where B::Target: BroadcasterInterface,
21952229
F::Target: FeeEstimator,
@@ -2214,6 +2248,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
22142248
panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!");
22152249
}
22162250
let mut ret = Ok(());
2251+
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator);
22172252
for update in updates.updates.iter() {
22182253
match update {
22192254
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs } => {
@@ -2231,7 +2266,6 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
22312266
},
22322267
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => {
22332268
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
2234-
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator);
22352269
self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage, broadcaster, &bounded_fee_estimator, logger)
22362270
},
22372271
ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => {
@@ -2247,6 +2281,25 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
22472281
self.lockdown_from_offchain = true;
22482282
if *should_broadcast {
22492283
self.broadcast_latest_holder_commitment_txn(broadcaster, logger);
2284+
// If the channel supports anchor outputs, we'll need to emit an external
2285+
// event to be consumed such that a child transaction is broadcast with a
2286+
// high enough feerate for the parent commitment transaction to confirm.
2287+
if self.onchain_tx_handler.opt_anchors() {
2288+
let funding_output = HolderFundingOutput::build(
2289+
self.funding_redeemscript.clone(), self.channel_value_satoshis,
2290+
self.onchain_tx_handler.opt_anchors(),
2291+
);
2292+
let best_block_height = self.best_block.height();
2293+
let commitment_package = PackageTemplate::build_package(
2294+
self.funding_info.0.txid.clone(), self.funding_info.0.index as u32,
2295+
PackageSolvingData::HolderFundingOutput(funding_output),
2296+
best_block_height, false, best_block_height,
2297+
);
2298+
self.onchain_tx_handler.update_claims_view(
2299+
&[], vec![commitment_package], best_block_height, best_block_height,
2300+
broadcaster, &bounded_fee_estimator, logger,
2301+
);
2302+
}
22502303
} else if !self.holder_tx_signed {
22512304
log_error!(logger, "You have a toxic holder commitment transaction avaible in channel monitor, read comment in ChannelMonitor::get_latest_holder_commitment_txn to be informed of manual action to take");
22522305
} else {
@@ -2299,6 +2352,17 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
22992352
pub fn get_and_clear_pending_events(&mut self) -> Vec<Event> {
23002353
let mut ret = Vec::new();
23012354
mem::swap(&mut ret, &mut self.pending_events);
2355+
for claim_event in self.onchain_tx_handler.get_and_clear_pending_claim_events().drain(..) {
2356+
match claim_event {
2357+
ClaimEvent::BumpCommitment {
2358+
target_feerate_sat_per_1000_weight, commitment_tx, anchor_output_idx,
2359+
} => {
2360+
ret.push(self.construct_bump_channel_close_event(
2361+
target_feerate_sat_per_1000_weight, commitment_tx, anchor_output_idx,
2362+
));
2363+
},
2364+
}
2365+
}
23022366
ret
23032367
}
23042368

@@ -2880,15 +2944,20 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
28802944
self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0));
28812945
let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
28822946
self.holder_tx_signed = true;
2883-
// Because we're broadcasting a commitment transaction, we should construct the package
2884-
// assuming it gets confirmed in the next block. Sadly, we have code which considers
2885-
// "not yet confirmed" things as discardable, so we cannot do that here.
2886-
let (mut new_outpoints, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height());
2887-
let new_outputs = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, &commitment_tx);
2888-
if !new_outputs.is_empty() {
2889-
watch_outputs.push((self.current_holder_commitment_tx.txid.clone(), new_outputs));
2947+
// We can't broadcast our HTLC transactions while the commitment transaction is
2948+
// unconfirmed. We'll delay doing so until we detect the confirmed commitment in
2949+
// `transactions_confirmed`.
2950+
if !self.onchain_tx_handler.opt_anchors() {
2951+
// Because we're broadcasting a commitment transaction, we should construct the package
2952+
// assuming it gets confirmed in the next block. Sadly, we have code which considers
2953+
// "not yet confirmed" things as discardable, so we cannot do that here.
2954+
let (mut new_outpoints, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height());
2955+
let new_outputs = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, &commitment_tx);
2956+
if !new_outputs.is_empty() {
2957+
watch_outputs.push((self.current_holder_commitment_tx.txid.clone(), new_outputs));
2958+
}
2959+
claimable_outpoints.append(&mut new_outpoints);
28902960
}
2891-
claimable_outpoints.append(&mut new_outpoints);
28922961
}
28932962

28942963
// Find which on-chain events have reached their confirmation threshold.

lightning/src/chain/onchaintx.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use alloc::collections::BTreeMap;
3939
use core::cmp;
4040
use core::convert::TryInto;
4141
use core::ops::Deref;
42-
use core::mem::replace;
42+
use core::mem::{replace, swap};
4343
use bitcoin::hashes::Hash;
4444

4545
const MAX_ALLOC_SIZE: usize = 64*1024;
@@ -164,6 +164,7 @@ impl Writeable for Option<Vec<Option<(usize, Signature)>>> {
164164
}
165165
}
166166

167+
#[derive(PartialEq, Eq, PartialOrd, Ord)]
167168
pub(crate) enum ClaimEvent {
168169
BumpCommitment {
169170
target_feerate_sat_per_1000_weight: u32,
@@ -391,6 +392,14 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
391392
self.holder_commitment.to_broadcaster_value_sat()
392393
}
393394

395+
pub(crate) fn get_and_clear_pending_claim_events(&mut self) -> Vec<ClaimEvent> {
396+
let mut ret = HashMap::new();
397+
swap(&mut ret, &mut self.pending_claim_events);
398+
let mut ret = ret.into_iter().map(|(_, event)| event).collect::<Vec<_>>();
399+
ret.sort_unstable();
400+
ret
401+
}
402+
394403
/// Lightning security model (i.e being able to redeem/timeout HTLC or penalize counterparty
395404
/// onchain) lays on the assumption of claim transactions getting confirmed before timelock
396405
/// expiration (CSV or CLTV following cases). In case of high-fee spikes, claim tx may get stuck

lightning/src/util/events.rs

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use routing::gossip::NetworkUpdate;
2525
use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
2626
use routing::router::{RouteHop, RouteParameters};
2727

28-
use bitcoin::{PackedLockTime, Transaction};
28+
use bitcoin::{PackedLockTime, Transaction, OutPoint};
2929
use bitcoin::blockdata::script::Script;
3030
use bitcoin::hashes::Hash;
3131
use bitcoin::hashes::sha256::Hash as Sha256;
@@ -196,6 +196,94 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCDestination,
196196
}
197197
);
198198

199+
/// A descriptor used to sign for a commitment transaction's anchor output.
200+
#[derive(Clone, Debug)]
201+
pub struct AnchorDescriptor {
202+
/// A unique identifier used along with `channel_value_satoshis` to re-derive the
203+
/// [`InMemorySigner`] required to sign `input`.
204+
///
205+
/// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
206+
pub channel_keys_id: [u8; 32],
207+
/// The value in satoshis of the channel we're attempting to spend the anchor output of. This is
208+
/// used along with `channel_keys_id` to re-derive the [`InMemorySigner`] required to sign
209+
/// `input`.
210+
///
211+
/// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
212+
pub channel_value_satoshis: u64,
213+
/// The transaction input's outpoint corresponding to the commitment transaction's anchor
214+
/// output.
215+
pub outpoint: OutPoint,
216+
}
217+
218+
/// Describes a pending HTLC in a commitment transaction.
219+
#[derive(Clone, Debug)]
220+
pub struct CommitmentPendingHTLC {
221+
/// Whether the pending HTLC originated from LDK.
222+
pub outbound: bool,
223+
/// The amount, in satoshis, of the pending HTLC's output in the commitment transaction.
224+
pub amount_sat: u64,
225+
/// The absolute height in the chain at which the pending HTLC expires and can be claimed back
226+
/// by its originator.
227+
pub expiry: u32,
228+
/// The index of the pending HTLC's output in the commitment transaction.
229+
pub output_index: u32,
230+
}
231+
232+
/// Represents the different types of transactions, originating from LDK, to be bumped.
233+
#[derive(Clone, Debug)]
234+
pub enum BumpTransaction {
235+
/// Indicates that a channel featuring anchors outputs is to be closed by broadcasting the local
236+
/// commitment transaction. Since commitment transactions have a static feerate pre-agreed upon,
237+
/// they may need additional fees to be attached through a child transaction using the popular
238+
/// [Child-Pays-For-Parent](https://bitcoinops.org/en/topics/cpfp) fee bumping technique. This
239+
/// child transaction must include the anchor input described within `anchor_descriptor` along
240+
/// with additional inputs to meet the target feerate. Failure to meet the target feerate
241+
/// decreases the confirmation odds of the transaction package (which includes the commitment
242+
/// and child anchor transactions), possibly resulting in a loss of funds. Once the transaction
243+
/// is constructed, it must be fully signed for and broadcasted by the consumer of the event
244+
/// along with the `commitment_tx` enclosed. Note that the `commitment_tx` must always be
245+
/// broadcast first, as the child anchor transaction depends on it.
246+
///
247+
/// The consumer should be able to sign for any of the additional inputs included within the
248+
/// child anchor transaction. To sign its anchor input, an [`InMemorySigner`] should be
249+
/// re-derived through [`KeysManager::derive_channel_keys`] with the help of
250+
/// [`AnchorDescriptor::channel_keys_id`] and [`AnchorDescriptor::channel_value_satoshis`].
251+
///
252+
/// It is possible to receive more than an instance of this event if a valid child anchor
253+
/// transaction is never broadcast or is but not with a sufficient fee to be mined. Care should
254+
/// be taken by the consumer of the event to ensure any future iterations of the child anchor
255+
/// transaction adhere to the [Replace-By-Fee
256+
/// rules](https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md)
257+
/// for fee bumps to be accepted into the mempool, and eventually the chain. As the frequency of
258+
/// these events is not user-controlled, users may ignore/drop the event if they are no longer
259+
/// to commit external confirmed funds to the child anchor transaction.
260+
///
261+
/// The set of `pending_htlcs` on the commitment transaction to be broadcast can be inspected to
262+
/// determine whether a significant portion of the channel's funds are allocated to HTLCs,
263+
/// enabling users to make their own decisions regarding the importance of the commitment
264+
/// transaction's confirmation. On commitments with no HTLCs (indicated by those with an empty
265+
/// `pending_htlcs`), confirmation of the commitment transaction can be considered to be not
266+
/// urgent.
267+
///
268+
/// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
269+
/// [`KeysManager::derive_channel_keys`]: crate::chain::keysinterface::KeysManager::derive_channel_keys
270+
ChannelClose {
271+
/// The target feerate to use for the child transaction spending the anchor output of the
272+
/// channel's commitment transaction to broadcast and bump the fee of.
273+
target_feerate_sat_per_1000_weight: u32,
274+
/// The channel's commitment transaction to bump the fee of. This transaction should be
275+
/// broadcast along with the anchor transaction constructed as a result of consuming this
276+
/// event.
277+
commitment_tx: Transaction,
278+
/// The descriptor to sign the anchor input of the anchor transaction constructed as a
279+
/// result of consuming this event.
280+
anchor_descriptor: AnchorDescriptor,
281+
/// The set of pending HTLCs on the commitment transaction that need to be resolved once the
282+
/// commitment transaction confirms.
283+
pending_htlcs: Vec<CommitmentPendingHTLC>,
284+
},
285+
}
286+
199287
/// An Event which you should probably take some action in response to.
200288
///
201289
/// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
@@ -602,6 +690,9 @@ pub enum Event {
602690
/// Destination of the HTLC that failed to be processed.
603691
failed_next_destination: HTLCDestination,
604692
},
693+
/// Indicates that a transaction originating from LDK needs to have its fee bumped. This event
694+
/// requires confirmed external funds to be readily available to spend.
695+
BumpTransaction(BumpTransaction),
605696
}
606697

607698
impl Writeable for Event {
@@ -753,6 +844,15 @@ impl Writeable for Event {
753844
(2, failed_next_destination, required),
754845
})
755846
},
847+
&Event::BumpTransaction(ref event)=> {
848+
27u8.write(writer)?;
849+
match event {
850+
// We never write the ChannelClose events as they'll be replayed upon restarting
851+
// anyway if the commitment transaction remains
852+
// unconfirmed.
853+
BumpTransaction::ChannelClose { .. } => {}
854+
}
855+
}
756856
// Note that, going forward, all new events must only write data inside of
757857
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
758858
// data via `write_tlv_fields`.

0 commit comments

Comments
 (0)