@@ -524,14 +524,14 @@ pub struct ProbabilisticScoringFeeParameters {
524
524
/// [`liquidity_offset_half_life`]: ProbabilisticScoringDecayParameters::liquidity_offset_half_life
525
525
pub liquidity_penalty_multiplier_msat : u64 ,
526
526
527
- /// A multiplier used in conjunction with the total amount flowing over a channel and the
528
- /// negative `log10` of the channel's success probability for the payment , as determined by our
529
- /// latest estimates of the channel's liquidity, to determine the amount penalty.
527
+ /// A multiplier used in conjunction with the payment amount and the negative `log10` of the
528
+ /// channel's success probability for the total amount flowing over a channel , as determined by
529
+ /// our latest estimates of the channel's liquidity, to determine the amount penalty.
530
530
///
531
531
/// The purpose of the amount penalty is to avoid having fees dominate the channel cost (i.e.,
532
532
/// fees plus penalty) for large payments. The penalty is computed as the product of this
533
- /// multiplier and `2^20`ths of the amount flowing over this channel , weighted by the negative
534
- /// `log10` of the success probability.
533
+ /// multiplier and `2^20`ths of the payment amount , weighted by the negative `log10` of the
534
+ /// success probability.
535
535
///
536
536
/// `-log10(success_probability) * liquidity_penalty_amount_multiplier_msat * amount_msat / 2^20`
537
537
///
@@ -560,15 +560,14 @@ pub struct ProbabilisticScoringFeeParameters {
560
560
/// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat
561
561
pub historical_liquidity_penalty_multiplier_msat : u64 ,
562
562
563
- /// A multiplier used in conjunction with the total amount flowing over a channel and the
564
- /// negative `log10` of the channel's success probability for the payment , as determined based
565
- /// on the history of our estimates of the channel's available liquidity, to determine a
563
+ /// A multiplier used in conjunction with the payment amount and the negative `log10` of the
564
+ /// channel's success probability for the total amount flowing over a channel , as determined
565
+ /// based on the history of our estimates of the channel's available liquidity, to determine a
566
566
/// penalty.
567
567
///
568
568
/// The purpose of the amount penalty is to avoid having fees dominate the channel cost for
569
569
/// large payments. The penalty is computed as the product of this multiplier and `2^20`ths
570
- /// of the amount flowing over this channel, weighted by the negative `log10` of the success
571
- /// probability.
570
+ /// of the payment amount, weighted by the negative `log10` of the success probability.
572
571
///
573
572
/// This penalty is similar to [`liquidity_penalty_amount_multiplier_msat`], however, instead
574
573
/// of using only our latest estimate for the current liquidity available in the channel, it
@@ -1138,14 +1137,18 @@ impl<L: Deref<Target = u64>, HT: Deref<Target = HistoricalLiquidityTracker>, T:
1138
1137
DirectedChannelLiquidity < L , HT , T > {
1139
1138
/// Returns a liquidity penalty for routing the given HTLC `amount_msat` through the channel in
1140
1139
/// this direction.
1141
- fn penalty_msat ( & self , amount_msat : u64 , score_params : & ProbabilisticScoringFeeParameters ) -> u64 {
1140
+ fn penalty_msat (
1141
+ & self , amount_msat : u64 , inflight_htlc_msat : u64 ,
1142
+ score_params : & ProbabilisticScoringFeeParameters ,
1143
+ ) -> u64 {
1144
+ let total_inflight_amount_msat = amount_msat. saturating_add ( inflight_htlc_msat) ;
1142
1145
let available_capacity = self . capacity_msat ;
1143
1146
let max_liquidity_msat = self . max_liquidity_msat ( ) ;
1144
1147
let min_liquidity_msat = core:: cmp:: min ( self . min_liquidity_msat ( ) , max_liquidity_msat) ;
1145
1148
1146
- let mut res = if amount_msat <= min_liquidity_msat {
1149
+ let mut res = if total_inflight_amount_msat <= min_liquidity_msat {
1147
1150
0
1148
- } else if amount_msat >= max_liquidity_msat {
1151
+ } else if total_inflight_amount_msat >= max_liquidity_msat {
1149
1152
// Equivalent to hitting the else clause below with the amount equal to the effective
1150
1153
// capacity and without any certainty on the liquidity upper bound, plus the
1151
1154
// impossibility penalty.
@@ -1155,8 +1158,10 @@ DirectedChannelLiquidity< L, HT, T> {
1155
1158
score_params. liquidity_penalty_amount_multiplier_msat )
1156
1159
. saturating_add ( score_params. considered_impossible_penalty_msat )
1157
1160
} else {
1158
- let ( numerator, denominator) = success_probability ( amount_msat,
1159
- min_liquidity_msat, max_liquidity_msat, available_capacity, score_params, false ) ;
1161
+ let ( numerator, denominator) = success_probability (
1162
+ total_inflight_amount_msat, min_liquidity_msat, max_liquidity_msat,
1163
+ available_capacity, score_params, false ,
1164
+ ) ;
1160
1165
if denominator - numerator < denominator / PRECISION_LOWER_BOUND_DENOMINATOR {
1161
1166
// If the failure probability is < 1.5625% (as 1 - numerator/denominator < 1/64),
1162
1167
// don't bother trying to use the log approximation as it gets too noisy to be
@@ -1171,7 +1176,7 @@ DirectedChannelLiquidity< L, HT, T> {
1171
1176
}
1172
1177
} ;
1173
1178
1174
- if amount_msat >= available_capacity {
1179
+ if total_inflight_amount_msat >= available_capacity {
1175
1180
// We're trying to send more than the capacity, use a max penalty.
1176
1181
res = res. saturating_add ( Self :: combined_penalty_msat ( amount_msat,
1177
1182
NEGATIVE_LOG10_UPPER_BOUND * 2048 ,
@@ -1184,7 +1189,8 @@ DirectedChannelLiquidity< L, HT, T> {
1184
1189
score_params. historical_liquidity_penalty_amount_multiplier_msat != 0 {
1185
1190
if let Some ( cumulative_success_prob_times_billion) = self . liquidity_history
1186
1191
. calculate_success_probability_times_billion (
1187
- score_params, amount_msat, self . capacity_msat )
1192
+ score_params, total_inflight_amount_msat, self . capacity_msat
1193
+ )
1188
1194
{
1189
1195
let historical_negative_log10_times_2048 =
1190
1196
log_approx:: negative_log10_times_2048 ( cumulative_success_prob_times_billion + 1 , 1024 * 1024 * 1024 ) ;
@@ -1195,8 +1201,10 @@ DirectedChannelLiquidity< L, HT, T> {
1195
1201
// If we don't have any valid points (or, once decayed, we have less than a full
1196
1202
// point), redo the non-historical calculation with no liquidity bounds tracked and
1197
1203
// the historical penalty multipliers.
1198
- let ( numerator, denominator) = success_probability ( amount_msat, 0 ,
1199
- available_capacity, available_capacity, score_params, true ) ;
1204
+ let ( numerator, denominator) = success_probability (
1205
+ total_inflight_amount_msat, 0 , available_capacity, available_capacity,
1206
+ score_params, true ,
1207
+ ) ;
1200
1208
let negative_log10_times_2048 =
1201
1209
log_approx:: negative_log10_times_2048 ( numerator, denominator) ;
1202
1210
res = res. saturating_add ( Self :: combined_penalty_msat ( amount_msat, negative_log10_times_2048,
@@ -1353,13 +1361,12 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreLookUp for Probabilistic
1353
1361
_ => { } ,
1354
1362
}
1355
1363
1356
- let amount_msat = usage. amount_msat . saturating_add ( usage. inflight_htlc_msat ) ;
1357
1364
let capacity_msat = usage. effective_capacity . as_msat ( ) ;
1358
1365
self . channel_liquidities
1359
1366
. get ( scid)
1360
1367
. unwrap_or ( & ChannelLiquidity :: new ( Duration :: ZERO ) )
1361
1368
. as_directed ( & source, & target, capacity_msat)
1362
- . penalty_msat ( amount_msat, score_params)
1369
+ . penalty_msat ( usage . amount_msat , usage . inflight_htlc_msat , score_params)
1363
1370
. saturating_add ( anti_probing_penalty_msat)
1364
1371
. saturating_add ( base_penalty_msat)
1365
1372
}
@@ -3269,7 +3276,7 @@ mod tests {
3269
3276
short_channel_id : 42 ,
3270
3277
} ) ;
3271
3278
3272
- assert_eq ! ( scorer. channel_penalty_msat( & candidate, usage, & params) , 2050 ) ;
3279
+ assert_eq ! ( scorer. channel_penalty_msat( & candidate, usage, & params) , 2048 ) ;
3273
3280
3274
3281
let usage = ChannelUsage {
3275
3282
amount_msat : 1 ,
0 commit comments