lightning/util/
anchor_channel_reserves.rs

1//! Defines anchor channel reserve requirements.
2//!
3//! The Lightning protocol advances the state of the channel based on commitment and HTLC
4//! transactions, which allow each participant to unilaterally close the channel with the correct
5//! state and resolve pending HTLCs on-chain. Originally, these transactions are signed by both
6//! counterparties over the entire transaction and therefore contain a fixed fee, which can be
7//! updated with the `update_fee` message by the funder. However, these fees can lead to
8//! disagreements and can diverge from the prevailing fee rate if a party is disconnected.
9//!
10//! To address these issues, fees are provided exogenously for anchor output channels.
11//! Anchor outputs are negotiated on channel opening to add outputs to each commitment transaction.
12//! These outputs can be spent in a child transaction with additional fees to incentivize the
13//! mining of the parent transaction, this technique is called Child Pays For Parent (CPFP).
14//! Similarly, HTLC transactions will be signed with `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` so
15//! additional inputs and outputs can be added to pay for fees.
16//!
17//! UTXO reserves will therefore be required to supply commitment transactions and HTLC
18//! transactions with fees to be confirmed in a timely manner. If HTLCs are not resolved
19//! appropriately, it can lead to loss of funds of the in-flight HLTCs as mentioned above. Only
20//! partially satisfying UTXO requirements incurs the risk of not being able to resolve a subset of
21//! HTLCs.
22use crate::chain::chaininterface::BroadcasterInterface;
23use crate::chain::chaininterface::FeeEstimator;
24use crate::chain::chainmonitor::ChainMonitor;
25use crate::chain::chainmonitor::Persist;
26use crate::chain::Filter;
27use crate::events::bump_transaction::Utxo;
28use crate::ln::chan_utils::max_htlcs;
29use crate::ln::channelmanager::AChannelManager;
30use crate::prelude::new_hash_set;
31use crate::sign::ecdsa::EcdsaChannelSigner;
32use crate::sign::EntropySource;
33use crate::types::features::ChannelTypeFeatures;
34use crate::util::logger::Logger;
35use bitcoin::constants::WITNESS_SCALE_FACTOR;
36use bitcoin::Amount;
37use bitcoin::FeeRate;
38use bitcoin::Weight;
39use core::cmp::min;
40use core::ops::Deref;
41
42// Transaction weights based on:
43// https://github.com/lightning/bolts/blob/master/03-transactions.md#appendix-a-expected-weights
44const COMMITMENT_TRANSACTION_BASE_WEIGHT: u64 = 900 + 224;
45const COMMITMENT_TRANSACTION_PER_HTLC_WEIGHT: u64 = 172;
46const PER_HTLC_TIMEOUT_WEIGHT: u64 = 666;
47const PER_HTLC_SUCCESS_WEIGHT: u64 = 706;
48
49// The transaction at least contains:
50// - 4 bytes for the version
51// - 4 bytes for the locktime
52// - 1 byte for the number of inputs
53// - 1 byte for the number of outputs
54// - 2 bytes for the witness header
55//   - 1 byte for the flag
56//   - 1 byte for the marker
57const TRANSACTION_BASE_WEIGHT: u64 = (4 + 4 + 1 + 1) * WITNESS_SCALE_FACTOR as u64 + 2;
58
59// A P2WPKH input consists of:
60// - 36 bytes for the previous outpoint:
61//   - 32 bytes transaction hash
62//   - 4 bytes index
63// - 4 bytes for the sequence
64// - 1 byte for the script sig length
65// - the witness:
66//   - 1 byte for witness items count
67//   - 1 byte for the signature length
68//   - 72 bytes for the signature
69//   - 1 byte for the public key length
70//   - 33 bytes for the public key
71const P2WPKH_INPUT_WEIGHT: u64 = (36 + 4 + 1) * WITNESS_SCALE_FACTOR as u64 + (1 + 1 + 72 + 1 + 33);
72
73// A P2WPKH output consists of:
74// - 8 bytes for the output amount
75// - 1 byte for the script length
76// - 22 bytes for the script (OP_0 OP_PUSH20 20 byte public key hash)
77const P2WPKH_OUTPUT_WEIGHT: u64 = (8 + 1 + 22) * WITNESS_SCALE_FACTOR as u64;
78
79// A P2TR key path input consists of:
80// - 36 bytes for the previous outpoint:
81//   - 32 bytes transaction hash
82//   - 4 bytes index
83// - 4 bytes for the sequence
84// - 1 byte for the script sig length
85// - the witness:
86//   - 1 byte for witness items count
87//   - 1 byte for the signature length
88//   - 64 bytes for the Schnorr signature
89const P2TR_KEYPATH_INPUT_WEIGHT: u64 = (36 + 4 + 1) * WITNESS_SCALE_FACTOR as u64 + (1 + 1 + 64);
90// A P2TR output consists of:
91// - 8 bytes for the output amount
92// - 1 byte for the script length
93// - 34 bytes for the script (OP_1 OP_PUSH32 32 byte Schnorr public key)
94const P2TR_OUTPUT_WEIGHT: u64 = (8 + 1 + 34) * WITNESS_SCALE_FACTOR as u64;
95
96// An P2WSH anchor input consists of:
97// - 36 bytes for the previous outpoint:
98//   - 32 bytes transaction hash
99//   - 4 bytes index
100// - 4 bytes for the sequence
101// - 1 byte for the script sig length
102// - the witness:
103//   - 1 byte for witness item count
104//   - 1 byte for signature length
105//   - 72 bytes signature
106//   - 1 byte for script length
107//   - 40 byte script
108//     <pubkey> OP_CHECKSIG OP_IFDUP OP_NOTIF OP_16 OP_CHECKSEQUENCEVERIFY OP_ENDIF
109//     - 33 byte pubkey with 1 byte OP_PUSHBYTES_33.
110//     - 6 1-byte opcodes
111const ANCHOR_INPUT_WEIGHT: u64 = (36 + 4 + 1) * WITNESS_SCALE_FACTOR as u64 + (1 + 1 + 72 + 1 + 40);
112
113fn htlc_success_transaction_weight(context: &AnchorChannelReserveContext) -> u64 {
114	PER_HTLC_SUCCESS_WEIGHT
115		+ if context.taproot_wallet {
116			P2TR_KEYPATH_INPUT_WEIGHT + P2TR_OUTPUT_WEIGHT
117		} else {
118			P2WPKH_INPUT_WEIGHT + P2WPKH_OUTPUT_WEIGHT
119		}
120}
121
122fn htlc_timeout_transaction_weight(context: &AnchorChannelReserveContext) -> u64 {
123	PER_HTLC_TIMEOUT_WEIGHT
124		+ if context.taproot_wallet {
125			P2TR_KEYPATH_INPUT_WEIGHT + P2TR_OUTPUT_WEIGHT
126		} else {
127			P2WPKH_INPUT_WEIGHT + P2WPKH_OUTPUT_WEIGHT
128		}
129}
130
131fn anchor_output_spend_transaction_weight(
132	context: &AnchorChannelReserveContext, input_weight: Weight,
133) -> u64 {
134	TRANSACTION_BASE_WEIGHT
135		+ ANCHOR_INPUT_WEIGHT
136		+ input_weight.to_wu()
137		+ if context.taproot_wallet { P2TR_OUTPUT_WEIGHT } else { P2WPKH_OUTPUT_WEIGHT }
138}
139
140/// Parameters defining the context around the anchor channel reserve requirement calculation.
141#[derive(Clone, Debug, PartialEq, Eq)]
142pub struct AnchorChannelReserveContext {
143	/// An upper bound fee rate estimate used to calculate the anchor channel reserve that is
144	/// sufficient to provide fees for all required transactions.
145	pub upper_bound_fee_rate: FeeRate,
146	/// The expected number of accepted in-flight HTLCs per channel.
147	///
148	/// Note that malicious counterparties can saturate the number of accepted in-flight HTLCs up to
149	/// the maximum prior to forcing a unilateral closure. This estimate can include that case as a
150	/// weighted average, assuming some percentage of channels are controlled by malicious peers and
151	/// have the maximum number of accepted in-flight HTLCs.
152	///
153	/// See [ChannelHandshakeConfig::our_max_accepted_htlcs] to configure the maximum number of
154	/// accepted in-flight HTLCs.
155	///
156	/// [ChannelHandshakeConfig::our_max_accepted_htlcs]: crate::util::config::ChannelHandshakeConfig::our_max_accepted_htlcs
157	pub expected_accepted_htlcs: u16,
158	/// Whether the wallet handling anchor channel reserves creates Taproot P2TR outputs for any new
159	/// outputs, or Segwit P2WPKH outputs otherwise.
160	pub taproot_wallet: bool,
161}
162
163/// A default for the [AnchorChannelReserveContext] parameters is provided as follows:
164/// - The upper bound fee rate is set to the 99th percentile of the median block fee rate since 2019:
165///   ~50 sats/vbyte.
166/// - The number of accepted in-flight HTLCs per channel is set to 10, providing additional margin
167///   above the number seen for a large routing node over a month (average <1, maximum 10
168///   accepted in-flight HTLCS aggregated across all channels).
169/// - The wallet is assumed to be a Segwit wallet.
170impl Default for AnchorChannelReserveContext {
171	fn default() -> Self {
172		AnchorChannelReserveContext {
173			upper_bound_fee_rate: FeeRate::from_sat_per_kwu(50 * 250),
174			expected_accepted_htlcs: 10,
175			taproot_wallet: false,
176		}
177	}
178}
179
180fn get_reserve_per_channel_with_input(
181	context: &AnchorChannelReserveContext, initial_input_weight: Weight,
182) -> Amount {
183	let max_max_htlcs = max_htlcs(&ChannelTypeFeatures::only_static_remote_key());
184	let expected_accepted_htlcs = min(context.expected_accepted_htlcs, max_max_htlcs) as u64;
185	let weight = Weight::from_wu(
186		COMMITMENT_TRANSACTION_BASE_WEIGHT +
187		// Reserves are calculated in terms of accepted HTLCs, as their timeout defines the urgency of
188		// on-chain resolution. Each accepted HTLC is assumed to be forwarded to calculate an upper
189		// bound for the reserve, resulting in `expected_accepted_htlcs` inbound HTLCs and
190		// `expected_accepted_htlcs` outbound HTLCs per channel in aggregate.
191		2 * expected_accepted_htlcs * COMMITMENT_TRANSACTION_PER_HTLC_WEIGHT +
192		anchor_output_spend_transaction_weight(context, initial_input_weight) +
193		// As an upper bound, it is assumed that each HTLC is resolved in a separate transaction.
194		// However, they might be aggregated when possible depending on timelocks and expiries.
195		htlc_success_transaction_weight(context) * expected_accepted_htlcs +
196		htlc_timeout_transaction_weight(context) * expected_accepted_htlcs,
197	);
198	context.upper_bound_fee_rate.fee_wu(weight).unwrap_or(Amount::MAX)
199}
200
201/// Returns the amount that needs to be maintained as a reserve per anchor channel.
202///
203/// This reserve currently needs to be allocated as a disjoint set of at least 1 UTXO per channel,
204/// as claims are not yet aggregated across channels.
205///
206/// To only require 1 UTXO per channel, it is assumed that, on average, transactions are able to
207/// get confirmed within 1 block with [ConfirmationTarget::UrgentOnChainSweep], or that only a
208/// portion of channels will go through unilateral closure at the same time, allowing UTXOs to be
209/// shared. Otherwise, multiple UTXOs would be needed per channel:
210/// - HTLC time-out transactions with different expiries cannot be aggregated. This could result in
211/// many individual transactions that need to be confirmed starting from different, but potentially
212/// sequential block heights.
213/// - If each transaction takes N blocks to confirm, at least N UTXOs per channel are needed to
214/// provide the necessary concurrency.
215///
216/// The returned amount includes the fee to spend a single UTXO of the type indicated by
217/// [AnchorChannelReserveContext::taproot_wallet]. Larger sets of UTXOs with more complex witnesses
218/// will need to include the corresponding fee required to spend them.
219///
220/// [ConfirmationTarget::UrgentOnChainSweep]: crate::chain::chaininterface::ConfirmationTarget::UrgentOnChainSweep
221pub fn get_reserve_per_channel(context: &AnchorChannelReserveContext) -> Amount {
222	get_reserve_per_channel_with_input(
223		context,
224		if context.taproot_wallet {
225			Weight::from_wu(P2TR_KEYPATH_INPUT_WEIGHT)
226		} else {
227			Weight::from_wu(P2WPKH_INPUT_WEIGHT)
228		},
229	)
230}
231
232/// Calculates the number of anchor channels that can be supported by the reserve provided
233/// by `utxos`.
234pub fn get_supportable_anchor_channels(
235	context: &AnchorChannelReserveContext, utxos: &[Utxo],
236) -> u64 {
237	// Get the reserve needed per channel, accounting for the actual satisfaction weight below.
238	let reserve_per_channel = get_reserve_per_channel_with_input(context, Weight::ZERO);
239
240	let mut total_fractional_amount = Amount::from_sat(0);
241	let mut num_whole_utxos = 0;
242	for utxo in utxos {
243		let satisfaction_fee = context
244			.upper_bound_fee_rate
245			.fee_wu(Weight::from_wu(utxo.satisfaction_weight))
246			.unwrap_or(Amount::MAX);
247		let amount = utxo.output.value.checked_sub(satisfaction_fee).unwrap_or(Amount::MIN);
248		if amount >= reserve_per_channel {
249			num_whole_utxos += 1;
250		} else {
251			total_fractional_amount =
252				total_fractional_amount.checked_add(amount).unwrap_or(Amount::MAX);
253		}
254	}
255	// We require disjoint sets of UTXOs for the reserve of each channel,
256	// as claims are currently only aggregated per channel.
257	//
258	// A worst-case coin selection is assumed for fractional UTXOs, selecting up to double the
259	// required amount.
260	num_whole_utxos + total_fractional_amount.to_sat() / reserve_per_channel.to_sat() / 2
261}
262
263/// Verifies whether the anchor channel reserve provided by `utxos` is sufficient to support
264/// an additional anchor channel.
265///
266/// This should be verified:
267/// - Before opening a new outbound anchor channel with [ChannelManager::create_channel].
268/// - Before accepting a new inbound anchor channel while handling [Event::OpenChannelRequest].
269///
270/// [ChannelManager::create_channel]: crate::ln::channelmanager::ChannelManager::create_channel
271/// [Event::OpenChannelRequest]: crate::events::Event::OpenChannelRequest
272pub fn can_support_additional_anchor_channel<
273	AChannelManagerRef: Deref,
274	ChannelSigner: EcdsaChannelSigner,
275	FilterRef: Deref,
276	BroadcasterRef: Deref,
277	EstimatorRef: Deref,
278	LoggerRef: Deref,
279	PersistRef: Deref,
280	EntropySourceRef: Deref,
281	ChainMonitorRef: Deref<
282		Target = ChainMonitor<
283			ChannelSigner,
284			FilterRef,
285			BroadcasterRef,
286			EstimatorRef,
287			LoggerRef,
288			PersistRef,
289			EntropySourceRef,
290		>,
291	>,
292>(
293	context: &AnchorChannelReserveContext, utxos: &[Utxo], a_channel_manager: AChannelManagerRef,
294	chain_monitor: ChainMonitorRef,
295) -> bool
296where
297	AChannelManagerRef::Target: AChannelManager,
298	FilterRef::Target: Filter,
299	BroadcasterRef::Target: BroadcasterInterface,
300	EstimatorRef::Target: FeeEstimator,
301	LoggerRef::Target: Logger,
302	PersistRef::Target: Persist<ChannelSigner>,
303	EntropySourceRef::Target: EntropySource,
304{
305	let mut anchor_channels = new_hash_set();
306	// Calculate the number of in-progress anchor channels by inspecting ChannelMonitors with balance.
307	// This includes channels that are in the process of being resolved on-chain.
308	for channel_id in chain_monitor.list_monitors() {
309		let channel_monitor = if let Ok(channel_monitor) = chain_monitor.get_monitor(channel_id) {
310			channel_monitor
311		} else {
312			continue;
313		};
314		if channel_monitor.channel_type_features().supports_anchors_zero_fee_htlc_tx()
315			&& !channel_monitor.get_claimable_balances().is_empty()
316		{
317			anchor_channels.insert(channel_id);
318		}
319	}
320	// Also include channels that are in the middle of negotiation or anchor channels that don't have
321	// a ChannelMonitor yet.
322	for channel in a_channel_manager.get_cm().list_channels() {
323		if channel.channel_type.map_or(true, |ct| ct.supports_anchors_zero_fee_htlc_tx()) {
324			anchor_channels.insert(channel.channel_id);
325		}
326	}
327	get_supportable_anchor_channels(context, utxos) > anchor_channels.len() as u64
328}
329
330#[cfg(test)]
331mod test {
332	use super::*;
333	use bitcoin::{OutPoint, ScriptBuf, TxOut, Txid};
334	use std::str::FromStr;
335
336	#[test]
337	fn test_get_reserve_per_channel() {
338		// At a 1000 sats/kw, with 4 expected transactions at ~1kw (commitment transaction, anchor
339		// output spend transaction, 2 HTLC transactions), we expect the reserve to be around 4k sats.
340		assert_eq!(
341			get_reserve_per_channel(&AnchorChannelReserveContext {
342				upper_bound_fee_rate: FeeRate::from_sat_per_kwu(1000),
343				expected_accepted_htlcs: 1,
344				taproot_wallet: false,
345			}),
346			Amount::from_sat(4349)
347		);
348	}
349
350	fn make_p2wpkh_utxo(amount: Amount) -> Utxo {
351		Utxo {
352			outpoint: OutPoint {
353				txid: Txid::from_str(
354					"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
355				)
356				.unwrap(),
357				vout: 0,
358			},
359			output: TxOut { value: amount, script_pubkey: ScriptBuf::new() },
360			satisfaction_weight: 1 * 4 + (1 + 1 + 72 + 1 + 33),
361		}
362	}
363
364	#[test]
365	fn test_get_supportable_anchor_channels() {
366		let context = AnchorChannelReserveContext::default();
367		let reserve_per_channel = get_reserve_per_channel(&context);
368		// Only 3 disjoint sets with a value greater than the required reserve can be created.
369		let utxos = vec![
370			make_p2wpkh_utxo(reserve_per_channel * 3 / 2),
371			make_p2wpkh_utxo(reserve_per_channel),
372			make_p2wpkh_utxo(reserve_per_channel * 99 / 100),
373			make_p2wpkh_utxo(reserve_per_channel * 99 / 100),
374			make_p2wpkh_utxo(reserve_per_channel * 20 / 100),
375		];
376		assert_eq!(get_supportable_anchor_channels(&context, utxos.as_slice()), 3);
377	}
378
379	#[test]
380	fn test_anchor_output_spend_transaction_weight() {
381		// Example with smaller signatures:
382		// https://mempool.space/tx/188b0f9f26999a48611dba4e2a88507251eba31f3695d005023de3514cba34bd
383		// DER-encoded ECDSA signatures vary in size and can be 71-73 bytes.
384		assert_eq!(
385			anchor_output_spend_transaction_weight(
386				&AnchorChannelReserveContext { taproot_wallet: false, ..Default::default() },
387				Weight::from_wu(P2WPKH_INPUT_WEIGHT),
388			),
389			717
390		);
391
392		// Example:
393		// https://mempool.space/tx/9c493177e395ec77d9e725e1cfd465c5f06d4a5816dd0274c3a8c2442d854a85
394		assert_eq!(
395			anchor_output_spend_transaction_weight(
396				&AnchorChannelReserveContext { taproot_wallet: true, ..Default::default() },
397				Weight::from_wu(P2TR_KEYPATH_INPUT_WEIGHT),
398			),
399			723
400		);
401	}
402
403	#[test]
404	fn test_htlc_success_transaction_weight() {
405		assert_eq!(
406			htlc_success_transaction_weight(&AnchorChannelReserveContext {
407				taproot_wallet: false,
408				..Default::default()
409			}),
410			1102
411		);
412
413		assert_eq!(
414			htlc_success_transaction_weight(&AnchorChannelReserveContext {
415				taproot_wallet: true,
416				..Default::default()
417			}),
418			1108
419		);
420	}
421
422	#[test]
423	fn test_htlc_timeout_transaction_weight() {
424		// Example with smaller signatures:
425		// https://mempool.space/tx/37185342f9f088bd12376599b245dbc02eb0bb6c4b99568b75a8cd775ddfd1f4
426		assert_eq!(
427			htlc_timeout_transaction_weight(&AnchorChannelReserveContext {
428				taproot_wallet: false,
429				..Default::default()
430			}),
431			1062
432		);
433
434		assert_eq!(
435			htlc_timeout_transaction_weight(&AnchorChannelReserveContext {
436				taproot_wallet: true,
437				..Default::default()
438			}),
439			1068
440		);
441	}
442}