[WIP] askrene-getroutes adaptive bounds - #9380
Open
Lagrang3 wants to merge 8 commits into
Open
Conversation
Improved the fakenet simulation by moving funds after a payment succeeds. This triggers a bug in xpay. At PAYING Node ElementsProject#8 xpay fails after trying many 1msat routes: ``` error: {'code': 209, 'message': "Timed out after after 842 attempts. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102199msat. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102197msat. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102196msat. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102195msat. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102194msat. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102193msat. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102192msat. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102191msat. We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198102190msat ... We got temporary_channel_failure for 45210x2134x44171/0, assuming it can't carry 198101779msat. Payment of 9996982msat reached destination, but timed out before the rest arrived.. Payment of 998000msat reached destination, but timed out before the rest arrived.. Payment of 3000000msat reached destination, but timed out before the rest arrived.. Payment of 197000000msat reached destination, but timed out before the rest arrived.. Payment of 91005018msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. ... Payment of 1msat reached destination, but timed out before the rest arrived.. Payment of 1msat reached destination, but timed out before the rest arrived.. "} ``` A lower bound learned for channel 45210x2134x44171 at a previous payment is to blame. xpay thinks it has enough liquidity for ~198ksat 100% sure and it keeps trying and failing, while refine produces 1msat alternative payment routes after every MCF computation because fees don't fit even for our current knowledge. As a matter of fact the computed routes are attributed a very low probability of success at around ~0.4%. This is a case for which our assumption that "the cost of X+fees is not much greater than the cost of X" breaks down. To fix this: - we need xpay to relax that lower bound. The multiple failures are empirical evidence that our knowledge is wrong and we should correct it, - the probability cost function should add a buffer for hypothetical fees, ie. New_cost(x) = Old_cost(x + fees). Changelog-None Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Lagrang3
force-pushed
the
xpay-adaptive-bounds
branch
from
August 5, 2026 07:09
d7b771e to
69c1355
Compare
When the known max and known min are about the same value, the probability cost of sending x=value is zero and MCF will try it. It doesn't take into account the possibility that when we hit that channel the actual flow is x+fees. We adjust the min/max bounds by a factor of 1/1.01 like if we had a 1% reserve for fees. Changelog-Fixed: askrene-getroutes: Account for a worst case 1% fee in the flow amount when computing probability costs. Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Lagrang3
force-pushed
the
xpay-adaptive-bounds
branch
from
August 5, 2026 11:27
8ac9c19 to
7bca9fb
Compare
Changelog-None Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Changelog-None Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Lagrang3
force-pushed
the
xpay-adaptive-bounds
branch
3 times, most recently
from
August 6, 2026 21:11
d1727d5 to
6d2ff19
Compare
Lagrang3
marked this pull request as ready for review
August 6, 2026 21:19
Lagrang3
force-pushed
the
xpay-adaptive-bounds
branch
2 times, most recently
from
August 7, 2026 07:10
4009272 to
5860bf2
Compare
Liquidity bounds are estimated from the observations gathered from askrene-inform-channel. When combined, these intel entries are relaxed base on the likelyhood of the observation with the prior knowledge, eg. observing a channel failure when Pickhardt-Richer probability of success is 99% indicates that it is likely that our prior knowledge was wrong. We also use observations corresponding to the opposite direction of the channel. Changelog-Fixed: askrene-getroutes: liquidity bounds change with the evidence gathered from askrene-inform-channel Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Lagrang3
force-pushed
the
xpay-adaptive-bounds
branch
2 times, most recently
from
August 7, 2026 11:30
2323e5b to
c6d596a
Compare
Use an exponential function to relax the liquidity bounds in askrene-getroutes. The choice of the time scale, currently lifetime=24h is arbitrary, the choice of the function is arbitrary as well. For whatever decay function we use it is important for consistency that the semi-group property of time evolution be satisfied. This time relaxation is useful because it allow us to smoothly discard old information, eg. we can try routes that have failed on us in the past and we don't get too optimistic about lower bounds we have learned a while ago. Another benefit is that we can combine channel intels giving older entries "less importance" by applying the time evolution between intel time gaps. Changelog-None Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
We have set an exponential decay time for liquidity bounds with a lifetime of 1 day, it halves every 16 hours. This parameter can be tuned. But I think throwing away entries after 1 hour is too aggresive. Better to remove them after 1 week. In that time it will be halved 10 times. Changelog-None Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Lagrang3
force-pushed
the
xpay-adaptive-bounds
branch
3 times, most recently
from
August 8, 2026 11:04
a2357db to
6505622
Compare
The 3 channel intel types, constraint_min, constraint_max and impressions, are basically the same type. Instead of doing pointer magic define a single channel intel type to gather these 3 cases for the internal use. The JSON API still makes a distinction between them. Changelog-None Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Lagrang3
force-pushed
the
xpay-adaptive-bounds
branch
from
August 10, 2026 07:43
6505622 to
1524935
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
After #9150, some flaws in askrene came to light. I've documented as much as I saw appropriate
in the code and commit messages, but for more details there was a thought process explained in #9282.
TLDR: