@@ -477,7 +477,7 @@ impl SimulatedChannel {
477477
478478/// SimNetwork represents a high level network coordinator that is responsible for the task of actually propagating
479479/// payments through the simulated network.
480- trait SimNetwork : Send + Sync {
480+ pub trait SimNetwork : Send + Sync {
481481 /// Sends payments over the route provided through the network, reporting the final payment outcome to the sender
482482 /// channel provided.
483483 fn dispatch_payment (
@@ -495,30 +495,53 @@ trait SimNetwork: Send + Sync {
495495}
496496
497497/// 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 {
499510 fn find_route (
500511 & self ,
501512 source : & PublicKey ,
502513 dest : PublicKey ,
503514 amount_msat : u64 ,
504- pathfinding_graph : & NetworkGraph < & ' a WrappedLog > ,
505- scorer : & ProbabilisticScorer < Arc < NetworkGraph < & ' a WrappedLog > > , & ' a WrappedLog > ,
515+ pathfinding_graph : & NetworkGraph < & ' static WrappedLog > ,
506516 ) -> Result < Route , SimulationError > ;
507517}
508518
509- /// Default pathfinder that uses LDK's pathfinding algorithm.
519+ /// The default pathfinding implementation that uses LDK's built-in pathfinding algorithm.
510520#[ derive( Clone ) ]
511521pub struct DefaultPathFinder ;
512522
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 {
514530 fn find_route (
515531 & self ,
516532 source : & PublicKey ,
517533 dest : PublicKey ,
518534 amount_msat : u64 ,
519- pathfinding_graph : & NetworkGraph < & ' a WrappedLog > ,
520- scorer : & ProbabilisticScorer < Arc < NetworkGraph < & ' a WrappedLog > > , & ' a WrappedLog > ,
535+ pathfinding_graph : & NetworkGraph < & ' static WrappedLog > ,
521536 ) -> 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)
522545 find_route (
523546 source,
524547 & RouteParameters {
@@ -529,10 +552,10 @@ impl<'a> PathFinder<'a> for DefaultPathFinder {
529552 final_value_msat : amount_msat,
530553 max_total_routing_fee_msat : None ,
531554 } ,
532- pathfinding_graph,
555+ pathfinding_graph, // This is the real network graph used for pathfinding
533556 None ,
534557 & WrappedLog { } ,
535- scorer,
558+ & scorer, // LDK requires a scorer, so we provide a simple one
536559 & Default :: default ( ) ,
537560 & [ 0 ; 32 ] ,
538561 )
@@ -544,45 +567,32 @@ impl<'a> PathFinder<'a> for DefaultPathFinder {
544567/// all functionality through to a coordinating simulation network. This implementation contains both the [`SimNetwork`]
545568/// implementation that will allow us to dispatch payments and a read-only NetworkGraph that is used for pathfinding.
546569/// While these two could be combined, we re-use the LDK-native struct to allow re-use of their pathfinding logic.
547- struct SimNode < ' a , T : SimNetwork , P : PathFinder < ' a > = DefaultPathFinder > {
570+ pub struct SimNode < T : SimNetwork , P : PathFinder = DefaultPathFinder > {
548571 info : NodeInfo ,
549572 /// The underlying execution network that will be responsible for dispatching payments.
550573 network : Arc < Mutex < T > > ,
551574 /// Tracks the channel that will provide updates for payments by hash.
552575 in_flight : HashMap < PaymentHash , Receiver < Result < PaymentResult , LightningError > > > ,
553576 /// 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 > > ,
558578 /// The pathfinder implementation to use for finding routes
559579 pathfinder : P ,
560580}
561581
562- impl < ' a , T : SimNetwork , P : PathFinder < ' a > > SimNode < ' a , T , P > {
582+ impl < T : SimNetwork , P : PathFinder > SimNode < T , P > {
563583 /// Creates a new simulation node that refers to the high level network coordinator provided to process payments
564584 /// on its behalf. The pathfinding graph is provided separately so that each node can handle its own pathfinding.
565585 pub fn new (
566586 pubkey : PublicKey ,
567587 payment_network : Arc < Mutex < T > > ,
568- pathfinding_graph : Arc < NetworkGraph < & ' a WrappedLog > > ,
588+ pathfinding_graph : Arc < NetworkGraph < & ' static WrappedLog > > ,
569589 pathfinder : P ,
570590 ) -> 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-
580591 SimNode {
581592 info : node_info ( pubkey) ,
582593 network : payment_network,
583594 in_flight : HashMap :: new ( ) ,
584595 pathfinding_graph,
585- scorer,
586596 pathfinder,
587597 }
588598 }
@@ -602,7 +612,7 @@ fn node_info(pubkey: PublicKey) -> NodeInfo {
602612}
603613
604614#[ async_trait]
605- impl < ' a , T : SimNetwork , P : PathFinder < ' a > > LightningNode for SimNode < ' a , T , P > {
615+ impl < T : SimNetwork , P : PathFinder > LightningNode for SimNode < T , P > {
606616 fn get_info ( & self ) -> & NodeInfo {
607617 & self . info
608618 }
@@ -624,7 +634,6 @@ impl<'a, T: SimNetwork, P: PathFinder<'a>> LightningNode for SimNode<'a, T, P> {
624634 dest,
625635 amount_msat,
626636 & self . pathfinding_graph ,
627- & self . scorer ,
628637 ) {
629638 Ok ( route) => route,
630639 Err ( e) => {
@@ -1001,7 +1010,7 @@ pub async fn ln_node_from_graph<P>(
10011010 pathfinder : P ,
10021011) -> HashMap < PublicKey , Arc < Mutex < dyn LightningNode > > >
10031012where
1004- P : for < ' a > PathFinder < ' a > + Clone + ' static ,
1013+ P : PathFinder + ' static ,
10051014{
10061015 let mut nodes: HashMap < PublicKey , Arc < Mutex < dyn LightningNode > > > = HashMap :: new ( ) ;
10071016
@@ -1499,7 +1508,6 @@ mod tests {
14991508 use mockall:: mock;
15001509 use ntest:: assert_true;
15011510 use std:: time:: Duration ;
1502- use tokio:: sync:: oneshot;
15031511 use tokio:: time:: { self , timeout} ;
15041512
15051513 /// Creates a test channel policy with its maximum HTLC size set to half of the in flight limit of the channel.
@@ -1889,7 +1897,12 @@ mod tests {
18891897
18901898 // Create a simulated node for the first channel in our network.
18911899 let pk = channels[ 0 ] . node_1 . policy . pubkey ;
1892- let mut node = SimNode :: new ( pk, sim_network. clone ( ) , Arc :: new ( graph) , DefaultPathFinder ) ;
1900+ let mut node = SimNode :: new (
1901+ pk,
1902+ sim_network. clone ( ) ,
1903+ Arc :: new ( graph) ,
1904+ DefaultPathFinder :: new ( ) ,
1905+ ) ;
18931906
18941907 // Prime mock to return node info from lookup and assert that we get the pubkey we're expecting.
18951908 let lookup_pk = channels[ 3 ] . node_1 . policy . pubkey ;
@@ -1974,16 +1987,15 @@ mod tests {
19741987 }
19751988
19761989 /// Contains elements required to test dispatch_payment functionality.
1977- struct DispatchPaymentTestKit < ' a > {
1990+ struct DispatchPaymentTestKit {
19781991 graph : SimGraph ,
19791992 nodes : Vec < PublicKey > ,
1980- routing_graph : Arc < NetworkGraph < & ' a WrappedLog > > ,
1981- scorer : ProbabilisticScorer < Arc < NetworkGraph < & ' a WrappedLog > > , & ' a WrappedLog > ,
1993+ routing_graph : Arc < NetworkGraph < & ' static WrappedLog > > ,
19821994 shutdown : ( Trigger , Listener ) ,
19831995 pathfinder : DefaultPathFinder ,
19841996 }
19851997
1986- impl DispatchPaymentTestKit < ' _ > {
1998+ impl DispatchPaymentTestKit {
19871999 /// Creates a test graph with a set of nodes connected by three channels, with all the capacity of the channel
19882000 /// on the side of the first node. For example, if called with capacity = 100 it will set up the following
19892001 /// network:
@@ -2001,12 +2013,6 @@ mod tests {
20012013 populate_network_graph ( channels. clone ( ) , Arc :: new ( SystemClock { } ) ) . unwrap ( ) ,
20022014 ) ;
20032015
2004- let scorer = ProbabilisticScorer :: new (
2005- ProbabilisticScoringDecayParameters :: default ( ) ,
2006- routing_graph. clone ( ) ,
2007- & WrappedLog { } ,
2008- ) ;
2009-
20102016 // Collect pubkeys in-order, pushing the last node on separately because they don't have an outgoing
20112017 // channel (they are not node_1 in any channel, only node_2).
20122018 let mut nodes = channels
@@ -2027,9 +2033,8 @@ mod tests {
20272033 . expect ( "could not create test graph" ) ,
20282034 nodes,
20292035 routing_graph,
2030- scorer,
20312036 shutdown : shutdown_clone,
2032- pathfinder : DefaultPathFinder ,
2037+ pathfinder : DefaultPathFinder :: new ( ) ,
20332038 } ;
20342039
20352040 // Assert that our channel balance is all on the side of the channel opener when we start up.
@@ -2074,18 +2079,14 @@ mod tests {
20742079 ) -> ( Route , Result < PaymentResult , LightningError > ) {
20752080 let route = self
20762081 . pathfinder
2077- . find_route ( & source, dest, amt, & self . routing_graph , & self . scorer )
2082+ . find_route ( & source, dest, amt, & self . routing_graph )
20782083 . unwrap ( ) ;
2084+ let ( sender, receiver) = tokio:: sync:: oneshot:: channel ( ) ;
20792085
2080- let ( sender, receiver) = oneshot:: channel ( ) ;
20812086 self . graph
2082- . dispatch_payment ( source, route. clone ( ) , PaymentHash ( [ 1 ; 32 ] ) , sender) ;
2083-
2084- let payment_result = timeout ( Duration :: from_millis ( 10 ) , receiver) . await ;
2085- // Assert that we receive from the channel or fail.
2086- assert ! ( payment_result. is_ok( ) ) ;
2087+ . dispatch_payment ( source, route. clone ( ) , PaymentHash ( [ 0 ; 32 ] ) , sender) ;
20872088
2088- ( route, payment_result . unwrap ( ) . unwrap ( ) )
2089+ ( route, receiver . await . unwrap ( ) )
20892090 }
20902091
20912092 // Sets the balance on the channel to the tuple provided, used to arrange liquidity for testing.
0 commit comments