Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persist swap phase in db #1079

Closed
2 of 3 tasks
kilrau opened this issue Jul 3, 2019 · 1 comment · Fixed by #1081
Closed
2 of 3 tasks

Persist swap phase in db #1079

kilrau opened this issue Jul 3, 2019 · 1 comment · Fixed by #1081
Assignees
Labels
P1 top priority

Comments

@kilrau
Copy link
Contributor

kilrau commented Jul 3, 2019

Basics: all measures to handle failures/attacks in a swap flow gracefully (#942 ) require the node to know which phase the swap is in. This issue is about persisting the SwapPhase & SwapState (reason to be in that state as per types.ts) in db after each step in the protocol, read it after restarts/crashes and display swaps in critical phases in getinfo.

Status Quo

Currently these SwapPhases are already present, but only success/failure is persisted in the swapdeals table in xud.db:

export enum SwapPhase {
  /** The swap has been created locally. */
  SwapCreated = 0,
  /** The swap has been sent to a peer to request approval. */
  SwapRequested = 1,
  /** The terms of the swap have been agreed to, and we will attempt to execute it. */
  SwapAgreed = 2,
  /**
   * We have commanded swap client to send payment according to the agreed terms. The payment (and swap)
   * could still fail due to no route with sufficient capacity, lack of cooperation from the
   * receiver or any intermediary node along the route, or an unexpected error from swap client.
   */
  SendingAmount = 3,
  /** We have received the agreed amount of the swap, and the preimage is now known to both sides. */
  AmountReceived = 4,
  /** The swap has been formally completed and both sides have confirmed they've received payment. */
  SwapCompleted = 5,
}

TODO

  • Persist each phase change in db, only continue with next step if phase was successfully stored in db
  • New swap phases as per Swap Flow without breaking changes:
export enum SwapPhase {
  /** Role Taker: The swap has been created locally. */
  SwapCreated = 0,

  /** Role Taker: The swap, stating currencies and amounts has been sent to the maker to request approval. */
  SwapRequested = 1,

  /**
  * Role Maker: We set the agreed currency and amount (can be be less than requested) of the swap and we successfully sent a `SwapAccepted` packet with these details to the Taker. Or successfully declined swap with `SwapFailed` packet.*/
  * Role Taker: The currency and an amount of the swap have been agreed to or declined (we received the `SwapAccepted` or `SwapFailed` packet from the Maker)
*/
  SwapAgreed = 2,

  /**
   * Role Taker: We have commanded swap client to send payment (leg 1) according to the agreed currency and amount of the received `SwapAccepted` packet. This can fail due to no route with sufficient capacity, lack of cooperation from the eceiver or any intermediary node along the route, or an unexpected error from swap client. Result stored in `state`.
   * Role Maker: Sending Payment (leg 2) AFTER received taker's payment (phase 4). Can fail due to no route, see above.
   */
  SendingPayment = 3,

  /** 
   * Role Taker: We have received the agreed amount of the swap as an in-flight HTLC (leg 2)
   * Role Maker: We have received the agreed amount of the swap as an in-flight HTLC (leg 1)
   */
  PaymentReceived = 4,

  /** 
   * Role Taker: Role Taker: Successfully revealed preimage and claimed payment on leg 2.
   * Role Maker: Successfully claimed payment on leg 1 (after phase 7).
   */
  PaymentClaimed = 6,

  /**  Role Maker: Successfully received preimage from Taker. */
  PreimageReceived = 7,

 /** Role Taker+Maker: The swap has been formally completed and both sides have confirmed they've received payment OR collaboratively failed the swap. */
  SwapCompleted = 5,
}
  • Display swaps in stages which are NOT 5 with some details (tbd) in getinfo to bring these to the users's attention. Then user can use ID to search the log for details.
@kilrau kilrau assigned ghost Jul 3, 2019
@kilrau kilrau mentioned this issue Jul 3, 2019
5 tasks
@kilrau kilrau assigned sangaman and unassigned ghost Jul 3, 2019
@kilrau kilrau mentioned this issue Jul 3, 2019
29 tasks
@ghost
Copy link

ghost commented Jul 4, 2019

The new phases look good. I'm thinking we might want to separate the phases so that they are specific to the role SendingPaymentTaker, SendingPaymentMaker instead of SendingPayment.

I believe this would make the debugging experience better/more readable.

@kilrau kilrau added the P1 top priority label Jul 4, 2019
sangaman added a commit that referenced this issue Jul 5, 2019
This commit persists the state of swap deals to the database upon each
phase change once a deal has been accepted to. This is done to be able
to prevent loss of funds and recover gracefully from any active swaps
should `xud` crash unexpectedly.

This is the first step towards closing #1079.
sangaman added a commit that referenced this issue Jul 5, 2019
This commit persists the state of swap deals to the database upon each
phase change once a deal has been accepted to. This is done to be able
to prevent loss of funds and recover gracefully from any active swaps
should `xud` crash unexpectedly.

This is the first step towards closing #1079.
sangaman added a commit that referenced this issue Jul 5, 2019
This commit persists the state of swap deals to the database upon each
phase change once a deal has been accepted to. This is done to be able
to prevent loss of funds and recover gracefully from any active swaps
should `xud` crash unexpectedly.

This is the first step towards closing #1079.
sangaman added a commit that referenced this issue Jul 5, 2019
This commit attempts to recover swap deals that were interrupted due to
a system or `xud` crash. In the case where we are the maker and have
attempted to send payment for the second leg of the swap, we attempt to
query the swap client for the preimage of that payment in case it went
through. We can then use that preimage to try to claim the payment from
the first leg of the swap. In all other cases, we simply attempt to
close any open invoices and mark the swap deal as having errored.

Raiden currently does not expose an API call to query for the preimage
of a completed payment.

The recovery attempts happen once on `xud` startup by looking for any
swap deals in the database that have an `Active` state.

Closes #1079.
sangaman added a commit that referenced this issue Jul 5, 2019
This commit attempts to recover swap deals that were interrupted due to
a system or `xud` crash. In the case where we are the maker and have
attempted to send payment for the second leg of the swap, we attempt to
query the swap client for the preimage of that payment in case it went
through. We can then use that preimage to try to claim the payment from
the first leg of the swap. In all other cases, we simply attempt to
close any open invoices and mark the swap deal as having errored.

Raiden currently does not expose an API call to query for the preimage
of a completed payment.

The recovery attempts happen once on `xud` startup by looking for any
swap deals in the database that have an `Active` state.

Closes #1079.
sangaman added a commit that referenced this issue Jul 7, 2019
This commit attempts to recover swap deals that were interrupted due to
a system or `xud` crash. In the case where we are the maker and have
attempted to send payment for the second leg of the swap, we attempt to
query the swap client for the preimage of that payment in case it went
through. We can then use that preimage to try to claim the payment from
the first leg of the swap. In all other cases, we simply attempt to
close any open invoices and mark the swap deal as having errored.

Raiden currently does not expose an API call to query for the preimage
of a completed payment.

The recovery attempts happen once on `xud` startup by looking for any
swap deals in the database that have an `Active` state.

Closes #1079.
sangaman added a commit that referenced this issue Jul 7, 2019
This commit attempts to recover swap deals that were interrupted due to
a system or `xud` crash. In the case where we are the maker and have
attempted to send payment for the second leg of the swap, we attempt to
query the swap client for the preimage of that payment in case it went
through. We can then use that preimage to try to claim the payment from
the first leg of the swap. In all other cases, we simply attempt to
close any open invoices and mark the swap deal as having errored.

Raiden currently does not expose an API call to query for the preimage
of a completed payment.

The recovery attempts happen once on `xud` startup by looking for any
swap deals in the database that have an `Active` state.

Closes #1079.
sangaman added a commit that referenced this issue Jul 8, 2019
This commit persists the state of swap deals to the database upon each
phase change once a deal has been accepted to. This is done to be able
to prevent loss of funds and recover gracefully from any active swaps
should `xud` crash unexpectedly.

This is the first step towards closing #1079.
sangaman added a commit that referenced this issue Aug 5, 2019
This commit persists the state of swap deals to the database upon each
phase change once a deal has been accepted to. This is done to be able
to prevent loss of funds and recover gracefully from any active swaps
should `xud` crash unexpectedly.

This is the first step towards closing #1079.
sangaman added a commit that referenced this issue Aug 5, 2019
This commit persists the state of swap deals to the database upon each
phase change once a deal has been accepted to. This is done to be able
to prevent loss of funds and recover gracefully from any active swaps
should `xud` crash unexpectedly.

This is the first step towards closing #1079.
sangaman added a commit that referenced this issue Aug 5, 2019
This commit attempts to recover swap deals that were interrupted due to
a system or `xud` crash. In the case where we are the maker and have
attempted to send payment for the second leg of the swap, we attempt to
query the swap client for the preimage of that payment in case it went
through. We can then use that preimage to try to claim the payment from
the first leg of the swap. In case the payment is knkown to have failed,
we simply attempt to close any open invoices and mark the swap deal as
having errored.

If an outgoing payment is still in flight and we do not have the
preimage for it, we add it to a set of "pending" swaps and check on it
on a scheduled interval until we can determine whether it has failed
or succeeded.

A new `SwapRecovery` class is introduced to contain the logic for
recovering interrupted swap deals and for tracking swaps that are
still pending.

Raiden currently does not expose an API call to push a preimage to claim
an incoming payment or to reject an incoming payment, instead we print
a warning to the log for now.

The recovery attempts happen on `xud` startup by looking for any swap
deals in the database that have an `Active` state.

Closes #1079.
sangaman added a commit that referenced this issue Aug 26, 2019
This commit attempts to recover swap deals that were interrupted due to
a system or `xud` crash. In the case where we are the maker and have
attempted to send payment for the second leg of the swap, we attempt to
query the swap client for the preimage of that payment in case it went
through. We can then use that preimage to try to claim the payment from
the first leg of the swap. In case the payment is known to have failed,
we simply attempt to close any open invoices and mark the swap deal as
having errored.

If an outgoing payment is still in flight and we do not have the
preimage for it, we add it to a set of "pending" swaps and check on it
on a scheduled interval until we can determine whether it has failed
or succeeded.

A new `SwapRecovery` class is introduced to contain the logic for
recovering interrupted swap deals and for tracking swaps that are
still pending.

Raiden currently does not expose an API call to push a preimage to claim
an incoming payment or to reject an incoming payment, instead we print
a warning to the log for now.

The recovery attempts happen on `xud` startup by looking for any swap
deals in the database that have an `Active` state.

Closes #1079.
sangaman added a commit that referenced this issue Sep 11, 2019
This commit attempts to recover swap deals that were interrupted due to
a system or `xud` crash. In the case where we are the maker and have
attempted to send payment for the second leg of the swap, we attempt to
query the swap client for the preimage of that payment in case it went
through. We can then use that preimage to try to claim the payment from
the first leg of the swap. In case the payment is known to have failed,
we simply attempt to close any open invoices and mark the swap deal as
having errored.

If an outgoing payment is still in flight and we do not have the
preimage for it, we add it to a set of "pending" swaps and check on it
on a scheduled interval until we can determine whether it has failed
or succeeded.

A new `SwapRecovery` class is introduced to contain the logic for
recovering interrupted swap deals and for tracking swaps that are
still pending. Any pending swaps are listed in the `GetInfo` response.

Raiden currently does not expose an API call to push a preimage to claim
an incoming payment or to reject an incoming payment, instead we print
a warning to the log for now.

The recovery attempts happen on `xud` startup by looking for any swap
deals in the database that have an `Active` state.

This commit includes a suite of test cases for the newly added
functionality.

Closes #1079.
sangaman added a commit that referenced this issue Sep 11, 2019
This commit attempts to recover swap deals that were interrupted due to
a system or `xud` crash. In the case where we are the maker and have
attempted to send payment for the second leg of the swap, we attempt to
query the swap client for the preimage of that payment in case it went
through. We can then use that preimage to try to claim the payment from
the first leg of the swap. In case the payment is known to have failed,
we simply attempt to close any open invoices and mark the swap deal as
having errored.

If an outgoing payment is still in flight and we do not have the
preimage for it, we add it to a set of "pending" swaps and check on it
on a scheduled interval until we can determine whether it has failed
or succeeded.

A new `SwapRecovery` class is introduced to contain the logic for
recovering interrupted swap deals and for tracking swaps that are
still pending. Any pending swaps are listed in the `GetInfo` response.

Raiden currently does not expose an API call to push a preimage to claim
an incoming payment or to reject an incoming payment, instead we print
a warning to the log for now.

The recovery attempts happen on `xud` startup by looking for any swap
deals in the database that have an `Active` state.

This commit includes a suite of test cases for the newly added
functionality.

Closes #1079.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P1 top priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants