@@ -15,9 +15,9 @@ use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, PaymentId, P
15
15
use lightning:: ln:: channelmanager:: { PhantomRouteHints , MIN_CLTV_EXPIRY_DELTA } ;
16
16
use lightning:: ln:: inbound_payment:: { create, create_from_hash, ExpandedKey } ;
17
17
use lightning:: ln:: msgs:: LightningError ;
18
- use lightning:: routing:: gossip:: { NetworkGraph , RoutingFees } ;
19
- use lightning:: routing:: router:: { Route , RouteHint , RouteHintHop , RouteParameters , find_route} ;
20
- use lightning:: routing:: scoring:: Score ;
18
+ use lightning:: routing:: gossip:: { NetworkGraph , NodeId , RoutingFees } ;
19
+ use lightning:: routing:: router:: { Route , RouteHint , RouteHintHop , RouteParameters , find_route, RouteHop } ;
20
+ use lightning:: routing:: scoring:: { ChannelUsage , LockableScore , Score } ;
21
21
use lightning:: util:: logger:: Logger ;
22
22
use secp256k1:: PublicKey ;
23
23
use core:: ops:: Deref ;
@@ -440,33 +440,47 @@ fn filter_channels(channels: Vec<ChannelDetails>, min_inbound_capacity_msat: Opt
440
440
}
441
441
442
442
/// A [`Router`] implemented using [`find_route`].
443
- pub struct DefaultRouter < G : Deref < Target = NetworkGraph < L > > , L : Deref > where L :: Target : Logger {
443
+ pub struct DefaultRouter < G : Deref < Target = NetworkGraph < L > > , L : Deref , S : Deref > where
444
+ L :: Target : Logger ,
445
+ S :: Target : for < ' a > LockableScore < ' a > ,
446
+ {
444
447
network_graph : G ,
445
448
logger : L ,
446
449
random_seed_bytes : Mutex < [ u8 ; 32 ] > ,
450
+ scorer : S
447
451
}
448
452
449
- impl < G : Deref < Target = NetworkGraph < L > > , L : Deref > DefaultRouter < G , L > where L :: Target : Logger {
453
+ impl < G : Deref < Target = NetworkGraph < L > > , L : Deref , S : Deref > DefaultRouter < G , L , S > where
454
+ L :: Target : Logger ,
455
+ S :: Target : for < ' a > LockableScore < ' a > ,
456
+ {
450
457
/// Creates a new router using the given [`NetworkGraph`], a [`Logger`], and a randomness source
451
458
/// `random_seed_bytes`.
452
- pub fn new ( network_graph : G , logger : L , random_seed_bytes : [ u8 ; 32 ] ) -> Self {
459
+ pub fn new ( network_graph : G , logger : L , random_seed_bytes : [ u8 ; 32 ] , scorer : S ) -> Self {
453
460
let random_seed_bytes = Mutex :: new ( random_seed_bytes) ;
454
- Self { network_graph, logger, random_seed_bytes }
461
+ Self { network_graph, logger, random_seed_bytes, scorer }
455
462
}
456
463
}
457
464
458
- impl < G : Deref < Target = NetworkGraph < L > > , L : Deref > Router for DefaultRouter < G , L >
459
- where L :: Target : Logger {
460
- fn find_route < S : Score > (
465
+ impl < G : Deref < Target = NetworkGraph < L > > , L : Deref , S : Deref > Router for DefaultRouter < G , L , S > where
466
+ L :: Target : Logger ,
467
+ S :: Target : for < ' a > LockableScore < ' a > ,
468
+ {
469
+ fn find_route (
461
470
& self , payer : & PublicKey , params : & RouteParameters , _payment_hash : & PaymentHash ,
462
- first_hops : Option < & [ & ChannelDetails ] > , scorer : & S
471
+ first_hops : Option < & [ & ChannelDetails ] > , inflight_htlc_map : HashMap < ( u64 , bool ) , u64 >
463
472
) -> Result < Route , LightningError > {
464
473
let random_seed_bytes = {
465
474
let mut locked_random_seed_bytes = self . random_seed_bytes . lock ( ) . unwrap ( ) ;
466
475
* locked_random_seed_bytes = sha256:: Hash :: hash ( & * locked_random_seed_bytes) . into_inner ( ) ;
467
476
* locked_random_seed_bytes
468
477
} ;
469
- find_route ( payer, params, & self . network_graph , first_hops, & * self . logger , scorer, & random_seed_bytes)
478
+
479
+ find_route (
480
+ payer, params, & self . network_graph , first_hops, & * self . logger ,
481
+ & AccountForInFlightHtlcs { scorer : & mut self . scorer . lock ( ) , inflight_htlcs : inflight_htlc_map } ,
482
+ & random_seed_bytes
483
+ )
470
484
}
471
485
}
472
486
@@ -510,6 +524,51 @@ where
510
524
}
511
525
}
512
526
527
+
528
+ /// Used to store information about all the HTLCs that are inflight across all payment attempts
529
+ struct AccountForInFlightHtlcs < ' a , S : Score > {
530
+ scorer : & ' a mut S ,
531
+ /// Maps a channel's short channel id and its direction to the liquidity used up.
532
+ inflight_htlcs : HashMap < ( u64 , bool ) , u64 > ,
533
+ }
534
+
535
+ #[ cfg( c_bindings) ]
536
+ impl < ' a , S : Score > lightning:: util:: ser:: Writeable for AccountForInFlightHtlcs < ' a , S > {
537
+ fn write < W : lightning:: util:: ser:: Writer > ( & self , writer : & mut W ) -> Result < ( ) , std:: io:: Error > { self . scorer . write ( writer) }
538
+ }
539
+
540
+ impl < ' a , S : Score > Score for AccountForInFlightHtlcs < ' a , S > {
541
+ fn channel_penalty_msat ( & self , short_channel_id : u64 , source : & NodeId , target : & NodeId , usage : ChannelUsage ) -> u64 {
542
+ if let Some ( used_liqudity) = self . inflight_htlcs . get ( & ( short_channel_id, source < target) ) {
543
+ let usage = ChannelUsage {
544
+ inflight_htlc_msat : usage. inflight_htlc_msat + used_liqudity,
545
+ ..usage
546
+ } ;
547
+
548
+ self . scorer . channel_penalty_msat ( short_channel_id, source, target, usage)
549
+ } else {
550
+ self . scorer . channel_penalty_msat ( short_channel_id, source, target, usage)
551
+ }
552
+ }
553
+
554
+ fn payment_path_failed ( & mut self , path : & [ & RouteHop ] , short_channel_id : u64 ) {
555
+ self . scorer . payment_path_failed ( path, short_channel_id)
556
+ }
557
+
558
+ fn payment_path_successful ( & mut self , path : & [ & RouteHop ] ) {
559
+ self . scorer . payment_path_successful ( path)
560
+ }
561
+
562
+ fn probe_failed ( & mut self , path : & [ & RouteHop ] , short_channel_id : u64 ) {
563
+ self . scorer . probe_failed ( path, short_channel_id)
564
+ }
565
+
566
+ fn probe_successful ( & mut self , path : & [ & RouteHop ] ) {
567
+ self . scorer . probe_successful ( path)
568
+ }
569
+ }
570
+
571
+
513
572
#[ cfg( test) ]
514
573
mod test {
515
574
use core:: time:: Duration ;
0 commit comments