Commit Graph

77 Commits

Author SHA1 Message Date
Christian Decker 157e70ffe8 paymod: Add a comment about how we derive errors from erring_index
Mainly to help my future self remember
2020-07-23 10:14:21 +09:30
Christian Decker b2463b12c0 paymod: Count all attempts, not just the ones with a result
With the presplitter in particular we would have n attempts but the array
contains n+1 entries, which is kinda weird.
2020-07-23 10:14:21 +09:30
Christian Decker c984376a15 plugin: Always set an end_time for payments in a final state
Reported-by: @thestick613
Fixes #3848
2020-07-18 17:21:11 +02:00
Christian Decker 2146a548bd plugin: Do not return multiple times from `pay`
While we were unsetting the `payment->cmd` in case of a success to signal that
we should not return to the JSON-RPC command twice, we were not doing that in
the case of failures. This was causing multiple responses to a single incoming
command, and `lightningd` was correctly killing the plugin. This issue was
introduced through early returns (anything setting `payment->abort=true`) and
was caused in Rusty's case through an MPP timeout.

Fixes #3847
Reported-by: Rusty Russell <@rustyrussell>
Signed-off-by: Christian Decker <@cdecker>
2020-07-18 11:40:02 +02:00
Christian Decker 958244367c plugin: Do not get upset if it can't parse waitsendpay result
We were rather pedanticly failing the plugin if we were unable to parse the
`waitsendpay` result, but had coded all the modifiers in such a way that they
can handle a `NULL` result (verified in the code and manually by randomly
failing the parsing). So we now just log the result we failed to parse and
merrily go our way.

Worst case is that we end up retrying the same route multiple times, since we
can't blacklist any nodes / channels without understanding the error, but that
is still in the scope of what we must handle anyway.
2020-07-18 11:40:02 +02:00
Christian Decker 3b54847ae4 paymod: Do not assume that parsing the waitsendpay result succeeds
Suggested-by: ZmnSCPxj
Signed-off-by: Christian Decker
Reference: #3846
2020-07-18 11:40:02 +02:00
Christian Decker a3610d66ac retrymod: Make retry modifier slightly more verbose
I found it rather useful to trace how a payment is getting retried in the logs.
2020-07-15 11:32:58 +02:00
Christian Decker 041ee930a4 mpp: Consider an abort as the payment being finished
If one part sets the root to be aborted, there is little point in continuing
to wait for the remainder, return to the caller immediately.
2020-07-15 11:32:58 +02:00
Christian Decker 718b6e3398 mpp: Detect if destination supports MPP from invoice and abort early
We abort on the root since that is the coordination point for all parts of the payment.
2020-07-15 11:32:58 +02:00
Christian Decker de75d3ac0c mpp: Add CLI option to opt-out of multi-part payments
Several tests are not well-suited for mpp, so I added a CLI option to opt-out
of the MPP support at startup time.
2020-07-15 11:32:58 +02:00
Christian Decker 535aaca109 paymod: Implement adaptive splitter
This modifier splits a payment that has been attempted a number of times (by a
modifier earlier in the mod chain) and has failed consistently. It splits the
amount roughly in half, with a but if random fuzz, and then starts a new round
of attempts for the two smaller amounts.
2020-07-15 11:32:58 +02:00
Christian Decker 443643e0b0 retrymod: Reset retry counter if parent is a split
If the parent is a split we have new payment parameters, and want to perform a
number of attempts with those.
2020-07-15 11:32:58 +02:00
Christian Decker d0eb3a79eb paymod: Not having a result doesn't mean we failed at getroute
Specifically if we split, there is no result, but we shouldn't add a failure
message.
2020-07-15 11:32:58 +02:00
Christian Decker 3f399d15cb paymod: Don't assume that the first payment was executed at all
With the `presplit`-modifier we actually skip execution of the root altogether
which results in the root not having a result at all. Instead we should use
the result returned by `payment_collect_result`.
2020-07-15 11:32:58 +02:00
Christian Decker c97ff05ffb mpp: Add the presplit-modifier that splits a root payment first 2020-07-15 11:32:58 +02:00
Christian Decker 7f53ade64b paymod: Allow callers to opt out of shadow routing amount fuzzing
With MPP we require that the sum of parts is equal to the `total_msat` amount
declared in the onion. Since that can't be changed once the first part arrives
we need a way to disable amount fuzzing for MPP.
2020-07-15 11:32:58 +02:00
Rusty Russell 899ec2b3d4 JSON API: fix up two existing warnings to be conformant.
Technically an API break, but nobody relies on these I hope!

Note that the feerates warning was buried inside the style object:
it should be top-level.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-07-14 21:28:26 +02:00
Christian Decker 65963bc003 exemptfee: Only apply to the root payment and fix logs
We were applying the fee exemption to all payments individually, which is ok
until we switch to MPP, where amounts change. Also the log entry was referring
to the total amount, and not the fee of the payment.
2020-07-14 06:25:29 +09:30
Christian Decker 9be4d552fa paymod: Add a bit more information to the `pay` response
Amount, parent_part_id  and own partid can be helpful when debugging.
2020-07-14 06:25:29 +09:30
Christian Decker 6f40cb0202 paymod: Inherit exemptfee modifier data on retry 2020-07-14 06:25:29 +09:30
Christian Decker b88a55b2a4 paymod: Only wait on blockheight if we need to
We were wrongfully identifying all payment failures as blockheight mismatches.
2020-07-14 06:25:29 +09:30
Christian Decker f20091fc72 pay: Do not duplicate "message" field in response to `pay` 2020-07-14 06:25:29 +09:30
Christian Decker 411b760985 paymod: Reset the step if we're waiting for a block
This was causing the state flapping test to fail, since we were yielding
control of the io_loop, waiting for the blockheight to be reached, and not
setting the status beforehand. An interim `paystatus` call would then find a
failed leaf and deduce the entire payment failed. Setting it back to the
previous state keeps the overall payment pending while we wait.
2020-07-14 06:25:29 +09:30
Christian Decker 02e44e9903 paymod: Set the STOPPED_RETRYING status code if we stopped retrying 2020-07-14 06:25:29 +09:30
Christian Decker 5776a33116 paymod: Activate paymod and move legacy pay to `legacypay` command
As suggested during the paymod-03 review it is better to activate the new code
right away, and give users an escape hatch to use the legacy code instead. The
way I implemented it allows using either `legacypay` or `pay` and then set
`legacy` to switch to the other implementation.

Changelog-Added: JSON-RPC: The `pay` command now uses the new payment flow, the new `legacypay` command can be used to issue payment with the legacy code if required.

Suggested-by: Rusty Russell <@rustyrussell>
Suggested-by: ZmnSCPxj <@zmnscpxj>
2020-07-14 06:25:29 +09:30
Christian Decker 514c4044c8 tlv: Allow passing a raw pointer and a length to tlvstream_set_raw
Allows us to do fewer allocations, since the argument doesn't have to be tal
allocated itself.

Suggested-by: Rusty Russell <@rustyrussell>
2020-07-13 14:19:16 +02:00
Christian Decker af4955c28e paymod: Fix waitsendpay error parsing for unknown failure codes
It turns out that the `failcodename` doesn't get populated if the `failcode`
isn't a known error from the enum (duh...) so don't fail parsing if it's
missing.
2020-07-07 23:25:45 +02:00
Christian Decker 5daa5bd61e paymod: Fix the onion payload construction
I wrongly used a pointer to the array that'd move on append, so an extra
dereference was required here.
2020-07-07 23:25:45 +02:00
Christian Decker da8eb6fb4c paymod: Expose riskfactor and wire through to getroute 2020-07-07 23:25:45 +02:00
Christian Decker d8b8a0b31e paymod: Add label to sendonion calls
These get reflected in the `listsendpays` command, and are quite useful.
2020-07-07 23:25:45 +02:00
Christian Decker 2649de54f2 paymod: Do not wait for a blockheight if we're already there
We want to differentiate a wrong block-height from other failure reasons, such
as an unknown `payment_hash`, so we skip the `waitblockheight` if we're
already at the correct height.
2020-07-07 23:25:45 +02:00
Christian Decker 5601a1ab21 paymod: Add a deadline to the pay command and retry modifier 2020-07-07 23:25:45 +02:00
Christian Decker f557955515 paymod: Consolidate parsing RPC results in libplugin
We handle these in a number of different ways, and regularly get the parsing
and logic for optional fields wrong, so let's consolidate them here.
2020-07-07 23:25:45 +02:00
Christian Decker 4b3e849ce9 paymod: Add function to set the current step
This is necessary otherwise we would not be calling modifiers for the newly
set state which can lead to unexpected results.
2020-07-07 23:25:45 +02:00
Christian Decker 4aed45e98d paymod: Add attempts array to `pay` return value 2020-07-07 23:25:45 +02:00
Christian Decker 030633bb28 paymod: Add a human readable failreason to payments
This makes it easier to stash a human readable failure message in an attempt.
2020-07-07 23:25:45 +02:00
Christian Decker 2ef130e427 paymod: Apply and unapply routes to the channel hints
Add/remove the HTLC amount from the channel hints so concurrent getroute calls
have the correct exclusions. This can sometimes underflow, if we're unlucky
and call getroute too closely, but that's not a big issue, it can only result
in a failed MPP attempt too many, nothing fatal, and it'll get corrected based
on the result returned by the failing node.
2020-07-07 23:25:45 +02:00
Christian Decker 2331cd62e1 paymod: Add user-provided label back into the paystatus result 2020-07-07 23:25:45 +02:00
Christian Decker 215a0ada8b paymod: Update the route constraints as we apply routes and mods
These are primarily the fee and cltv constraints that we need to keep up to
date in order to give modifiers a correct view of what is and what isn't
allowed.
2020-07-07 23:25:45 +02:00
Christian Decker 935578e567 paymod: Exclude most expensive/slowest chan if limits are exceeded 2020-07-07 23:25:45 +02:00
Christian Decker 4648d2867f paymod: Compute fee and CLTV delta limits for a payment
So far we got away with not caring about these but since we're implementing
modifiers that impact these limits, we better keep track of them.
2020-07-07 23:25:45 +02:00
Christian Decker e71bdf9ed8 paymod: Wrap the getroute request in a struct
Keeping the arguments in their non-serialized form allows us to amend them as
we apply modifiers and learn new information.
2020-07-07 23:25:45 +02:00
Christian Decker 097cb8d3a0 paymod: Exclude nodes that we found to be faulty 2020-07-07 23:25:45 +02:00
Christian Decker 2f0e535b81 paymod: Add reason why a payment was attempted
This is a slight change in interface in that the string no longer spells out
that a specific node was excluded.
2020-07-07 23:25:45 +02:00
Christian Decker 3a35dd34ac paymod: Add the contents of paystatus
This proved to be rather difficult given the tight coupling of the old structs
and the output of the command.
2020-07-07 23:25:45 +02:00
Christian Decker 2e88249a7b paymod: Make the transition to FAILED a function call
We need to set some variables as well, and the transition to FAILED is a bit
special in that quite some modifiers will skip into FAILED.
2020-07-07 23:25:45 +02:00
ZmnSCPxj jxPCSnmZ 4a89819cdd plugins/Makefile: Change plugins build procedure.
Changelog-None
2020-07-07 21:32:31 +02:00
Christian Decker 7981f4c4d9 paymod: Extract the channel hints update into its own function
We could end up with multiple channel hints, which is a bit wasteful. We now
look for existing ones before adding a new one, and if one exists we use the
more restrictive parameters.

Suggested-by: Lisa Neigut <@niftynei>
2020-07-02 11:54:12 +02:00
Christian Decker ddb0424a4d paymod: Remove the dummy payment modifier
It was there only for demonstration purposes, and is no longer useful.
2020-07-02 11:54:12 +02:00
Christian Decker fc714bf2df paymod: Fill in the `pay` return value 2020-07-02 11:54:12 +02:00