-
Notifications
You must be signed in to change notification settings - Fork 40
Add Custom Pathfinding #303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shared some thoughts.
simln-lib/src/sim_node.rs
Outdated
amount_msat: u64, | ||
pathfinding_graph: &LdkNetworkGraph, | ||
) -> Result<Route, SimulationError> { | ||
let scorer_graph = NetworkGraph::new(bitcoin::Network::Regtest, Arc::new(WrappedLog {})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes more sense to pass in this graph rather than instantiating it every time.
use super::*; | ||
|
||
#[test] | ||
fn test_create_activity() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this helper function is still needed in this PR
sim-cli/src/parsing.rs
Outdated
======= | ||
pub async fn create_simulation_with_network<P: for<'a> PathFinder<'a> + Clone + 'static>( | ||
cli: &Cli, | ||
>>>>>>> 59dbbe6 (Add pathfinder trait) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the commits in between seem to have these from conflicts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah - will fix before taking it out of draft. Thanks!
simln-lib/src/sim_node.rs
Outdated
let scorer_graph = NetworkGraph::new(bitcoin::Network::Regtest, Arc::new(WrappedLog {})); | ||
let mut scorers = self.scorers.lock().await; | ||
let scorer = scorers.entry(*source).or_insert_with(|| { | ||
ProbabilisticScorer::new( | ||
ProbabilisticScoringDecayParameters::default(), | ||
Arc::new(scorer_graph), | ||
Arc::new(WrappedLog {}), | ||
) | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following - could you explain why does it need a map and one scorer per sender?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my understanding, having one scorer per node gives us more realistic pathfinding as this is close to the real-world behaviour of the Lightning Network (each node is responsible for its own pathfinding), so simulations would be run under real-world conditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, I'm wondering because each SimNode
has a Pathfinder
and each time a node is being instantiated in ln_node_from_graph
, the pathfinder is cloned. So IIUC, the entire map with all scorers will be cloned on every SimNode
. Perhaps it should be in an Arc
?
edit: I'm wrong - I see the map in ScorersMap
is behind an Arc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, here it's creating a new empty graph for each scorer. Shouldn't it use the already existing graph
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a second look, I'm still not sure on why we need a map to keep track of all scorers. If each SimNode
has a Pathfinder
then I don't see why it's needed for the DefaultPathfinder
of every SimNode
to have that map. Each Pathfinder
for each SimNode
would only need its own scorer + the network graph no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, here it's creating a new empty graph for each scorer. Shouldn't it use the already existing graph
Yeah, you are right - left a comment about that above . Still thinking of the best approach as the type
needed for the scorer graph is slightly different from the type
of network graph we have currently.
On a second look, I'm still not sure on why we need a map to keep track of all scorers. If each
SimNode
has aPathfinder
then I don't see why it's needed for theDefaultPathfinder
of everySimNode
to have that map. EachPathfinder
for eachSimNode
would only need its own scorer + the network graph no?
Yeah this makes sense! If the DefaultPathfinder
holds its own scorer, that gives us one scorer per node.
simln-lib/src/sim_node.rs
Outdated
pub struct DefaultPathFinder { | ||
scorers: ScorersMap, | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feels like this should have a NetworkGraph
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah - thought of that but also considering allowing the user pass in the NetworkGraph
(for scoring) directly into the find_route
method as an Option
or perhaps we could somehow still use the pathfinding_graph
already being passed into find_route
- What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmmm API-wise not sure what's best but I'd think that find_route
in the Pathfinder
could do without having to pass the network graph? A pathfinder impl can have it's own view of the network and based on sender
and destination
pubkeys and the amount return a Route
.
Edit: internally the DefaultPathfinder
could use the graph we already have for scoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edit: internally the
DefaultPathfinder
could use the graph we already have for scoring.
Yeah! That makes sense.
d4423a0
to
04842b1
Compare
routing_graph.clone(), | ||
clock.clone(), | ||
)?)), | ||
pathfinder.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't cloning the pathfinder here cause every SimNode
to have the same scorer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the issue here is that the scorer
in DefaultPathfinder
is wrapped in an Arc
which prevents pathfinder.clone()
from creating a unique deep copy of the mutable scorer state for each SimNode
. I'll push a fix to remove the Arc
and implement the necessary custom Clone
logic to ensure isolation.
); | ||
|
||
// Create the pathfinder instance | ||
let pathfinder = DefaultPathFinder::new(routing_graph.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not pass the pathfinder to create_simulation_with_network
? there should be a way to create a simulation with a custom one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that makes sense though since DefaultPathFinder
depends on the network graph, we would probably have to pass the graph into create_simulation_with_network
too which seems unnecessary to me.
If a user needs to create a simulation with a custom pathfinder, don't you think they can simply instantiate their custom pathfinder here? Moreso, if they have a custom pathfinder, they would probably be comfortable using simln-lib
directly, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we would probably have to pass the graph into
create_simulation_with_network
too
yeah... don't see any other way.
If a user needs to create a simulation with a custom pathfinder, don't you think they can simply instantiate their custom pathfinder here? Moreso, if they have a custom pathfinder, they would probably be comfortable using
simln-lib
directly, no?
here how? If using simln
as a lib, this create_simulation_with_network
function is the one they would use to create a Simulation
. They can setup their own custom pathfinder but would need a way to pass it somehow to simln-lib
so that a Simulation
can be setup using their custom pathfinder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's my perspective - sim-cli
is the application layer which should have the default settings which can be used to run a simulation out-of-the-box and simln-lib
is the library which users can depend on and which they can pass custom values to, to run custom simulations that are not possible with the default sim-cli
application. From what you are saying, the user would be expected to depend on both sim-cli
as well as simln-lib
. Shouldn't the user just depend on simln-lib
(this is making me think create_simulation
and create_simulation_with_network
methods belong to simln-lib
and not sim-cli
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hehe woops, my bad, I just realized that create_simulation
and create_simulation_with_network
are in sim-cli
.
(this is making me think
create_simulation
andcreate_simulation_with_network
methods belong tosimln-lib
and notsim-cli
)?
I saw those (create_simulation
and create_simulation_with_network
) as lib utils since having users do everything that is in there seemed like a handful. But you made me realize they are not in simln-lib
😅 so what you said makes sense.
This PR builds upon the work done here #273
This PR introduces a new
PathFinder
trait which allows for more flexible pathfinding. Instead of being locked into the LDK pathfinding algorithm, custom pathfinding algorithms can be swapped in. ADefaultPathFinder
has been provided to maintain backwards compatibility.