@@ -495,30 +495,53 @@ pub trait SimNetwork: Send + Sync {
495
495
}
496
496
497
497
/// A trait for custom pathfinding implementations.
498
- pub trait PathFinder < ' a > : Send + Sync {
498
+ /// Finds a route from the source node to the destination node for the specified amount.
499
+ ///
500
+ /// # Arguments
501
+ /// * `source` - The public key of the node initiating the payment.
502
+ /// * `dest` - The public key of the destination node to receive the payment.
503
+ /// * `amount_msat` - The amount to send in millisatoshis.
504
+ /// * `pathfinding_graph` - The network graph containing channel topology and routing information.
505
+ ///
506
+ /// # Returns
507
+ /// Returns a `Route` containing the payment path, or a `SimulationError` if no route is found.
508
+
509
+ pub trait PathFinder : Send + Sync + Clone {
499
510
fn find_route (
500
511
& self ,
501
512
source : & PublicKey ,
502
513
dest : PublicKey ,
503
514
amount_msat : u64 ,
504
- pathfinding_graph : & NetworkGraph < & ' a WrappedLog > ,
505
- scorer : & ProbabilisticScorer < Arc < NetworkGraph < & ' a WrappedLog > > , & ' a WrappedLog > ,
515
+ pathfinding_graph : & NetworkGraph < & ' static WrappedLog > ,
506
516
) -> Result < Route , SimulationError > ;
507
517
}
508
518
509
- /// Default pathfinder that uses LDK's pathfinding algorithm.
519
+ /// The default pathfinding implementation that uses LDK's built-in pathfinding algorithm.
510
520
#[ derive( Clone ) ]
511
521
pub struct DefaultPathFinder ;
512
522
513
- impl < ' a > PathFinder < ' a > for DefaultPathFinder {
523
+ impl DefaultPathFinder {
524
+ pub fn new ( ) -> Self {
525
+ Self
526
+ }
527
+ }
528
+
529
+ impl PathFinder for DefaultPathFinder {
514
530
fn find_route (
515
531
& self ,
516
532
source : & PublicKey ,
517
533
dest : PublicKey ,
518
534
amount_msat : u64 ,
519
- pathfinding_graph : & NetworkGraph < & ' a WrappedLog > ,
520
- scorer : & ProbabilisticScorer < Arc < NetworkGraph < & ' a WrappedLog > > , & ' a WrappedLog > ,
535
+ pathfinding_graph : & NetworkGraph < & ' static WrappedLog > ,
521
536
) -> Result < Route , SimulationError > {
537
+ let scorer_graph = NetworkGraph :: new ( bitcoin:: Network :: Regtest , & WrappedLog { } ) ;
538
+ let scorer = ProbabilisticScorer :: new (
539
+ ProbabilisticScoringDecayParameters :: default ( ) ,
540
+ Arc :: new ( scorer_graph) ,
541
+ & WrappedLog { } ,
542
+ ) ;
543
+
544
+ // Call LDK's find_route with the scorer (LDK-specific requirement)
522
545
find_route (
523
546
source,
524
547
& RouteParameters {
@@ -529,10 +552,10 @@ impl<'a> PathFinder<'a> for DefaultPathFinder {
529
552
final_value_msat : amount_msat,
530
553
max_total_routing_fee_msat : None ,
531
554
} ,
532
- pathfinding_graph,
555
+ pathfinding_graph, // This is the real network graph used for pathfinding
533
556
None ,
534
557
& WrappedLog { } ,
535
- scorer,
558
+ & scorer, // LDK requires a scorer, so we provide a simple one
536
559
& Default :: default ( ) ,
537
560
& [ 0 ; 32 ] ,
538
561
)
@@ -551,38 +574,25 @@ pub struct SimNode<'a, T: SimNetwork, P: PathFinder<'a> = DefaultPathFinder> {
551
574
/// Tracks the channel that will provide updates for payments by hash.
552
575
in_flight : HashMap < PaymentHash , Receiver < Result < PaymentResult , LightningError > > > ,
553
576
/// A read-only graph used for pathfinding.
554
- pathfinding_graph : Arc < NetworkGraph < & ' a WrappedLog > > ,
555
- /// Probabilistic scorer used to rank paths through the network for routing. This is reused across
556
- /// multiple payments to maintain scoring state.
557
- scorer : ProbabilisticScorer < Arc < NetworkGraph < & ' a WrappedLog > > , & ' a WrappedLog > ,
577
+ pathfinding_graph : Arc < NetworkGraph < & ' static WrappedLog > > ,
558
578
/// The pathfinder implementation to use for finding routes
559
579
pathfinder : P ,
560
580
}
561
581
562
- impl < ' a , T : SimNetwork , P : PathFinder < ' a > > SimNode < ' a , T , P > {
582
+ impl < T : SimNetwork , P : PathFinder > SimNode < T , P > {
563
583
/// Creates a new simulation node that refers to the high level network coordinator provided to process payments
564
584
/// on its behalf. The pathfinding graph is provided separately so that each node can handle its own pathfinding.
565
585
pub fn new (
566
586
pubkey : PublicKey ,
567
587
payment_network : Arc < Mutex < T > > ,
568
- pathfinding_graph : Arc < NetworkGraph < & ' a WrappedLog > > ,
588
+ pathfinding_graph : Arc < NetworkGraph < & ' static WrappedLog > > ,
569
589
pathfinder : P ,
570
590
) -> Self {
571
- // Initialize the probabilistic scorer with default parameters for learning from payment
572
- // history. These parameters control how much successful/failed payments affect routing
573
- // scores and how quickly these scores decay over time.
574
- let scorer = ProbabilisticScorer :: new (
575
- ProbabilisticScoringDecayParameters :: default ( ) ,
576
- pathfinding_graph. clone ( ) ,
577
- & WrappedLog { } ,
578
- ) ;
579
-
580
591
SimNode {
581
592
info : node_info ( pubkey) ,
582
593
network : payment_network,
583
594
in_flight : HashMap :: new ( ) ,
584
595
pathfinding_graph,
585
- scorer,
586
596
pathfinder,
587
597
}
588
598
}
@@ -664,7 +674,7 @@ fn node_info(pubkey: PublicKey) -> NodeInfo {
664
674
}
665
675
666
676
#[ async_trait]
667
- impl < ' a , T : SimNetwork , P : PathFinder < ' a > > LightningNode for SimNode < ' a , T , P > {
677
+ impl < T : SimNetwork , P : PathFinder > LightningNode for SimNode < T , P > {
668
678
fn get_info ( & self ) -> & NodeInfo {
669
679
& self . info
670
680
}
@@ -686,7 +696,6 @@ impl<'a, T: SimNetwork, P: PathFinder<'a>> LightningNode for SimNode<'a, T, P> {
686
696
dest,
687
697
amount_msat,
688
698
& self . pathfinding_graph ,
689
- & self . scorer ,
690
699
) {
691
700
Ok ( route) => route,
692
701
Err ( e) => {
@@ -1064,7 +1073,7 @@ pub async fn ln_node_from_graph<P>(
1064
1073
pathfinder : P ,
1065
1074
) -> HashMap < PublicKey , Arc < Mutex < dyn LightningNode > > >
1066
1075
where
1067
- P : for < ' a > PathFinder < ' a > + Clone + ' static ,
1076
+ P : PathFinder + ' static ,
1068
1077
{
1069
1078
let mut nodes: HashMap < PublicKey , Arc < Mutex < dyn LightningNode > > > = HashMap :: new ( ) ;
1070
1079
@@ -1563,7 +1572,6 @@ mod tests {
1563
1572
use mockall:: mock;
1564
1573
use ntest:: assert_true;
1565
1574
use std:: time:: Duration ;
1566
- use tokio:: sync:: oneshot;
1567
1575
use tokio:: time:: { self , timeout} ;
1568
1576
1569
1577
/// Creates a test channel policy with its maximum HTLC size set to half of the in flight limit of the channel.
@@ -1953,7 +1961,12 @@ mod tests {
1953
1961
1954
1962
// Create a simulated node for the first channel in our network.
1955
1963
let pk = channels[ 0 ] . node_1 . policy . pubkey ;
1956
- let mut node = SimNode :: new ( pk, sim_network. clone ( ) , Arc :: new ( graph) , DefaultPathFinder ) ;
1964
+ let mut node = SimNode :: new (
1965
+ pk,
1966
+ sim_network. clone ( ) ,
1967
+ Arc :: new ( graph) ,
1968
+ DefaultPathFinder :: new ( ) ,
1969
+ ) ;
1957
1970
1958
1971
// Prime mock to return node info from lookup and assert that we get the pubkey we're expecting.
1959
1972
let lookup_pk = channels[ 3 ] . node_1 . policy . pubkey ;
@@ -2038,16 +2051,15 @@ mod tests {
2038
2051
}
2039
2052
2040
2053
/// Contains elements required to test dispatch_payment functionality.
2041
- struct DispatchPaymentTestKit < ' a > {
2054
+ struct DispatchPaymentTestKit {
2042
2055
graph : SimGraph ,
2043
2056
nodes : Vec < PublicKey > ,
2044
- routing_graph : Arc < NetworkGraph < & ' a WrappedLog > > ,
2045
- scorer : ProbabilisticScorer < Arc < NetworkGraph < & ' a WrappedLog > > , & ' a WrappedLog > ,
2057
+ routing_graph : Arc < NetworkGraph < & ' static WrappedLog > > ,
2046
2058
shutdown : ( Trigger , Listener ) ,
2047
2059
pathfinder : DefaultPathFinder ,
2048
2060
}
2049
2061
2050
- impl DispatchPaymentTestKit < ' _ > {
2062
+ impl DispatchPaymentTestKit {
2051
2063
/// Creates a test graph with a set of nodes connected by three channels, with all the capacity of the channel
2052
2064
/// on the side of the first node. For example, if called with capacity = 100 it will set up the following
2053
2065
/// network:
@@ -2065,12 +2077,6 @@ mod tests {
2065
2077
populate_network_graph ( channels. clone ( ) , Arc :: new ( SystemClock { } ) ) . unwrap ( ) ,
2066
2078
) ;
2067
2079
2068
- let scorer = ProbabilisticScorer :: new (
2069
- ProbabilisticScoringDecayParameters :: default ( ) ,
2070
- routing_graph. clone ( ) ,
2071
- & WrappedLog { } ,
2072
- ) ;
2073
-
2074
2080
// Collect pubkeys in-order, pushing the last node on separately because they don't have an outgoing
2075
2081
// channel (they are not node_1 in any channel, only node_2).
2076
2082
let mut nodes = channels
@@ -2091,9 +2097,8 @@ mod tests {
2091
2097
. expect ( "could not create test graph" ) ,
2092
2098
nodes,
2093
2099
routing_graph,
2094
- scorer,
2095
2100
shutdown : shutdown_clone,
2096
- pathfinder : DefaultPathFinder ,
2101
+ pathfinder : DefaultPathFinder :: new ( ) ,
2097
2102
} ;
2098
2103
2099
2104
// Assert that our channel balance is all on the side of the channel opener when we start up.
@@ -2138,18 +2143,14 @@ mod tests {
2138
2143
) -> ( Route , Result < PaymentResult , LightningError > ) {
2139
2144
let route = self
2140
2145
. pathfinder
2141
- . find_route ( & source, dest, amt, & self . routing_graph , & self . scorer )
2146
+ . find_route ( & source, dest, amt, & self . routing_graph )
2142
2147
. unwrap ( ) ;
2148
+ let ( sender, receiver) = tokio:: sync:: oneshot:: channel ( ) ;
2143
2149
2144
- let ( sender, receiver) = oneshot:: channel ( ) ;
2145
2150
self . graph
2146
- . dispatch_payment ( source, route. clone ( ) , PaymentHash ( [ 1 ; 32 ] ) , sender) ;
2147
-
2148
- let payment_result = timeout ( Duration :: from_millis ( 10 ) , receiver) . await ;
2149
- // Assert that we receive from the channel or fail.
2150
- assert ! ( payment_result. is_ok( ) ) ;
2151
+ . dispatch_payment ( source, route. clone ( ) , PaymentHash ( [ 0 ; 32 ] ) , sender) ;
2151
2152
2152
- ( route, payment_result . unwrap ( ) . unwrap ( ) )
2153
+ ( route, receiver . await . unwrap ( ) )
2153
2154
}
2154
2155
2155
2156
// Sets the balance on the channel to the tuple provided, used to arrange liquidity for testing.
0 commit comments