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

Eduardo/renepay #12

Closed
wants to merge 64 commits into from
Closed

Eduardo/renepay #12

wants to merge 64 commits into from

Conversation

Lagrang3
Copy link

@Lagrang3 Lagrang3 commented Apr 19, 2023

Overview

This PR about implementing a payment plugin called renepay that seeks to
construct optimal Multi-Path-Payments (o-MPP) in terms of fees and reliability.
The original idea was published by Rene Pickhardt and Stefan Richter [1].
There exists a python implementation of o-MPP by Pickhardt (pickhardtpayments).

This work was possible thanks to a Build on L2 Grant.

Pickhardtpayments

Any node in the Lightning Network (LN) has knowledge of the existence of public
channels and their capacities, but the channel liquidity is unknown unless that
channel is local to the node.
Therefore, when a node constructs a route to send a payment it is assuming that
all channels along the path have enough liquidity to forward the payment amount.
If the payment fails, alternative routes can be tried and the process repeats.

It is reasonable to assume that the smaller the payment amount it is more likely
that the payment attempt succeeds. With the use of MPP one could split the
payment into smaller parts and send it along different routes. However, also the
more routes a MPP has, the more likely it will fail. One must find a compromise
between the number of routes and the size of each payment part as well as an
strategy to select routes if one wishes to maximize the probability of success
of the payment.

Pickhardt-Richter [1] paper formalizes this problem stating that the liquidity
of every channel is a random variable distributed in the integer range between
0 and C, where C is the capacity of the channel. For simplicity we are
neglecting the channel reserved fund.
A MPP can also be modeled as flow in the LN, that is an integer value is
associated to each channel, which corresponds to the amount of satoshis this
channel must forward so that this MPP can be completed. Notice that a channel
could be used by two different routes within the same MPP and the flow
associated to that channel is the sum of all funds that need to get through it.
Formally a flow is an integer function in the domain of the channels.

For a realistic payment the Flow constraints include:

  1. for any channel c the flow cannot exceed the channel's capacity:
    0 <= Flow(c) <= Capacity(c);
  2. there is satoshi conservation, hence each node has a satoshi balance computed
    as the sum of all incoming flows minus the outgoing flows,
    the sum of all nodes balance must be zero.
  3. also for the payment to considered valid one must have that
    the destination node have an balance which equals the requested payment
    amount.
    The payer node have a negative balance and must correspond to the
    payment amount plus the routing fees.
    Routing nodes will have a positive balance that corresponds to the total fees
    they collect.

The probability of success of a certain MPP, or its associated Flow,
is then the multiplication of the
probabilities that each channel is able to forward the corresponding Flow:

    Prob(Flow) = Product_{channel c} Prob( c can forward Flow(c))

Maximizing this probability is equivalent to minimizing the function -log Prob(Flow)

    - log Prob(Flow) = - sum_{channel c} log Prob( c can forward Flow(c))

If we assume that:

  1. the probability distribution of the liquidity of every channel c is such that
    -log Prob(c can forward x) is always a convex function of x;
  2. and the routing fees are negligible, hence we can assume that the balance of
    every node different from the source and the destination is zero;

then the problem of finding an optimal Flow that satisfies the capacity and balance
constraints, while maximizing Prob(Flow) can be solved efficiently using
polynomial algorithms. Chapter 14 of Ahuja-Magnanti-Orlin's Network Flows book [2]
is dedicated to this class of problems.

Files

soon

Tests

soon

To-do list

soon

References

[1] Rene Pickhardt, Stefan Richter. Optimally Reliable & Cheap Payment Flows on the Lightning Network https://arxiv.org/abs/2107.05322
[2] R.K. Ahuja, T.L. Magnanti, and J.B. Orlin. Network Flows: Theory, Algorithms, and Applications. Prentice Hall, 1993.

Lagrang3 added 30 commits April 14, 2023 14:02
- add ccan/lqueue
- use an lqueue to traverse the residual network graph in order to seach
for an admissible path from `source` to `target`.
@Lagrang3 Lagrang3 marked this pull request as ready for review June 15, 2023 09:58
Lagrang3 added 13 commits June 20, 2023 09:42
Signed-off-by: Lagrang3 <eduardo.quintana@pm.me>
Signed-off-by: Lagrang3 <eduardo.quintana@pm.me>
We've just replicated the workflow of the standard pay command.
We first query listsendpays for previous attempts to pay for the same
hash.
Knowledge update must consider total amount of liquidity commited to a
channel in the form of HTLC.
- add a renepay object that lives throughout the life of the command.
- make a clear distinction between struct renepay and struct payment.
- add a payment module to keep the methods of renepay and payment.
- add a uncertainty_network module
- waitsendpay calls now are detached from the command, allowing to
  receive responses even after the command finishes
  (yet I think this could have been done in a more robust way using
  notifications instead of waitsendpay).
Instead of waitsendpay
@Lagrang3 Lagrang3 closed this Jul 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant