Commit graph

9 commits

Author SHA1 Message Date
Matt Corallo
7112661b10 Rewrite InvoicePayer retry to correctly handle MPP partial failures
This rewrites a good chunk of the retry logic in `InvoicePayer` to
address two issues:
 * it was not considering the return value of `send_payment` (and
   `retry_payment`) may indicate a failure on some paths but not
   others,
 * it was not considering that more failures may still come later
   when removing elements from the retry count map. This could
   result in us seeing an MPP-partial-failure, failing to retry,
   removing the retries count entry, and then retrying other parts,
   potentially forever.
2021-10-31 17:43:26 +00:00
Matt Corallo
e9e8a7d58d Dont unwrap RouteParameter::expiry_time as users can set it
Users can provide anything they want as `RouteParameters` so we
shouldn't assume any fields are set any particular way, including
`expiry_time` set at all.
2021-10-30 01:53:19 +00:00
Matt Corallo
51dd344f26 Expand InvoicePayer documentation somewhat to clarify edge-cases 2021-10-30 01:53:19 +00:00
Matt Corallo
c53048a40f
Merge pull request #1144 from jkczyz/2021-10-invoice-payer-scoring
Penalize failed channels
2021-10-29 20:16:36 +00:00
Jeffrey Czyz
7a8954e1ca
Notify scorer of failing payment path and channel
Upon receiving a PaymentPathFailed event, the failing payment may be
retried on a different path. To avoid using the channel responsible for
the failure, a scorer should be notified of the failure before being
used to find a new route.

Add a payment_path_failed method to routing::Score and call it in
InvoicePayer's event handler. Introduce a LockableScore parameterization
to InvoicePayer so the scorer is locked only once before calling
find_route.
2021-10-29 14:24:53 -05:00
Matt Corallo
04d4a8f835 Track the amount spent on fees as payments are retried
Especially once we merge the `InvoicePayer` logic soon, we'll want
to expose the total fee paid in the `PaymentSent` event.
2021-10-27 20:43:18 +00:00
Jeffrey Czyz
d9b9916601
Fail payment retry if Invoice is expired
According to BOLT 11:

- after the `timestamp` plus `expiry` has passed
  - SHOULD NOT attempt a payment

Add a convenience method for checking if an Invoice has expired, and use
it to short-circuit payment retries.
2021-10-27 10:54:53 -05:00
Jeffrey Czyz
e523e58152
Support paying zero-value invoices 2021-10-27 10:54:53 -05:00
Jeffrey Czyz
ad4f16b3e6
Add InvoicePayer for retrying failed payments
When a payment fails, it's useful to retry the payment once the network
graph and channel scores are updated. InvoicePayer is a utility for
making payments which will retry any failed payment paths for a payment
up to a configured number of total attempts. It is parameterized by a
Payer and Router for ease of customization and testing.

Implement EventHandler for InvoicePayer as a decorator that intercepts
PaymentPathFailed events and retries that payment using the parameters
from the event. It delegates to the decorated EventHandler after retries
have been exhausted and for other events.
2021-10-27 10:54:39 -05:00