-
Notifications
You must be signed in to change notification settings - Fork 913
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
pay: Remember and update channel_hints across payments #7494
Merged
Conversation
This file contains 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
cdecker
force-pushed
the
202407-pay-channel-hint-update
branch
7 times, most recently
from
July 31, 2024 11:18
92b6cc1
to
594f806
Compare
cdecker
force-pushed
the
202407-pay-channel-hint-update
branch
9 times, most recently
from
August 7, 2024 11:59
c676551
to
5259236
Compare
rustyrussell
previously requested changes
Aug 9, 2024
rustyrussell
force-pushed
the
202407-pay-channel-hint-update
branch
from
August 9, 2024 05:45
5259236
to
acc063d
Compare
I rebased, removed the final commit (which was from a different PR, and already merged) and added a commit with my suggested changes. But I'm not sure this PR is complete? |
Lagrang3
reviewed
Aug 9, 2024
cdecker
force-pushed
the
202407-pay-channel-hint-update
branch
3 times, most recently
from
August 9, 2024 10:44
dc74fd8
to
24437b4
Compare
cdecker
force-pushed
the
202407-pay-channel-hint-update
branch
from
August 9, 2024 10:50
24437b4
to
9fc9e9b
Compare
We relax constraints from the `channel_hint` through a linear refill.
We need to know the overall channel capacity, i.e., the amount_msat that the channel was funded with, in order to relax the channel_hint to refill over time.
We attach the hints to the plugin, so they get shared across multiple payments.
Changelog-None
We're getting serious about how we manage the channel_hints, so let's give them a proper home.
Suggested-by: Rusty Russell <@rustyrussell>
Suggested-by: Rusty Russell <@rustyrussell>
Keeping it in `amount_msat` made the comparisons easier, but it was the wrong type for this.
If we have a large channel, fail to send through a small amount, and then add a `channel_hint`, then it can happen that the call to `channel_hint_set_update` is already late enough that it refills the 1msat we removed from the attempted amount, thus making the edge we just excluded eligible again, which can lead into an infinite loop. We slow down the updating of the channel_hints to once every hysteresis timeout. This allows us to set tight constraints, while not incurring in the accidental relaxation issue.
Making sure that we don't accidentally create an endless loop.
We were using `channel_hint` to temporarily tweak the graph inside of a payment. However, these ad-hoc `channel_hints` are stickier than their predecessors, in that they outlive the payment attempt itself, and interfere with later ones. Changelog-Changed: pay: Discarding an overly long or expensive route does not blocklist channels anymore.
A failing payment would doom all subsequent ones. Now we step down the amount a single satoshi so any prior channel_hints do not doom the payment outright. Changelog-None
It was failing because the channel_hint from one attempt would prevent us from retrying. By changing the amounts so that the channel_hints do not concern them (value smaller than estimate) we can make things work as before again.
We were ignoring more reliable information because of the stricter-is-better logic. This meant that we were also ignoring local channel information, despite knowing better. By simplifying the logic to pick the one with the newer timestamp we ensure that later observations always trump earlier ones. There is a bit of interplay between the relaxation of the constraints updating the timestamp, and comparing to real observation timestamps, but that should not impact us for local channels.
This minimizes the need to convert back and forth from and to sat values, and it also removes a new instance of sats in the public interface (`channel_hints`). Suggested-By: Rusty Russell <@rustyrussell>
cdecker
force-pushed
the
202407-pay-channel-hint-update
branch
from
October 7, 2024 09:38
05c2d1a
to
d0b2f3c
Compare
Ok, I think I addressed all the feedback:
Can we merge this now? |
4 tasks
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.
Builds on top of #7487.
This PR takes the
channel_hint
s that were previously created,updated and then discarded as part of a payment, and instead we are
making them long-lived. This means that we share what we learn from
one payment with all later payments, allowing us to skip attempts that
will likely fail anyway, and improve the overall performance
(time-to-completion as well as success rate of payments).
The downside of this is that we are now keeping observations for
prolonged periods, meaning that these observations are no longer valid
when we use them. If used unchanged these earlier observations could
lead us to skip routes that we deem unavailable due to a prior
observation, but which is now back to being usable, which in turn
impacts our ability to complete a payment successfully. The core
contribution in this PR therefore is the time-based relaxation of
learnt constraints. It is based on a leaky-bucket approach, with a
linear refill-rate for depleted channels, such that after 2h we
consider any observation outdated.
Example
If at time
t
we observe a channelc
withcap_c
as overallcapacity, and
bal_c = 0.5 * cap_c
the currently available balance(i.e., we observed a payment of
bal_c + 1
fail to generate thishint), then we have a refill rate
r = cap_c / 7200
, and after 1h thechannel is considered to be fully available again, i.e., we don't have
a more restrictive observation, and it is old enough that it does not
add to the structural information we already have from the gossip.