Skip to content

Commit b90a953

Browse files
committed
f Extract initial input weight
1 parent 246ecec commit b90a953

File tree

1 file changed

+39
-31
lines changed

1 file changed

+39
-31
lines changed

lightning/src/util/anchor_channel_reserves.rs

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,13 @@ fn htlc_timeout_transaction_weight(context: &AnchorChannelReserveContext) -> u64
124124
}
125125
}
126126

127-
fn anchor_output_spend_transaction_weight(context: &AnchorChannelReserveContext) -> u64 {
127+
fn anchor_output_spend_transaction_weight(
128+
context: &AnchorChannelReserveContext, input_weight: Weight,
129+
) -> u64 {
128130
TRANSACTION_BASE_WEIGHT
129131
+ ANCHOR_INPUT_WEIGHT
130-
+ if context.taproot_wallet {
131-
P2TR_INPUT_WEIGHT + P2TR_OUTPUT_WEIGHT
132-
} else {
133-
P2WPKH_INPUT_WEIGHT + P2WPKH_OUTPUT_WEIGHT
134-
}
132+
+ input_weight.to_wu()
133+
+ if context.taproot_wallet { P2TR_OUTPUT_WEIGHT } else { P2WPKH_OUTPUT_WEIGHT }
135134
}
136135

137136
/// Parameters defining the context around the anchor channel reserve requirement calculation.
@@ -167,19 +166,17 @@ impl Default for AnchorChannelReserveContext {
167166
}
168167
}
169168

170-
/// Returns the amount that needs to be maintained as a reserve per anchor channel.
171-
///
172-
/// This reserve currently needs to be allocated as a disjoint set of UTXOs per channel,
173-
/// as claims are not yet aggregated across channels.
174-
pub fn get_reserve_per_channel(context: &AnchorChannelReserveContext) -> Amount {
169+
fn get_reserve_per_channel_with_input(
170+
context: &AnchorChannelReserveContext, initial_input_weight: Weight,
171+
) -> Amount {
175172
let weight = Weight::from_wu(
176173
COMMITMENT_TRANSACTION_BASE_WEIGHT +
177174
// Reserves are calculated in terms of accepted HTLCs, as their timeout defines the urgency of
178175
// on-chain resolution. Each accepted HTLC is assumed to be forwarded to calculate an upper
179176
// bound for the reserve, resulting in `expected_accepted_htlcs` inbound HTLCs and
180177
// `expected_accepted_htlcs` outbound HTLCs per channel in aggregate.
181178
2 * (context.expected_accepted_htlcs as u64) * COMMITMENT_TRANSACTION_PER_HTLC_WEIGHT +
182-
anchor_output_spend_transaction_weight(context) +
179+
anchor_output_spend_transaction_weight(context, initial_input_weight) +
183180
// As an upper bound, it is assumed that each HTLC is resolved in a separate transaction.
184181
// However, they might be aggregated when possible depending on timelocks and expiries.
185182
htlc_success_transaction_weight(context) * (context.expected_accepted_htlcs as u64) +
@@ -188,22 +185,33 @@ pub fn get_reserve_per_channel(context: &AnchorChannelReserveContext) -> Amount
188185
context.upper_bound_fee_rate.fee_wu(weight).unwrap_or(Amount::MAX)
189186
}
190187

188+
/// Returns the amount that needs to be maintained as a reserve per anchor channel.
189+
///
190+
/// This reserve currently needs to be allocated as a disjoint set of UTXOs per channel,
191+
/// as claims are not yet aggregated across channels.
192+
///
193+
/// Note that the returned amount assumes that the reserve will be provided by a single UTXO of the
194+
/// type indicated by [AnchorChannelReserveContext::taproot_wallet]. Larger sets of UTXOs with more
195+
/// complex witnesses will require a correspondingly larger reserve due to the weight required to
196+
/// spend them.
197+
pub fn get_reserve_per_channel(context: &AnchorChannelReserveContext) -> Amount {
198+
get_reserve_per_channel_with_input(
199+
context,
200+
if context.taproot_wallet {
201+
Weight::from_wu(P2TR_INPUT_WEIGHT)
202+
} else {
203+
Weight::from_wu(P2WPKH_INPUT_WEIGHT)
204+
},
205+
)
206+
}
207+
191208
/// Calculates the number of anchor channels that can be supported by the reserve provided
192209
/// by `utxos`.
193210
pub fn get_supportable_anchor_channels(
194211
context: &AnchorChannelReserveContext, utxos: &[Utxo],
195212
) -> u64 {
196-
// Get the reserve needed per channel, replacing the fee for an initial spend with the actual value
197-
// below.
198-
let default_satisfaction_fee = context
199-
.upper_bound_fee_rate
200-
.fee_wu(Weight::from_wu(if context.taproot_wallet {
201-
P2TR_INPUT_WEIGHT
202-
} else {
203-
P2WPKH_INPUT_WEIGHT
204-
}))
205-
.unwrap_or(Amount::MAX);
206-
let reserve_per_channel = get_reserve_per_channel(context) - default_satisfaction_fee;
213+
// Get the reserve needed per channel, accounting for the actual satisfaction weight below.
214+
let reserve_per_channel = get_reserve_per_channel_with_input(context, Weight::ZERO);
207215

208216
let mut total_fractional_amount = Amount::from_sat(0);
209217
let mut num_whole_utxos = 0;
@@ -347,20 +355,20 @@ mod test {
347355
// https://mempool.space/tx/188b0f9f26999a48611dba4e2a88507251eba31f3695d005023de3514cba34bd
348356
// DER-encoded ECDSA signatures vary in size and can be 71-73 bytes.
349357
assert_eq!(
350-
anchor_output_spend_transaction_weight(&AnchorChannelReserveContext {
351-
taproot_wallet: false,
352-
..Default::default()
353-
}),
358+
anchor_output_spend_transaction_weight(
359+
&AnchorChannelReserveContext { taproot_wallet: false, ..Default::default() },
360+
Weight::from_wu(P2WPKH_INPUT_WEIGHT),
361+
),
354362
717
355363
);
356364

357365
// Example:
358366
// https://mempool.space/tx/9c493177e395ec77d9e725e1cfd465c5f06d4a5816dd0274c3a8c2442d854a85
359367
assert_eq!(
360-
anchor_output_spend_transaction_weight(&AnchorChannelReserveContext {
361-
taproot_wallet: true,
362-
..Default::default()
363-
}),
368+
anchor_output_spend_transaction_weight(
369+
&AnchorChannelReserveContext { taproot_wallet: true, ..Default::default() },
370+
Weight::from_wu(P2TR_INPUT_WEIGHT),
371+
),
364372
723
365373
);
366374
}

0 commit comments

Comments
 (0)