@@ -475,6 +475,9 @@ where L::Target: Logger {
475
475
network_graph : G ,
476
476
logger : L ,
477
477
channel_liquidities : HashMap < u64 , ChannelLiquidity > ,
478
+ /// The last time we were given via a [`ScoreUpdate`] method. This does not imply that we've
479
+ /// decayed every liquidity bound up to that time.
480
+ last_duration_since_epoch : Duration ,
478
481
}
479
482
480
483
/// Parameters for configuring [`ProbabilisticScorer`].
@@ -637,6 +640,22 @@ pub struct ProbabilisticScoringFeeParameters {
637
640
///
638
641
/// Default value: false
639
642
pub linear_success_probability : bool ,
643
+
644
+ /// In order to ensure we have knowledge for as many paths as possible, when probing it makes
645
+ /// sense to bias away from channels for which we have very recent data.
646
+ ///
647
+ /// This value is a penalty that is applied based on the last time that we updated the bounds
648
+ /// on the available liquidity in a channel. The specified value is the maximum penalty that
649
+ /// will be applied.
650
+ ///
651
+ /// It obviously does not make sense to assign a non-0 value here unless you are using the
652
+ /// pathfinding result for background probing.
653
+ ///
654
+ /// Specifically, the following penalty is applied
655
+ /// `probing_diversity_penalty_msat * max(0, (86400 - current time + last update))^2 / 86400^2` is
656
+ ///
657
+ /// Default value: 0
658
+ pub probing_diversity_penalty_msat : u64 ,
640
659
}
641
660
642
661
impl Default for ProbabilisticScoringFeeParameters {
@@ -652,6 +671,7 @@ impl Default for ProbabilisticScoringFeeParameters {
652
671
historical_liquidity_penalty_multiplier_msat : 10_000 ,
653
672
historical_liquidity_penalty_amount_multiplier_msat : 64 ,
654
673
linear_success_probability : false ,
674
+ probing_diversity_penalty_msat : 0 ,
655
675
}
656
676
}
657
677
}
@@ -706,6 +726,7 @@ impl ProbabilisticScoringFeeParameters {
706
726
anti_probing_penalty_msat : 0 ,
707
727
considered_impossible_penalty_msat : 0 ,
708
728
linear_success_probability : true ,
729
+ probing_diversity_penalty_msat : 0 ,
709
730
}
710
731
}
711
732
}
@@ -823,6 +844,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ProbabilisticScorer<G, L> whe
823
844
network_graph,
824
845
logger,
825
846
channel_liquidities : new_hash_map ( ) ,
847
+ last_duration_since_epoch : Duration :: from_secs ( 0 ) ,
826
848
}
827
849
}
828
850
@@ -1141,7 +1163,7 @@ DirectedChannelLiquidity< L, HT, T> {
1141
1163
/// Returns a liquidity penalty for routing the given HTLC `amount_msat` through the channel in
1142
1164
/// this direction.
1143
1165
fn penalty_msat (
1144
- & self , amount_msat : u64 , inflight_htlc_msat : u64 ,
1166
+ & self , amount_msat : u64 , inflight_htlc_msat : u64 , last_duration_since_epoch : Duration ,
1145
1167
score_params : & ProbabilisticScoringFeeParameters ,
1146
1168
) -> u64 {
1147
1169
let total_inflight_amount_msat = amount_msat. saturating_add ( inflight_htlc_msat) ;
@@ -1216,6 +1238,13 @@ DirectedChannelLiquidity< L, HT, T> {
1216
1238
}
1217
1239
}
1218
1240
1241
+ if score_params. probing_diversity_penalty_msat != 0 {
1242
+ let time_since_update = last_duration_since_epoch. saturating_sub ( * self . last_updated ) ;
1243
+ let mul = Duration :: from_secs ( 60 * 60 * 24 ) . saturating_sub ( time_since_update) . as_secs ( ) ;
1244
+ let penalty = score_params. probing_diversity_penalty_msat . saturating_mul ( mul * mul) ;
1245
+ res = res. saturating_add ( penalty / ( ( 60 * 60 * 24 ) * ( 60 * 60 * 24 ) ) ) ;
1246
+ }
1247
+
1219
1248
res
1220
1249
}
1221
1250
@@ -1365,11 +1394,12 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreLookUp for Probabilistic
1365
1394
}
1366
1395
1367
1396
let capacity_msat = usage. effective_capacity . as_msat ( ) ;
1397
+ let time = self . last_duration_since_epoch ;
1368
1398
self . channel_liquidities
1369
1399
. get ( scid)
1370
1400
. unwrap_or ( & ChannelLiquidity :: new ( Duration :: ZERO ) )
1371
1401
. as_directed ( & source, & target, capacity_msat)
1372
- . penalty_msat ( usage. amount_msat , usage. inflight_htlc_msat , score_params)
1402
+ . penalty_msat ( usage. amount_msat , usage. inflight_htlc_msat , time , score_params)
1373
1403
. saturating_add ( anti_probing_penalty_msat)
1374
1404
. saturating_add ( base_penalty_msat)
1375
1405
}
@@ -1415,6 +1445,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreUpdate for Probabilistic
1415
1445
}
1416
1446
if at_failed_channel { break ; }
1417
1447
}
1448
+ self . last_duration_since_epoch = duration_since_epoch;
1418
1449
}
1419
1450
1420
1451
fn payment_path_successful ( & mut self , path : & Path , duration_since_epoch : Duration ) {
@@ -1442,6 +1473,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreUpdate for Probabilistic
1442
1473
hop. short_channel_id) ;
1443
1474
}
1444
1475
}
1476
+ self . last_duration_since_epoch = duration_since_epoch;
1445
1477
}
1446
1478
1447
1479
fn probe_failed ( & mut self , path : & Path , short_channel_id : u64 , duration_since_epoch : Duration ) {
@@ -1473,6 +1505,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreUpdate for Probabilistic
1473
1505
liquidity. min_liquidity_offset_msat != 0 || liquidity. max_liquidity_offset_msat != 0 ||
1474
1506
liquidity. liquidity_history . has_datapoints ( )
1475
1507
} ) ;
1508
+ self . last_duration_since_epoch = duration_since_epoch;
1476
1509
}
1477
1510
}
1478
1511
@@ -1906,15 +1939,20 @@ ReadableArgs<(ProbabilisticScoringDecayParameters, G, L)> for ProbabilisticScore
1906
1939
r : & mut R , args : ( ProbabilisticScoringDecayParameters , G , L )
1907
1940
) -> Result < Self , DecodeError > {
1908
1941
let ( decay_params, network_graph, logger) = args;
1909
- let mut channel_liquidities = new_hash_map ( ) ;
1942
+ let mut channel_liquidities: HashMap < u64 , ChannelLiquidity > = new_hash_map ( ) ;
1910
1943
read_tlv_fields ! ( r, {
1911
1944
( 0 , channel_liquidities, required) ,
1912
1945
} ) ;
1946
+ let mut last_duration_since_epoch = Duration :: from_secs ( 0 ) ;
1947
+ for ( _, liq) in channel_liquidities. iter ( ) {
1948
+ last_duration_since_epoch = cmp:: max ( last_duration_since_epoch, liq. last_updated ) ;
1949
+ }
1913
1950
Ok ( Self {
1914
1951
decay_params,
1915
1952
network_graph,
1916
1953
logger,
1917
1954
channel_liquidities,
1955
+ last_duration_since_epoch,
1918
1956
} )
1919
1957
}
1920
1958
}
0 commit comments