Skip to content

Commit a9ca975

Browse files
committed
f Extract initial input weight
1 parent 660f3f0 commit a9ca975

File tree

1 file changed

+40
-32
lines changed

1 file changed

+40
-32
lines changed

lightning/src/util/anchor_channel_reserves.rs

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,13 @@ fn htlc_timeout_transaction_weight(context: &AnchorChannelReserveContext) -> u64
126126
}
127127
}
128128

129-
fn anchor_output_spend_transaction_weight(context: &AnchorChannelReserveContext) -> u64 {
129+
fn anchor_output_spend_transaction_weight(
130+
context: &AnchorChannelReserveContext, input_weight: Weight,
131+
) -> u64 {
130132
TRANSACTION_BASE_WEIGHT
131133
+ ANCHOR_INPUT_WEIGHT
132-
+ if context.taproot_wallet {
133-
P2TR_INPUT_WEIGHT + P2TR_OUTPUT_WEIGHT
134-
} else {
135-
P2WPKH_INPUT_WEIGHT + P2WPKH_OUTPUT_WEIGHT
136-
}
134+
+ input_weight.to_wu()
135+
+ if context.taproot_wallet { P2TR_OUTPUT_WEIGHT } else { P2WPKH_OUTPUT_WEIGHT }
137136
}
138137

139138
/// Parameters defining the context around the anchor channel reserve requirement calculation.
@@ -178,12 +177,8 @@ impl Default for AnchorChannelReserveContext {
178177
}
179178
}
180179

181-
/// Returns the amount that needs to be maintained as a reserve per anchor channel.
182-
///
183-
/// This reserve currently needs to be allocated as a disjoint set of UTXOs per channel,
184-
/// as claims are not yet aggregated across channels.
185-
pub fn get_reserve_per_channel(
186-
context: &AnchorChannelReserveContext,
180+
fn get_reserve_per_channel_with_input(
181+
context: &AnchorChannelReserveContext, initial_input_weight: Weight,
187182
) -> Result<Amount, AnchorChannelReserveError> {
188183
let num_htlcs = min(context.expected_accepted_htlcs, MAX_HTLCS) as u64;
189184
let weight = Weight::from_wu(
@@ -193,7 +188,7 @@ pub fn get_reserve_per_channel(
193188
// bound for the reserve, resulting in `expected_accepted_htlcs` inbound HTLCs and
194189
// `expected_accepted_htlcs` outbound HTLCs per channel in aggregate.
195190
2 * num_htlcs * COMMITMENT_TRANSACTION_PER_HTLC_WEIGHT +
196-
anchor_output_spend_transaction_weight(context) +
191+
anchor_output_spend_transaction_weight(context, initial_input_weight) +
197192
// As an upper bound, it is assumed that each HTLC is resolved in a separate transaction.
198193
// However, they might be aggregated when possible depending on timelocks and expiries.
199194
htlc_success_transaction_weight(context) * num_htlcs +
@@ -202,22 +197,35 @@ pub fn get_reserve_per_channel(
202197
context.upper_bound_fee_rate.fee_wu(weight).ok_or(AnchorChannelReserveError::FeeOverflow)
203198
}
204199

200+
/// Returns the amount that needs to be maintained as a reserve per anchor channel.
201+
///
202+
/// This reserve currently needs to be allocated as a disjoint set of UTXOs per channel,
203+
/// as claims are not yet aggregated across channels.
204+
///
205+
/// Note that the returned amount assumes that the reserve will be provided by a single UTXO of the
206+
/// type indicated by [AnchorChannelReserveContext::taproot_wallet]. Larger sets of UTXOs with more
207+
/// complex witnesses will require a correspondingly larger reserve due to the weight required to
208+
/// spend them.
209+
pub fn get_reserve_per_channel(
210+
context: &AnchorChannelReserveContext,
211+
) -> Result<Amount, AnchorChannelReserveError> {
212+
get_reserve_per_channel_with_input(
213+
context,
214+
if context.taproot_wallet {
215+
Weight::from_wu(P2TR_INPUT_WEIGHT)
216+
} else {
217+
Weight::from_wu(P2WPKH_INPUT_WEIGHT)
218+
},
219+
)
220+
}
221+
205222
/// Calculates the number of anchor channels that can be supported by the reserve provided
206223
/// by `utxos`.
207224
pub fn get_supportable_anchor_channels(
208225
context: &AnchorChannelReserveContext, utxos: &[Utxo],
209226
) -> Result<u64, AnchorChannelReserveError> {
210-
// Get the reserve needed per channel, replacing the fee for an initial spend with the actual value
211-
// below.
212-
let default_satisfaction_fee = context
213-
.upper_bound_fee_rate
214-
.fee_wu(Weight::from_wu(if context.taproot_wallet {
215-
P2TR_INPUT_WEIGHT
216-
} else {
217-
P2WPKH_INPUT_WEIGHT
218-
}))
219-
.ok_or(AnchorChannelReserveError::FeeOverflow)?;
220-
let reserve_per_channel = get_reserve_per_channel(context)? - default_satisfaction_fee;
227+
// Get the reserve needed per channel, accounting for the actual satisfaction weight below.
228+
let reserve_per_channel = get_reserve_per_channel_with_input(context, Weight::ZERO)?;
221229

222230
let mut total_fractional_amount = Amount::from_sat(0);
223231
let mut num_whole_utxos = 0;
@@ -368,20 +376,20 @@ mod test {
368376
// https://mempool.space/tx/188b0f9f26999a48611dba4e2a88507251eba31f3695d005023de3514cba34bd
369377
// DER-encoded ECDSA signatures vary in size and can be 71-73 bytes.
370378
assert_eq!(
371-
anchor_output_spend_transaction_weight(&AnchorChannelReserveContext {
372-
taproot_wallet: false,
373-
..Default::default()
374-
}),
379+
anchor_output_spend_transaction_weight(
380+
&AnchorChannelReserveContext { taproot_wallet: false, ..Default::default() },
381+
Weight::from_wu(P2WPKH_INPUT_WEIGHT),
382+
),
375383
717
376384
);
377385

378386
// Example:
379387
// https://mempool.space/tx/9c493177e395ec77d9e725e1cfd465c5f06d4a5816dd0274c3a8c2442d854a85
380388
assert_eq!(
381-
anchor_output_spend_transaction_weight(&AnchorChannelReserveContext {
382-
taproot_wallet: true,
383-
..Default::default()
384-
}),
389+
anchor_output_spend_transaction_weight(
390+
&AnchorChannelReserveContext { taproot_wallet: true, ..Default::default() },
391+
Weight::from_wu(P2TR_INPUT_WEIGHT),
392+
),
385393
723
386394
);
387395
}

0 commit comments

Comments
 (0)