Skip to content

Provide send_payment idempotency guarantees#1761

Merged
TheBlueMatt merged 6 commits intolightningdevkit:mainfrom
TheBlueMatt:2022-10-user-idempotency-token
Nov 3, 2022
Merged

Provide send_payment idempotency guarantees#1761
TheBlueMatt merged 6 commits intolightningdevkit:mainfrom
TheBlueMatt:2022-10-user-idempotency-token

Conversation

@TheBlueMatt
Copy link
Collaborator

@TheBlueMatt TheBlueMatt commented Oct 9, 2022

In c986e52, an MppId was added
to HTLCSource objects as a way of correlating HTLCs which belong
to the same payment when the ChannelManager sees an HTLC
succeed/fail. This allows it to have awareness of the state of all
HTLCs in a payment when it generates the ultimate user-facing
payment success/failure events. This was used in the same PR to
avoid generating duplicative success/failure events for a single
payment.

Because the field was only used as an internal token to correlate
HTLCs, and retries were not supported, it was generated randomly by
calling the KeysInterface's 32-byte random-fetching function.
This also provided a backwards-compatibility story as the existing
HTLC randomization key was re-used for older clients.

In 28eea12 MppId was renamed to
the current PaymentId which was then used expose the
retry_payment interface, allowing users to send new HTLCs which
are considered a part of an existing payment.

At no point has the payment-sending API seriously considered
idempotency, a major drawback which leaves the API unsafe in most
deployments. Luckily, there is a simple solution - because the
PaymentId must be unique, and because payment information for a
given payment is held for several blocks after a payment
completes/fails, it represents an obvious idempotency token.

Here we simply reuse the PaymentHash as the PaymentId in
send_payment, ensuring idempotency of payments with a given hash.

Note that we continue to not store payment data indefinitely, and thus have to tweak the times at which outbound pending payments are removed from the map - for failed payments we no longer automatically time them out ever, and require abandon_payment unconditionally. For successful payments, we continue to remove them after all HTLCs are resolevd, but we do so only after the user has processed the PaymentSent event and some time has passed.

  • Open question - is the Backwards Compatibility note in the suggested release notes worth including?

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants