Skip to content
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

routing: pre-payment probe [PoC] #2537

Closed
wants to merge 16 commits into from

Conversation

joostjager
Copy link
Contributor

@joostjager joostjager commented Jan 24, 2019

This PR adds probe functionality to lnd.

What is probing?

Probing means trying to pay via a route with a payment hash that the receiver doesn't have the preimage of. The receiver nor any of the intermediate nodes are able to settle the payment. When the probe is successful, the receiver will return a incorrect_or_unknown_payment_details error to the sender.

A successful probe indicates that:

  • The route is valid (fees and time lock deltas are satisfying current channel policies).
  • All nodes involved are on line and connected.
  • There is enough balance in the channels to forward the payment.

When a probe is unsuccessful, one or more of the conditions above are not met and a different error will be returned from the final or any of the intermediate nodes.

A probe may take up to the route time lock to complete. This is potentially a long time (hundreds of blocks). Normally a probe is expected to complete quickly (seconds). If not, the probe is considered unsuccessful as well. Something along the route is holding up the payment. The worst variation of this is a 'black hole': a node that accepts the htlc, but never returns any response. It will take until the htlc expiry height for the probe to complete.

Because no one except the sender knows the preimage of a probe, probe amounts can be locked up but never taken by anyone.

Probe use cases

There are two main use cases for probing:

Reduction of amount of locked up funds and risk of overpaying

The normal payment process in lnd consists of optimizing the route (path finding) followed by sending the payment along this route. If the payment gets 'stuck' along the way, the full payment amount plus routing fees is locked for up to the expiry height of the handed out htlc.

For larger payment amounts, this becomes a significant problem. Not only are the locked funds unavailable for other uses, but the sender is also kept in uncertainty about whether the payment reached the receiver or might reach the receiver in the future. Requesting a new invoice, paying that and having the original payment go through after all means that the payment has been made twice (or even more times, if more attempts were needed). For services that do not refund any payments, this is money lost. At the very least, the service operator needs to be contacted for a refund.

Probing is a way to mitigate this risk. Once the payment process has found a suitable route, a probe with the lowest possible amount is sent out first. This checks that the route is valid, the nodes are online and not imposing unnecessary delays. If the probe does get stuck, the amount that is stuck is only small. Also, a different route can be tried without risking overpayment.

When the probe succeeds with a small amount, it can be repeated with the full payment amount. This also tests whether the channels contain enough balance for the payment.

Only when that second probe succeeds as well, the actual payment using the payment hash from the invoice will be made. There is no guarantuee that this payment will be successful though. The Lightning Network is dynamic and always changing, so in the short time window between probe and payment, things may have changed. In addition to that, adversaries may try to recognize probes and act differently. That said, the assumption here is that with the state the network is currently in, pre-payment probing will be an improvement.

Probing is also a trade off with payment speed. It takes time to probe. A way to deal with this is to cache probe results.

Routing fee estimates

In Lightning, intermediate nodes charge routing fees. The main mechanism for senders to control what they spend on routing fees is through a fee limit. Any route that exceeds the fee limit will be rejected. The sender will only know the actual fees paid after the payment is completed.

It can however be desirable to know up front how much is going to be paid in fees. Examples:

  • A service that gives out quotes that are based in some way on routing fees for a specific payment. Like a quote for withdrawal from an exchange to a Lightning node.

  • Showing the user of a Lightning wallet the actual routing fee before the payment is confirmed. This will likely be experienced as a ux improvement over a fee limit.

Sending out a probe is a way to accomplish this. If the probe succeeds, one can be reasonably sure that the payment can be made with the fees of the probed route.

Implementation

This PR builds on top of:

Probing consists of two stages:

  • Pre-probing which uses the least amount possible. This amount is based on the min_htlc
    policies of the channels along the routes.
  • Final probing which uses the actual payment amount.

If the pre-probe doesn't complete within the probe timeout interval, it is important for further attempts to know which hop caused this. This information is not available, because the probe didn't return any response at all. Any of the hops could be at fault.

In this case, an additional set of probes is fired to pinpoint the faulty edge. This set of probes contains sub paths of the originally probed route. The probes are attempted sequentially, starting with the shortest route.

Suppose the route consists of three hops. If probing the full route times out, a new route is created that only contains the first hop. If that probe succeeds, the second hop is added and probed. Say this probe times out. Then the edge between the first and second hop is considered bad and avoided in the next path finding round.

Usage

Probing is available through lncli. The payinvoice command is extended with two boolean flags:

--probe makes lnd execute pre-probes and a final probe before making the actual payment.

--estimatefee also executes pre-probes and a final probe, but does not make the actual payment. It does return the probed route, so that the total fee (and other interesting fields) can be extracted from it.

Trying out probing is currently only recommended on testnet.

@joostjager joostjager force-pushed the probe-poc branch 2 times, most recently from 415e5af to 5eecb1e Compare January 25, 2019 09:50
@joostjager joostjager changed the title routing: pre-payment probe routing: pre-payment probe [no review] Jan 30, 2019
@Roasbeef Roasbeef added enhancement Improvements to existing features / behaviour routing payments Related to invoices/payments incomplete WIP PR, not fully finalized, but light review possible labels Feb 1, 2019
@joostjager joostjager force-pushed the probe-poc branch 2 times, most recently from 3b7618c to 8d59432 Compare March 8, 2019 13:54
@joostjager joostjager force-pushed the probe-poc branch 7 times, most recently from 9017ce9 to cbf0a64 Compare April 1, 2019 09:50
@joostjager joostjager changed the title routing: pre-payment probe [no review] routing: pre-payment probe [work in progress] Apr 1, 2019
@joostjager joostjager force-pushed the probe-poc branch 2 times, most recently from 6905a63 to d18314f Compare April 9, 2019 11:47
@Roasbeef Roasbeef added this to the 0.10.0 milestone Jan 14, 2020
@Roasbeef Roasbeef added the v0.10 label Jan 14, 2020
@Roasbeef Roasbeef removed this from the 0.10.0 milestone Feb 18, 2020
@joostjager joostjager removed the v0.10 label Apr 7, 2020
@joostjager
Copy link
Contributor Author

This PR is complicated by mpp and the lack of a probing mechanism for that type of payments

@joostjager joostjager changed the title routing: pre-payment probe [work in progress] routing: pre-payment probe [PoC] Sep 11, 2020
@joostjager
Copy link
Contributor Author

Re-examined this PR again. There are a lot of preparatory commits that have in the mean time been merged as parts of other PRs. The only commit that is relevant still is routing: route probing.

It introduces the two types of probing described above: prepay probing and final probing. Final probing is already possible in master by replacing the payment hash of a payment request with a random value, which isn't too involved.

What is left is the prepay probing where paths are first probed with a minimal amount to check for black holes. It is possible to do this externally by running your own payment loop using QueryRoutes/SendToRoute, but that is some work. I think that it can still make sense to have prepay probing in lnd, depending on the importance of black hole defense.

@joostjager
Copy link
Contributor Author

I am probably not going to continue this on the short term, closing for now.

@joostjager joostjager closed this Apr 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvements to existing features / behaviour incomplete WIP PR, not fully finalized, but light review possible payments Related to invoices/payments routing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants