Commit Graph

324 Commits

Author SHA1 Message Date
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
65ca634528 plugin: Fix misspelled COMPAT_V090 compile guards 2020-07-18 11:40:02 +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
a287bbe55d mpp: Enable adaptive splitter
Changelog-Added: The adaptive multi-part payment modifier will split payments that are failing due to their size into smaller parts, and re-attempted.
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
b813974e13 mpp: Add the presplit MPP modifier
Changelog-Added: The MPP presplit modifier splits large payments into 10k satoshi parts to maximize chances of performing the payment and to obfuscate the overall amount being sent.
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
7978a13cae doc: Add a man-page for the new keysend command 2020-07-13 14:19:16 +02:00
Christian Decker
01a475161d paymod: Implement keysend sending support as a native RPC command
This makes use of the payment modifier structure to just add the preimage to
the TLV payload for the last hop.

Changelog-Added: JSON-RPC: The `keysend` command allows sending to a node without requiring an invoice first.
2020-07-13 14:19:16 +02:00
Rusty Russell
a9427f1a8d bitcoin/feerate: new exposure for feerate parsing outside lightningd.
This exposes the numeric part of param_feerate() as param_feerate_val().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-07-08 21:07:20 +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
0aa5c197ec pytest: Fix tests broken by the pay and paystatus changes
This commit collects the changes required to the tests caused by the changes
to the `pay` and `paystatus` commands. They are also rather good hints as to
what these changes entail.
2020-07-07 23:25:45 +02:00
Christian Decker
2ac87c1490 paymod: Reorder paymod arguments to match pay
We've been adding modifiers and arguments out of order, and we need the
arguments order to match up if we want `paymod` to be a drop-in replacement.
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
cb00cbac7c paymod: Add support for the msatoshi override argument 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
1b057f025c paymod: Let the payment know the local ID
This is necessary for the routehint modifier.
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
Christian Decker
9aff885828 paymod Collect the final failure when aggregating the tree results
We're lucky that we can distinguish the severity of the failure based on the
failcode, so we bubble up the one with the maximum failcode, and let callers
inspect details if they need more information.
2020-07-02 11:54:12 +02:00
Christian Decker
2acb86bfe3 paymod: Consider new payments when checking if an attempt is ongoing
Without this the flapping behavior tested in `test_pay_retry` would reappear.
2020-07-02 11:54:12 +02:00
Christian Decker
7a266b8239 paymod: Make payment_tree_result public to users can query state 2020-07-02 11:54:12 +02:00
Christian Decker
fbd8cf1495 paymod: Keep a copy of the serialized bolt11 in the root payment
We frequently query by the bolt11 string, so keeping it around saves us from
having to parse the query or serialize the parsed one.
2020-07-02 11:54:12 +02:00
Christian Decker
895542c6f1 paymod: Simplify retry mod logic and add abort logic 2020-07-02 11:54:12 +02:00
Christian Decker
73fc10e25f paymod: Parse error from waitsendpay and exclude failed chans 2020-07-02 11:54:12 +02:00
Christian Decker
9d7a48d0f4 pay: Key the MPP payments based on the payment_hash not the bolt11
This allows us to drive the payment from outside, and still get the
aggregation that we want.
2020-07-02 11:54:12 +02:00
Christian Decker
0b85b983ac paymod: Teach the retry_mod not to insist when it's futile
An important life lesson: if there is no path to happiness, then trying harder
will still not get you there.
2020-07-02 11:54:12 +02:00
Christian Decker
10f231bcb5 paymod: Include excludes resulting from channel_hints for getrotue 2020-07-02 11:54:12 +02:00
Christian Decker
5e3134083e paymod: Add a local_channel_hints modifier to collect local channels
We can have quite detailed information about our local channels, so call
`listpeers` before the `getroute` call on the root payment, to seed that
information in the channel_hints.
2020-07-02 11:54:12 +02:00
Christian Decker
b1e9f4923b paymod: Add the final cltv delta to the getroute call 2020-07-02 11:54:12 +02:00
Christian Decker
6fbfe24e3e paymod: Add a COMPAT_090 flag
Since we end up consolidating some of the return values for `pay` and
`paystatus` and change the public interface we need to add the compatibility
flag and guard the switchover behind it.
2020-07-02 11:54:12 +02:00
niftynei
2ab41af8e2 rm pullpush: cleans up unused methods for push/pull
most likely unused since the switch to libwally for internal blockchain
things.

these method names were clashing with ones that are to be introduced
with some libwally cleanups, so getting rid of them pre-emptively keeps
us libwally compatible
2020-07-01 19:50:02 -05:00
Christian Decker
6af5ab9504 paymod: Move onion payload construction into its own function
Suggested-by: Rusty Russell <@rustyrussell>
2020-07-01 12:19:02 +02:00
Christian Decker
b15876c112 paymod: Implement TLV onion payload generation 2020-07-01 12:19:02 +02:00
Christian Decker
958eb41cbb paymod: Do not pass cmd to sub-payments, plugin suffices
We were passing the `cmd` instance around where `plugin` suffices (used to
start RPC calls and logs).
2020-07-01 12:19:02 +02:00
Christian Decker
df94ec35ba paymod: Do not reply to the same JSON-RPC command multiple times 2020-07-01 12:19:02 +02:00
Christian Decker
c35df400b2 paymod: Maintain a list of current and past payments
We need to keep them around so we can inspect them later. We'll also need a
background cleanup every once in a while to free some memory. More on that in
a future commit.
2020-07-01 12:19:02 +02:00
Christian Decker
8207b4eac8 paymod: Use reasonable partids
We were just handwaving the partid generation, which broke some tests that
expected the first payment attempt to always have partid=0, so here we just
track the partids assigned in the payment tree, starting at 0.
2020-07-01 12:19:02 +02:00
Christian Decker
04c9c5e0d1 paymod: Collect and return results of a tree of partial payments
The status of what started as a simple JSON-RPC call is now spread across an
entire tree of partial payments and payment attempts. So we collect the status
in a single struct in order to report back success of failure.
2020-07-01 12:19:02 +02:00
Christian Decker
4fec969062 paymod: Parse and store the waitsendpay result
This is necessary so we can later aggregate across an entire tree of attempts
and report success or failure to the RPC caller.
2020-07-01 12:19:02 +02:00
Christian Decker
6fb81bf203 paymod: Call waitsendpay on the sendonion we just queued 2020-07-01 12:19:02 +02:00
Christian Decker
d8ebe6fbcd paymod: Parse createonion result and call sendonion 2020-07-01 12:19:02 +02:00
Christian Decker
d37b8548fb paymod: Call createonion to generate the onion and associated data
After we gave each modifier a chance to have its say, we can now proceed to
generate the onion that's going to be sent in the next step.
2020-07-01 12:19:02 +02:00
Christian Decker
5f32cfe9cd paymod: Implement legacy onion payload computation
This is just for testing for now, TLV payload computation will come next. We
stage all the payloads in deserialized form so modifiers can modify them more
easily and serialize them only before actually calling `createonion`.
2020-07-01 12:19:02 +02:00
Christian Decker
5ef7297e51 paymod: Add a getinfo call on payment_start to get the blockheight
This is necessary so we can build the absolute locktimes in the next step. For
now just fetch the blockheight on each (sub-)payment, later we can reuse the
root blockheight if it ends up using too much traffic.
2020-07-01 12:19:02 +02:00
Christian Decker
3c3e2c9c8f paymod: Implement getroute call 2020-07-01 12:19:02 +02:00
Christian Decker
ce0025c95c paymod: Implement bubbling results up the hierarchy of payments
A payment is considered finished if it is in a final state (success or
failure) or all its sub-payments are finished. If that's the case we notify
`payment_finished` and bubble up through `payment_child_finished`, eventually
bubbling up to the root, which can then report success of failure back to the
RPC command that initiated the whole process.
2020-07-01 12:19:02 +02:00
Christian Decker
5c32e33aab paymod: Add a retry modifier that retries payments on failure
This is likely a bit of overkill for this type of functionality, but it is a
nice first use-case of how functionality can be compartmentalized into
modifiers. If makes swapping retry mechanisms in and out really simple.
2020-07-01 12:19:02 +02:00
Christian Decker
aeb5cc0b7c paymod: Generate type-safe accessor functions for modifier data
This should make it easy for JSON-RPC functions and modifiers to get the
associated data for a given modifier name. Useful if a modifier needs to
access its parent's modifier data, or in other functions that need to access
modifier data, e.g., when passing destination pointers into the `param()`
call.
2020-07-01 12:19:02 +02:00
Christian Decker
23b4dca3c7 paymod: Add a simple test-command to test the paymod state-machine
This commit can be reverted/skipped once we have implemented all the logic and
have feature parity with the normal `pay`. It's main purpose is to expose the
unfinished functionality to test it, without completely breaking the existing
`pay` command.
2020-07-01 12:19:02 +02:00
Christian Decker
5d1725209d paymod: Implement base state-machine transitions
The actual steps are mocked out, but we can already run through the various
phases of a payment, and the modifiers should be called for each state.
2020-07-01 12:19:02 +02:00
Christian Decker
e108ebe559 paymod: Add base state-machine for payment flow 2020-07-01 12:19:02 +02:00
Christian Decker
8138ef136f plugin: Add a data backend for the new payment state-machine 2020-07-01 12:19:02 +02:00
Vasil Dimov
a3a37ea4ce build: fix compilation on i386
```
plugins/keysend.c:136:47: error: format specifies type 'unsigned long' but the argument has type 'time_t' (aka 'int') [-Werror,-Wformat]
        ki->label = tal_fmt(ki, "keysend-%lu.%09lu", now.ts.tv_sec, now.ts.tv_nsec);
                                         ~~~         ^~~~~~~~~~~~~
                                         %d
```

Changelog-None
2020-06-28 09:36:30 +00:00
Antoine Poinsot
e0aef66ce2 plugins: make the autoclean plugin static
The autocleaning will only happen if the autocleaninvoice-cycle startup
option is passed, which cannot happen if the plugin is started
post-startup.
Thus, it's less misleading for users to restrict its usage to startup.

Changelog-Added: plugins: The `autoclean` plugin is now static (you cannot manage it with the `plugin` RPC command anymore).

Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
2020-06-24 15:29:39 +02:00
niftynei
2d5c61dfc1 psbt: methods to mutate psbt in place
add the missing psbt helpers for adding and removing an input and output
2020-05-21 18:45:07 +09:30
Antoine Poinsot
d67743d511 bcli cleanups
Correct some comments wrt estimatefees, add a constructor for bitcoind

Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
2020-05-20 06:09:24 +09:30
Antoine Poinsot
f598caa60d config: don't ignore the --commit-fee option.
We did not take the value of --commit-fee into account : this removes
the unused option from lightningd and instead registers it in bcli,
where we set the actual feerate of commitment transactions. This also
corrects the documentation.

Changelog-Fixed: config: we now take the --commit-fee parameter into account.
Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
2020-05-20 06:09:24 +09:30
niftynei
fbe50e087a setup: create a common setup which will handle the wally-context
Since we now over-write the wally malloc/free functions, we need to do
so for tests as well. Here we pull up all of the common setup/teardown
logic into a separate place, and update the tests that use libwally to
use the new common_setup core

Changelog-None
2020-05-19 13:35:42 +09:30
Rusty Russell
cfb320c972 wire: move remaining bitcoin functions out to bitcoin/ files.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2020-05-18 14:51:12 +02:00