Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Don't be fooled by the relative simplicity of the code, it took me many iterations to get it to that state, every small detail/heuristic plays an important role!
At first I wanted really hard to use Ford-Fulkerson. I'm convinced that finding a good way to split the payment is a circulation problem. But the devil lies in the details, and there are a lot of non-trivial issues when trying to adapt flow algorithms to MPP:
minimum-htlc-msat
,maximum-htlc-msat
and the total fee budget is much harder than it looksIn the end I decided to start with a simpler method, which is quite similar to Ford-Fulkerson but without rebalancing flow between already-found paths. Yen's k-shortest paths already provides a quite diverse set of paths, so I start with that and then greedily add HTLCs, while keeping track of the already-allocated HTLCs to avoid creating conflicting HTLCs. This is a very simple algorithm to follow and it works quite well on the mainnet graph. It will be a good first solution, and then we can experiment with different algorithms based on production A/B testing: this is the only good way of selecting the "right" algorithm for LN since we're blind to most of the flow information in the network.
I've done many tests on the mainnet graph with random nodes: this is what decided the default choices of parameters (minimum part amount, maximum number of parts). The 5th percentile for channel capacity is 31 000 sats, so choosing half that value as minimum amount guarantees we'll be able to leverage almost all paths. I've run many path-finding tests between random nodes in the network for an amount of 1.000.000 sats, and very rarely found a route with more than 5 parts, hence the choice 6 for the maximum number of parts.
I think it could make sense to allow mobile users to set
max-parts
themselves if the default value doesn't find a route for their payment: it may be slower but if it helps their payment get through, they can then reset the value to a more conservative one.