Commit Graph
100 Commits
Author SHA1 Message Date
Joost Jager 3a2ca434fe htlcswitch/hop: fix logging
Logging for the hop package is controlled via the parent htlcswitch
package. Unfortunately the parent package only controlled the
initialization, but didn't enable the logger when the log level came
in from the main lnd package.
2019-09-09 13:52:35 +02:00
Joost Jager e54b24289f htlcswitch: move hop iterator into htlcswitch/hop package
Prepares for onion blob decoding outside of htlcswitch.
2019-09-05 15:30:31 +02:00
Joost Jager fb565bcd5d Merge pull request #3449 from joostjager/route-success-prob
routerrpc: report route success probability
2019-09-05 12:34:18 +02:00
Joost Jager 6638e1ddde Merge pull request #3466 from cfromknecht/htlcswitch-hop
htlcswitch/hop: new package for hop payload parsing/encapsulation
2019-09-05 12:31:23 +02:00
Joost Jager 99a920f2a3 routerrpc: report route success probability
The intention of adding this field is to make probability based path
finding more transparent and help understand why a route is returned.
2019-09-05 08:35:04 +02:00
Joost Jager 45cd76e9eb lnrpc+invoicesrpc: report invoice htlcs 2019-09-04 19:20:33 +02:00
Joost Jager d6d9ec6aa5 invoices: replay awareness
Previously the invoice registry wasn't aware of replayed htlcs. This was
dealt with by keeping the invoice accept/settle logic idempotent, so
that a replay wouldn't have an effect.

This mechanism has two limitations:

1. No accurate tracking of the total amount paid to an invoice. The total
amount couldn't just be increased with every htlc received, because it
could be a replay which would lead to counting the htlc amount multiple
times. Therefore the total amount was set to the amount of the first
htlc that was received, even though there may have been multiple htlcs
paying to the invoice.

2. Impossible to check htlc expiry consistently for hodl invoices. When
an htlc is new, its expiry needs to be checked against the invoice cltv
delta. But for a replay, that check must be skipped. The htlc was
accepted in time, the invoice was moved to the accepted state and a
replay some blocks later shouldn't lead to that htlc being cancelled.
Because the invoice registry couldn't recognize replays, it stopped
checking htlc expiry heights when the invoice reached the accepted
state. This prevents hold htlcs from being cancelled after a restart.
But unfortunately this also caused additional htlcs to be accepted on an
already accepted invoice without their expiry being checked.

In this commit, the invoice registry starts to persistently track htlcs
so that replays can be recognized. For replays, an htlc resolution
action is returned early. This fixes both limitations mentioned above.
2019-09-04 19:20:31 +02:00
Joost Jager 53eea09b63 channeldb: add now function
Needed for time control in unit tests.
2019-09-04 19:20:29 +02:00
Joost Jager c8fa51f865 invoices: refactor invoice update callback
This commit refactors the invoice registry accept/settle logic so that
it doesn't rely anymore on a set of error values to indirectly
communicate from the update callback to the main function what action is
required on the htlc.
2019-09-04 19:20:27 +02:00
Joost Jager 144856757d channeldb+invoices: move invoice cancel logic into registry
This commit is a continuation of the centralization of invoice state
transition logic in the invoice registry.
2019-09-04 19:20:25 +02:00
Joost Jager 416bc8c68c channeldb+invoices: move hold invoice settle logic into registry
This commit is a continuation of the centralization of invoice state
transition logic in the invoice registry.
2019-09-04 19:20:23 +02:00
Joost Jager ad3522f1a6 channeldb+invoices: move invoice accept or settle logic into registry
As the logic around invoice mutations gets more complex, the friction
caused by having this logic split between invoice registry and channeldb
becomes more apparent. This commit brings a clearer separation of
concerns by centralizing the accept/settle logic in the invoice
registry.

The original AcceptOrSettle method is renamed to UpdateInvoice because
the update to perform is controlled by the callback.
2019-09-04 19:20:21 +02:00
Joost Jager c1345a4117 multi: use separate cltv expiry field from invoice
Now that the Invoice struct contains the decoded final cltv delta value,
the decoding of payment requests can be removed from the invoice
registry.
2019-09-04 19:20:19 +02:00
Joost Jager 4105142c96 channeldb+invoices: add invoice htlcs
This commit adds a set of htlcs to the Invoice struct and
serializes/deserializes this set to/from disk. It is a preparation for
accurate invoice accounting across restarts of lnd.

A migration is added for the invoice htlcs.

In addition to these changes, separate final cltv delta and expiry
invoice fields are created and populated. Previously it was required
to decode this from the stored payment request. The reason to create
a combined commit is to prevent multiple migrations.
2019-09-04 19:20:17 +02:00
Joost Jager 061b34b924 channeldb: add int64 to codec 2019-09-04 19:20:15 +02:00
Joost Jager 05e6b62cb2 cnct+htlcswitch+invoices: report circuit key to invoice registry
Currently the invoice registry cannot tell apart the htlcs that pay to
an invoice. Because htlcs may also be replayed on startup, it isn't
possible to determine the total amount paid to an invoice.

This commit is a first step towards fixing that. It reports the circuit
keys of htlcs to the invoice registry, which forms the basis for
accurate invoice accounting.
2019-09-04 19:20:13 +02:00
Joost Jager 5871d69bde cnct: convert supplement functions to methods 2019-09-04 19:20:11 +02:00
Joost Jager 4fe846af6e invoices/test: extend hodl invoice test
Add logic to specifically exercise the replay behavior of invoice
registry for hodl invoices.
2019-09-04 19:20:09 +02:00
Joost Jager 43bad4af9f invoices: always check htlc amt with invoice amount
Previously a check was made for accepted and settled invoices against
the paid amount. This opens up a probe vector where an attacker can pay
to an invoice with an amt that is higher than the invoice amount and
find out if the invoice is already paid or not.
2019-09-04 19:20:07 +02:00
Joost Jager 762609a169 channeldb: fix suppressed error 2019-09-04 19:20:05 +02:00
Joost Jager d98a22879f invoices/test: clarify test parameters 2019-09-04 19:20:04 +02:00
Joost Jager ff0c5a0d5e routing: process successes in mission control
This commit modifies paymentLifecycle so that it not only feeds
failures into mission control, but successes as well.
This allows for more accurate probability estimates. Previously,
the success probability for a successful pair and a pair with
no history was equal. There was no force that pushed towards
previously successful routes.
2019-08-23 09:15:41 +02:00
Joost Jager 2594abfba1 routing/test: remove unused parameter in mission control test 2019-08-23 09:15:39 +02:00
Joost Jager d9ec158412 routing: stricter payment result interpretation
This commit overhauls the interpretation of failed payments. It changes
the interpretation rules so that we always apply the strongest possible
set of penalties, without making assumptions that would hurt good nodes.

Main changes are:

- Apply different rule sets for intermediate and final nodes. Both types
of nodes have different sets of failures that we expect. Penalize nodes
that send unexpected failure messages.

- Distinguish between direct payments and multi-hop payments. For direct
payments, we can infer more about the performance of our peer because we
trust ourselves.

- In many cases it is impossible for the sender to determine which of
the two nodes in a pair is responsible for the failure. In this
situation, we now penalize bidirectionally. This does not hurt the good
node of the pair, because only its connection to a bad node is
penalized.

- Previously we always penalized the outgoing connection of the
reporting node. This is incorrect for policy related failures. For
policy related failures, it could also be that the reporting node
received a wrongly crafted htlc from its predecessor. By penalizing the
incoming channel, we surely hit the responsible node.

- FailExpiryTooSoon is a failure that could have been caused by any node
up to the reporting node by delaying forwarding of the htlc. We don't
know which node is responsible, therefore we now penalize all node pairs
in the route.
2019-08-17 10:24:09 +02:00
Joost Jager e7a457f1ce routing: query bandwidth hints before each payment attempt
Previously the bandwidth hints were only queried once per payment. This
did not allow for concurrent payments changing channel balances.
2019-08-17 10:24:07 +02:00
Joost Jager 67e40d4433 htlcswitch: always assume an onion error for malformed htlc failures
Previously a temporary channel failure was returning for unexpected
malformed htlc failures. This is not what we want to communicate to the
sender, because the sender may apply a penalty to us only.

Returning the temporary channel failure is especially problematic if we
ourselves are the sender and the malformed htlc failure comes from our
direct peer. When interpretating the failure, we aren't able to
distinguish anymore between our channel not having enough balance and
our peer sending an unexpected failure back.
2019-08-17 10:24:05 +02:00
Joost Jager e135cf7326 routing: penalize all node pairs for unknown outcomes
When an undecryptable failure comes back for a payment attempt, we
previously only penalized our own outgoing connection. However,
any node could have caused this failure. It is therefore better to
penalize all node connections along the route. Then at least we know for
sure that we will hit the responsible node.
2019-08-17 10:24:03 +02:00
Joost Jager c39d7a29cd routing/test: do not test local channel mission control
This commit updates existing tests to not rely on mission control for
pruning of local channels. Information about local channels should
already be up to date before path finding starts. If not, the problem
should be fixed where bandwidth hints are set up.
2019-08-17 10:24:01 +02:00
Joost Jager 45dacd0df1 routing: isolate failure interpretation from mission control
This commit moves the payment outcome interpretation logic into a
separate file. Also, mission control isn't updated directly anymore, but
results are stored in an interpretedResult struct. This allows the
mission control state to be locked for a minimum amount of time and
makes it easier to unit test the result interpretation.
2019-08-17 10:23:59 +02:00
Joost Jager e7af6a077a routing: convert to nillable failure reason
This commit converts several functions from returning a bool and a
failure reason to a nillable failure reason as return parameter. This
will take away confusion about the interpretation of the two separate
values.
2019-08-17 10:23:57 +02:00
Joost Jager 4dd054ae90 multi: remove debug invoices
Debug invoices are rarely used nowadays, but keep asking for maintenance
every time refactoring in primarily the invoice registry occurs. We have
passed the cost/benefit tipping point, so therefore the debug invoice
concept is removed in this commit.

Previously the debughtlc flag also controlled whether hodl masks were
active. It is safe to remove that additional condition because the hodl
masks are still guarded by the dev build tag.
2019-08-14 21:33:03 +02:00
Joost Jager f1769c8c8c routing: convert to node pair based
Previously mission control tracked failures on a per node, per channel basis.
This commit changes this to tracking on the level of directed node pairs. The goal
of moving to this coarser-grained level is to reduce the number of required
payment attempts without compromising payment reliability.
2019-08-13 19:21:37 +02:00
Joost Jager 395e0596c2 invoices: fix synchronization issue with single invoice subscribers
This commit fixes a synchronization issue where a single invoice
subscriber could receive duplicate and/or out of order invoice updates.
2019-08-13 19:02:55 +02:00
Joost Jager 9ab23de197 invoices: create error for invoice registry shutting down 2019-08-13 19:02:53 +02:00
Joost Jager 46e2a9e9b8 invoices: reuse client.notify function 2019-08-13 19:02:51 +02:00
Joost Jager bed2acea33 invoices: remove redundant state field from invoice event 2019-08-13 19:02:50 +02:00
Joost Jager 6ee2c04190 lnrpc/routerrpc: use vertex constructor 2019-08-13 18:45:10 +02:00
Joost Jager a332990d2c routing/route: add vertex constructor from bytes 2019-08-13 18:45:08 +02:00
Joost Jager b610f417d2 routing: extended DirectedNodePair functionality 2019-08-13 18:45:06 +02:00
Joost Jager 5c52efc0eb lnrpc/routerrpc: fix line wrap 2019-08-13 18:45:04 +02:00
Joost Jager 2b4debf42b routing/test: remove unused methods from mock 2019-08-13 18:45:02 +02:00
Joost Jager 98fac9fb99 htlcswitch+invoices: always return incorrect_or_unknown_payment_details
In order to prevent information leaks by nodes probing with a payment
hash, this commit changes exit hop processing so that it always returns
incorrect_or_unknown_payment_details and leaves the prober in the dark
about whether an invoice actually exists.
2019-08-08 11:04:23 +02:00
Joost Jager 922f133fd2 htlcswitch: report incoming htlc time lock with FinalIncorrectCltvExpiry
Previously the time lock in the onion payload was reported. This is no
new information to the sender.
2019-08-08 11:04:21 +02:00
Joost Jager 45b3c647f7 htlcswitch: return final_incorrect_htlc_amount on onion payload mismatch
This commit fixes exit hop behavior to be in line with the lightning
spec.
2019-08-08 11:04:19 +02:00
Joost Jager aabd68ebcd multi: rename FailUnknownPaymentHash to FailIncorrectDetails
Align naming better with the lightning spec. Not the full name of the
failure (FailIncorrectOrUnknownPaymentDetails) is used, because this
would cause too many long lines in the code.
2019-08-08 11:04:17 +02:00
Joost Jager 8681729561 htlcswitch/test: extract failure code assertion to function 2019-08-08 11:04:15 +02:00
Joost Jager 7e7b620355 routing: persist mission control data 2019-07-31 08:44:00 +02:00
Joost Jager 3dc83d1b6b routerrpc: embed routing config 2019-07-29 13:42:59 +02:00
Joost Jager eb4e65e54f channeldb: export route serialization 2019-07-29 13:42:57 +02:00
Joost Jager 67ddb72eab lnwire: create failure message encode/decode functions 2019-07-29 09:38:38 +02:00
Joost Jager 9e26f0d079 routing: define payment result
This commit groups together all payment result data. It is a preparation
for historical payment results being retrieved from the database.
2019-07-29 09:38:36 +02:00
Joost Jager 1507ff6590 routing: extract timestamp from applying payment result
This commit prepares for timestamps being supplied from the database for
processing of historical payment results.
2019-07-29 09:38:34 +02:00
Joost Jager b4a7665bae routing: provide payment id to mission control 2019-07-29 09:38:32 +02:00
Joost Jager 334b6a3bfe routing: move unreadable failure handling into mission control 2019-07-29 09:38:30 +02:00
Joost Jager 934ea8e78d routing: move failure interpretation into mission control 2019-07-29 09:38:26 +02:00
Joost Jager 541e5f4af7 lncli: add use_mc flag 2019-07-18 15:49:30 +02:00
Joost Jager fc337cd34f routing+routerrpc+lnrpc: add option to use mc in queryroutes
A boolean flag is added to the QueryRoutes rpc that allows feeding
mission control probabilities into path finding.
2019-07-18 15:49:29 +02:00
Joost Jager 7f4c42847c lnrpc/routerrpc: create mission control interface 2019-07-18 15:49:27 +02:00
Joost Jager 34b264a3d8 routing: create PathFindingConfig for global parameters 2019-07-18 15:49:25 +02:00
Joost Jager 8055bcf2e0 routing: report failures to mission control directly
As there is no more state kept in the payment session, failure reporting
can go straight to mission control.
2019-07-13 22:38:25 +02:00
Joost Jager dc13da5abb routing: move second chance logic into mission control
If nodes return a channel policy related failure, they may get a second
chance. Our graph may not be up to date. Previously this logic was
contained in the payment session.

This commit moves that into global mission control and thereby removes
the last mission control state that was kept on the payment level.

Because mission control is not aware of the relation between payment
attempts and payments, the second chance logic is no longer based
tracking second chances given per payment.

Instead a time based approach is used. If a node reports a policy
failure that prevents forwarding to its peer, it will get a second
chance. But it will get it only if the previous second chance was
long enough ago.

Also those second chances are no longer dependent on whether an
associated channel update is valid. It will get the second chance
regardless, to prevent creating a dependency between mission control and
the graph. This would interfer with (future) replay of history, because
the graph may not be the same anymore at that point.
2019-07-13 22:38:23 +02:00
Joost Jager d31efddf1b routing: move generateBandwidthHints 2019-07-13 22:38:21 +02:00
Joost Jager 37e2751695 routing+routerrpc: isolate payment session source from mission control 2019-07-13 22:38:19 +02:00
Joost Jager cf3dd3fb94 routing/test: create mission control test context 2019-07-13 22:38:17 +02:00
Joost Jager 2726f50d7c htlcswitch: do not consider unknown failures an error 2019-07-11 19:49:49 +02:00
Joost Jager c6f9517e48 lnwire+htlcswitch: only use references for failure messages
Methods on failure message types used to be defined on value receivers.
This allowed assignment of a failure message to ForwardingError both as
a value and as a pointer. This is error-prone, especially when using a
type switch.

In this commit the failure message methods are changed so that they
target pointer receivers.

Two instances where a value was assigned instead of a reference are
fixed.
2019-07-11 19:49:47 +02:00
Joost Jager 418fe364de htlcswitch: use distinct error for unreadable failures 2019-07-11 19:49:45 +02:00
Joost Jager 0cdae56d28 htlcswitch+routing: make error decryption mockable 2019-07-11 10:37:28 +02:00
Joost Jager 2b47632b26 htlcswitch+routing+routerrpc: return error source as index 2019-07-11 10:37:26 +02:00
Joost Jager 55bef96cf3 htlcswitch/test: stricter error check in TestSwitchSendPayment 2019-07-11 10:37:24 +02:00
Joost Jager 569f821142 routing/test: allow arbitrary graph source nodes 2019-07-11 10:37:22 +02:00
Joost Jager 1e79ddc9bc routerrpc: accept route hints for SendPayment rpc 2019-07-04 09:27:18 +02:00
Joost Jager 5ce04091d8 routing+routerrpc+channeldb: return route on invalid payment details 2019-07-04 09:27:16 +02:00
Joost Jager 7bc56f5a7b routing: add subscriber event constructors 2019-07-04 09:27:14 +02:00
Joost Jager ae46fb00cb routing+channeldb: add more failure reasons 2019-07-04 09:27:12 +02:00
Joost Jager e2af3c0fa7 routerrpc: fix loop variable binding bug in querymc
This bug caused all node pubkey to be the same.
2019-06-26 16:48:46 +02:00
Joost Jager 865801c881 lncli: add reset mission control command 2019-06-19 12:37:32 +02:00
Joost Jager 26b2c79159 lncli: add usage to querymc command 2019-06-19 12:37:30 +02:00
Joost Jager ad2759dc94 lncli: assign category to SendToRoute command 2019-06-19 12:37:28 +02:00
Joost Jager 2e920de292 routing+lnrpc: move default payment timeout out of router
This commit moves the default timeout out of router and thereby fixes a
bug that caused SendToRoute to not return the actual error, but a
timeout result instead. SendToRoute only tries a single route, so a
timeout should never happen.
2019-06-11 08:36:17 +02:00
Joost Jager 9e26e4e8da invoices: check invoice amount even when already accepted or settled 2019-06-10 16:12:10 +02:00
Joost Jager 18c025151a invoices+channeldb: move invoice state check to invoiceregistry 2019-06-10 16:12:08 +02:00
Joost Jager 220c2becb1 lncli: unify payinvoice and sendpayment code
This commit prepares lncli for moving over to routerrpc payment calls.
2019-06-05 12:41:57 +02:00
Joost Jager 2644759924 channeldb: add todo for more detailed failure reasons 2019-06-05 12:41:55 +02:00
Joost Jager f03533c67a routerrpc: convert sendpayment to async
Modify the routerrpc SendPayment api to asynchronous. This allows
callers to pick up a payment after the rpc connection was lost or lnd
was restarted.
2019-06-05 12:41:53 +02:00
Joost Jager 07d289c14e routing: add SendPaymentAsync to router 2019-06-05 12:41:51 +02:00
Joost Jager eb2647e8fc channeldb: add subscription to control tower
Allows other sub-systems to subscribe to payment success and fail
events.
2019-06-05 12:41:49 +02:00
Joost Jager 87d3207baf channeldb+routing: move control tower interface to routing
This commit creates an empty shall for control tower in the routing
package. It is a preparation for adding event notification.
2019-06-05 12:41:47 +02:00
Joost Jager eb700d35e1 routerrpc: extend payment request parameters
Add missing parameters to routerrpc version of SendPayment.
2019-06-05 12:41:45 +02:00
Joost Jager 19d5f8f82c routing: move default cltv assignment out of router
This commit lifts default setting up to the rpc server level, in line
with other payment defaults.
2019-06-05 12:41:43 +02:00
Joost Jager afd86763ac lntypes: add ZeroHash 2019-06-05 12:41:41 +02:00
Joost Jager 054e42f680 routing+routerrpc: expose mission control parameters in lnd config
This commit exposes the three main parameters that influence mission
control and path finding to the user as command line or config file
flags. It allows for fine-tuning for optimal results.
2019-06-04 13:22:50 +02:00
Joost Jager 9b71d90a6e lncli: add querymc command
Adds querymc command to lncli to dump mission control state.
2019-06-04 10:00:29 +02:00
Joost Jager f7982f0f4c routing+routerrpc: expose mission control state over rpc
This commit exposes mission control state for rpc for development
purposes.
2019-06-04 10:00:27 +02:00
Joost Jager 7133f37bb8 routing: global probability based mission control
Previously every payment had its own local mission control state which
was in effect only for that payment. In this commit most of the local
state is removed and payments all tap into the global mission control
probability estimator.

Furthermore the decay time of pruned edges and nodes is extended, so
that observations about the network can better benefit future payment
processes.

Last, the probability function is transformed from a binary output to a
gradual curve, allowing for a better trade off between candidate routes.
2019-06-04 10:00:25 +02:00
Joost Jager 3349d517aa routing: add min probability to path finding
This commit adds a new restriction to pathfinding that allows returning
only routes with a minimum success probability.
2019-06-04 10:00:23 +02:00
Joost Jager 6b70791c2d routing: use probability source in path finding
This PR replaces the previously used edge and node ignore lists in path
finding by a probability based system. It modifies path finding so that
it not only compares routes on fee and time lock, but also takes route
success probability into account.

Allowing routes to be compared based on success probability is achieved
by introducing a 'virtual' cost of a payment attempt and using that to
translate probability into another cost factor.
2019-06-04 10:00:21 +02:00
Joost Jager b6102ad191 routing: remove querybandwidth self node check
This function is only ever called for channels connected to self.
2019-06-04 10:00:19 +02:00
Joost Jager 68f2a04f42 routerrpc: expose mission control reset rpc 2019-06-04 10:00:17 +02:00
Joost Jager 3db48dc53f routing: Route String() method 2019-06-04 10:00:15 +02:00