We don't actually support it yet, but this threads through the type change,
puts it in "decode" etc.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
And deprecate the --max-locktime-blocks which allows them to set it.
Hilariously, the spec misspells CLTV as CTLV at one point, so we work around it for now.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Listpeerchannels would update the local channel information setting the
liquidity in the outgoing channel to known_min=known_max=capacity,
when in fact it should be known_min=known_max=spendable.
The route-builder checks the liquidity bounds of each route one at a
time. Every route that satisfy the contraints is recorded in the
uncertainty network and produces an HTLC burden on the channels it uses,
so that the following routes cannot count on the same liquidity twice.
Routes contain only routing information and the payment they're linked
to can be obtained through the payment_hash. We remove the dependency of
route building routines from the payment itself. In order to make
plain payment information available we define a payment_info structure.
- use switch case over all possible WIRE_* errors,
- remove the virtual machine for routefail, use a simple two step
solution: 1. update the gossip and 2. handle error cases
Using enum renepay_errorcode simplifies the low level API of chan_extra and flow.
We can extract information about the nature of a function call failure
from its return value.
Routefail consist mainly of an API `routefail_start` that handles the
failure of a forwarding request (encoded in a route). Internally there
is a routefail datastructure that goes through a series of execution
steps, eg. updating the gossmap, updating the uncertainty network, etc.
Routebuilder constitute the module that builds the routes we try in the
payment. The public API is simply `get_routes`, it replaces the similar
interface for pay_flows.
Add a new implementation of the payment state machine.
This is based in the `pay` plugin concept of payment modifiers,
but here we take it to the next level.
The payment goes through a virtual machine that includes calling
functions and evaluating conditions.
gcc-12 (Ubuntu 12.3.0-9ubuntu2) 12.3.0 with -O3 gives:
```
In file included from plugins/renepay/test/../mcf.c:5,
from plugins/renepay/test/run-arc.c:13:
ccan/ccan/tal/str/str.h: In function ‘minflow’:
ccan/ccan/tal/str/str.h:43:9: error: ‘errmsg’ may be used uninitialized [-Werror=maybe-uninitialized]
43 | tal_fmt_(ctx, TAL_LABEL(char, "[]"), __VA_ARGS__)
| ^~~~~~~~
plugins/renepay/test/../mcf.c:1565:15: note: ‘errmsg’ was declared here
1565 | char *errmsg;
| ^~~~~~
cc1: all warnings being treated as errors
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
is_local, ie. "is this side of the channel ours?" is not needed since we
can determine that predicate by evaluating
`scidd->dir == node_id_idx(self, peer)`
In the Min. Cost Flow solver we put a constraint on arcs capacities,
such that the total flow that can be allocated through a channel does
not exceed htlc_max. This solves two previous problem of the htlc_max
constraint at the MCF level.
Add spendable/receivable and is_local fields to the callback function
used in gossmods_from_listpeerchannels. This allows to do more fine
grained use of the listpeerchannels call.
The first use case is renepay, for which we need to ignore the htlc_max
of the local channels only.
It's a u64, we should pass by copy. This is a big sweeping change,
but mainly mechanical (change one, compile, fix breakage, repeat).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This has the benefit of being shorter, as well as more reliable (you
will get a link error if we can't print it, not a runtime one!).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
In some weird situations it may happen that some channel along the route
could have htlcmax=htlcmin, so that the supremum of htlcmin and the
infimum of htlcmax are the same number. In that case there is only one
allowed amount that can go through that route.
Without this patch renepay would not handle correctly this cornercase.
I noticed that run-route-infloop chose some worse-looking paths after
routing was fixed, eg the second node:
Before:
Destination node, success, probability, hops, fees, cltv, scid...
02b3aa1e4ed31be83cca4bd367b2c01e39502cb25e282a9b4520ad376a1ba0a01a,1,0.991856,2,1004,40,2572260x39x0/1,2131897x45x0/0
After:
Destination node, success, probability, hops, fees, cltv, scid...
02b3aa1e4ed31be83cca4bd367b2c01e39502cb25e282a9b4520ad376a1ba0a01a,1,0.954540,3,1046,46,2570715x21x0/1,2346882x26x14/1,2131897x45x0/0
This is because although the final costs don't reflect it, routing was taking
into account local channels, and 2572260x39x0/1 has a base fee of 2970.
There's an easy fix: when we the pay plugin creates localmods for our
gossip graph, add all local channels with delay and fees equal to 0.
We do the same thing in our unit test. This improves things across
the board:
Linear success probability (when found): min-max(mean +/- stddev)
Before: 0.487040-0.999543(0.952548+/-0.075)
After: 0.486985-0.999750(0.975978+/-0.053)
Hops:
Before: 1-5(2.98374+/-0.77)
After: 1-5(2.09593+/-0.63)
Fees:
Before: 0-50848(922.457+/-2.7e+03)
After: 0-50041(861.621+/-2.7e+03)
Delay (blocks):
Before: 0-196(65.8081+/-60)
After: 0-190(60.3285+/-60)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Plugins: `pay` route algorithm doesn't bias against our own "expensive" channels any more.
Whenever there is a payment failure that requires gossip update, for
example changing the fee rates of remote channels, we call addgossip.
For renepay to consider this changes in the coming payment attempts, it
must update gossmap.
- previous pending sendpays must add up so that the plugin tries to pay
the rest of the amount,
- avoid groupid, partid collisions,
- add shadow fees if the option is set and the payment amount - total
delivering = 0
- add a test,
- also fix a buggy shadow routing test
Min. Cost Flow does not take into account fees when computing a flow
with liquidity constraints.
This is a work-around solution that reduces the amount on every route to
respect the liquidity bound. The deficity in the delivered amount is
solved by running MCF once again.
Changes:
1. the function `flow_complete` allocates amounts to send over the set of routes
computed by the MCF algorithm, but it does not allocate more than liquidity
bound of the route. For this reason `minflow` returns a set of routes that
satisfy the liquidity bounds but it is not guaranteed that the total payment
reaches the destination therefore there could a deficit in the delivery:
`deficit = amount_to_deliver - delivering`.
2. in the function `add_payflows` after `minflow` returns a set of routes we
call `flows_fit_amount` that tries to a allocate the `deficit` in the routes
that the MCF have computed.
3. if the resulting flows pass all payment constraints then we update
`amount_to_deliver = amount_to_deliver - delivering`, and the loop
repeats as long as `amount_to_deliver` is not zero.
In other words, the excess amount, beyond the liquidity bound,
in the routes is removed and then we try to allocate it
into known routes, otherwise we do a whole MCF again just for the
remaining amount.
Fixes issue #6599