@@ -477,6 +477,7 @@ where L::Target: Logger {
477477 channel_liquidities : ChannelLiquidities ,
478478}
479479/// ChannelLiquidities contains live and historical liquidity bounds for each channel.
480+ #[ derive( Clone ) ]
480481pub struct ChannelLiquidities ( HashMap < u64 , ChannelLiquidity > ) ;
481482
482483impl ChannelLiquidities {
@@ -522,6 +523,7 @@ impl DerefMut for ChannelLiquidities {
522523 }
523524}
524525
526+ // TODO: Avoid extra level of tlv serialization
525527impl Readable for ChannelLiquidities {
526528 #[ inline]
527529 fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
@@ -533,6 +535,7 @@ impl Readable for ChannelLiquidities {
533535 }
534536}
535537
538+
536539/// Parameters for configuring [`ProbabilisticScorer`].
537540///
538541/// Used to configure base, liquidity, and amount penalties, the sum of which comprises the channel
@@ -860,6 +863,7 @@ impl ProbabilisticScoringDecayParameters {
860863/// first node in the ordering of the channel's counterparties. Thus, swapping the two liquidity
861864/// offset fields gives the opposite direction.
862865#[ repr( C ) ] // Force the fields in memory to be in the order we specify
866+ #[ derive( Clone ) ]
863867pub struct ChannelLiquidity {
864868 /// Lower channel liquidity bound in terms of an offset from zero.
865869 min_liquidity_offset_msat : u64 ,
@@ -1672,16 +1676,34 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreUpdate for Probabilistic
16721676 }
16731677}
16741678
1679+ /// A probabilistic scorer that combines local and external information to score channels.
16751680pub struct CombinedScorer < G : Deref < Target = NetworkGraph < L > > , L : Deref > where L :: Target : Logger {
1676- pub local_only_scorer : ProbabilisticScorer < G , L > ,
1677- pub scorer : ProbabilisticScorer < G , L > ,
1681+ local_only_scorer : ProbabilisticScorer < G , L > ,
1682+ scorer : ProbabilisticScorer < G , L > ,
16781683}
16791684
1680- impl < G : Deref < Target = NetworkGraph < L > > , L : Deref > CombinedScorer < G , L > where L :: Target : Logger {
1681- pub fn merge ( & mut self , external_scores : HashMap < u64 , ChannelLiquidity > ) {
1685+ impl < G : Deref < Target = NetworkGraph < L > > + Clone , L : Deref + Clone > CombinedScorer < G , L > where L :: Target : Logger {
1686+ /// Create a new combined scorer with the given local scorer.
1687+ pub fn new ( local_scorer : ProbabilisticScorer < G , L > ) -> Self {
1688+ let decay_params = local_scorer. decay_params ;
1689+ let network_graph = local_scorer. network_graph . clone ( ) ;
1690+ let logger = local_scorer. logger . clone ( ) ;
1691+ let mut scorer = ProbabilisticScorer :: new ( decay_params, network_graph, logger) ;
1692+
1693+ scorer. channel_liquidities = local_scorer. channel_liquidities . clone ( ) ;
1694+
1695+ Self {
1696+ local_only_scorer : local_scorer,
1697+ scorer : scorer,
1698+ }
1699+ }
1700+
1701+ /// Merge external channel liquidity information into the scorer.
1702+ pub fn merge ( & mut self , external_scores : ChannelLiquidities ) {
16821703 let local_scores = & self . local_only_scorer . channel_liquidities ;
16831704
1684- for ( scid, mut liquidity) in external_scores {
1705+ // For each channel, merge the external liquidity information with the isolated local liquidity information.
1706+ for ( scid, mut liquidity) in external_scores. 0 {
16851707 if let Some ( local_liquidity) = local_scores. get ( & scid) {
16861708 liquidity. merge ( local_liquidity) ;
16871709 }
@@ -1696,7 +1718,7 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreLookUp for CombinedScore
16961718 fn channel_penalty_msat (
16971719 & self , candidate : & CandidateRouteHop , usage : ChannelUsage , score_params : & ProbabilisticScoringFeeParameters
16981720 ) -> u64 {
1699- self . local_only_scorer . channel_penalty_msat ( candidate, usage, score_params)
1721+ self . scorer . channel_penalty_msat ( candidate, usage, score_params)
17001722 }
17011723}
17021724
@@ -3785,6 +3807,36 @@ mod tests {
37853807 assert_eq ! ( scorer. historical_estimated_payment_success_probability( 42 , & target, amount_msat, & params, false ) ,
37863808 Some ( 0.0 ) ) ;
37873809 }
3810+
3811+ #[ test]
3812+ fn combined_scorer ( ) {
3813+ let logger = TestLogger :: new ( ) ;
3814+ let network_graph = network_graph ( & logger) ;
3815+ let params = ProbabilisticScoringFeeParameters :: default ( ) ;
3816+ let mut scorer = ProbabilisticScorer :: new ( ProbabilisticScoringDecayParameters :: default ( ) , & network_graph, & logger) ;
3817+
3818+ scorer. payment_path_failed ( & payment_path_for_amount ( 500 ) , 42 , Duration :: ZERO ) ;
3819+
3820+ let source = source_node_id ( ) ;
3821+
3822+ let base_penalty_msat = params. base_penalty_msat ;
3823+ let usage = ChannelUsage {
3824+ amount_msat : 750 ,
3825+ inflight_htlc_msat : 0 ,
3826+ effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_000 , htlc_maximum_msat : 1_000 } ,
3827+ } ;
3828+ let network_graph = network_graph. read_only ( ) ;
3829+ let channel = network_graph. channel ( 42 ) . unwrap ( ) ;
3830+ let ( info, _) = channel. as_directed_from ( & source) . unwrap ( ) ;
3831+ let candidate = CandidateRouteHop :: PublicHop ( PublicHopCandidate {
3832+ info,
3833+ short_channel_id : 42 ,
3834+ } ) ;
3835+ let penalty = scorer. channel_penalty_msat ( & candidate, usage, & params) ;
3836+ assert_eq ! ( penalty, 100000021275 ) ;
3837+
3838+ }
3839+
37883840}
37893841
37903842#[ cfg( ldk_bench) ]
0 commit comments