taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit 9e148c42d940ddcfafe1394f0461d40bceabb008
parent 836ec500bdbdb91a07110b1455f0f6cf2d26fa7c
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  9 Apr 2023 17:22:43 +0200

more work on DD37 review

Diffstat:
MMakefile | 4+++-
Mdesign-documents/037-wallet-transactions-lifecycle.rst | 284++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Mtransaction-common-states.dot | 2+-
Mtransaction-deposit-states.dot | 4++--
Mtransaction-payment-states.dot | 9+++++++--
Atransaction-push-credit-states.dot | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtransaction-refresh-states.dot | 5++++-
Mtransaction-refund-states.dot | 11++++++-----
Mtransaction-tip-states.dot | 32+++++++++++++++++---------------
Mtransaction-withdrawal-states.dot | 4++--
10 files changed, 327 insertions(+), 103 deletions(-)

diff --git a/Makefile b/Makefile @@ -69,6 +69,8 @@ transaction-deposit-states.png: transaction-deposit-states.dot dot -Tpng transaction-deposit-states.dot > transaction-deposit-states.png transaction-push-debit-states.png: transaction-push-debit-states.dot dot -Tpng transaction-push-debit-states.dot > transaction-push-debit-states.png +transaction-push-credit-states.png: transaction-push-credit-states.dot + dot -Tpng transaction-push-credit-states.dot > transaction-push-credit-states.png coin.png: coin.dot dot -Tpng coin.dot > coin.png deposit.png: deposit.dot @@ -76,7 +78,7 @@ deposit.png: deposit.dot reserve.png: reserve.dot dot -Tpng reserve.dot > reserve.png -diagrams: arch-api.png coin.png deposit.png reserve.png transaction-common-states.png transaction-withdrawal-states.png transaction-payment-states.png transaction-refund-states.png transaction-refresh-states.png transaction-tip-states.png transaction-deposit-states.png transaction-push-debit-states.png +diagrams: arch-api.png coin.png deposit.png reserve.png transaction-common-states.png transaction-withdrawal-states.png transaction-payment-states.png transaction-refund-states.png transaction-refresh-states.png transaction-tip-states.png transaction-deposit-states.png transaction-push-debit-states.png transaction-push-credit-states.png # The html-linked builder does not support caching, so we diff --git a/design-documents/037-wallet-transactions-lifecycle.rst b/design-documents/037-wallet-transactions-lifecycle.rst @@ -56,7 +56,9 @@ include more information information relevant to the transaction in `abortReason ``suspended``: Similar to a ``aborted`` transaction, but the transaction was could be resumed and may then still succeed. -``failed``: Similar to ``done``, but the transaction could not even be aborted properly. +``failed``: Similar to ``done``, but the transaction could not even be aborted +properly. The user may have lost money. This is likely a case for a report to +the auditor. ``deleted``: A ``deleted`` state is always a final state. We only use this state for illustrative purposes. In the implementation, the data associated @@ -68,13 +70,6 @@ Common Transitions Transitions are actions or other events. -``[action:delete]``: Deleting a transaction -completely deletes the transaction from the database. Depending on the type of -transaction, some of the other data *resulting* from the transaction might -still survive deletion. For example, deleting a withdrawal transaction does not -delete already successfully withdrawn coins. Deleting is only safe (no money lost) -on initial and final states (failed, aborted, done). - ``[action:retry]``: Retrying a transaction *(1.)* stops ongoing long-polling requests for the transaction *(2.)* resets the retry timeout *(3.)* re-runs the handler to process the transaction. Retries are always possible the following @@ -96,11 +91,6 @@ states: ``pending(*)`` and ``aborting(*)``. retries should basically never be > 24h (we can impose a hard cap), the absolute time can just be in the format HH:MM:SS (without day). -``[action:abort]``: Aborting a transaction either directly stops processing for the -transaction and puts it in an ``aborted`` state, or starts the necessary steps to -actively abort the transaction (e.g. to avoid losing money) and puts it in an -``aborting`` state. - ``[action:suspend]``: Suspends a pending transaction, stopping any associated network activities, but with a chance of trying again at a later time. This could be useful if a user needs to save battery power or bandwidth and an @@ -110,22 +100,43 @@ withdrawal operation). ``[action:resume]``: Suspended transactions may be resumed, placing them back into a pending state. -``[action:abort-force]``: Directly puts an ``aborting`` transaction into the -``failed`` state. +``[action:abort]``: Aborting a transaction either directly stops processing for the +transaction and puts it in an ``aborted`` state, or starts the necessary steps to +actively abort the transaction (e.g. to avoid losing money) and puts it in an +``aborting`` state. + +``[action:force-abort]``: Directly puts an ``aborting`` transaction into a +``failed`` state. May result in an ultimate loss of funds (beyond fees) to the +user and thus requires additional consent. +``[action:delete]``: Deleting a transaction completely deletes the transaction +from the database. Depending on the type of transaction, some of the other +data *resulting* from the transaction might still survive deletion. For +example, deleting a withdrawal transaction does not delete already +successfully withdrawn coins. Deleting is only safe (no money lost) on initial +and final states (failed, aborted, done). -Whether aborting or resuming are possible depends on the transaction type, and -usually only one of the two choices should be offered. +``[action:force-delete]``: Directly puts a transaction into a ``deleted`` +state. May result in an ultimate loss of funds (beyond fees) to the user and +thus requires additional consent. + + +Whether aborting, deleting or suspending are possible depends on the +transaction type, and usually only one of the three choices should be offered. .. image:: ../transaction-common-states.png :width: 400 -Boxed labels indicate an end state in which it is safe to delete the -transaction record since no work is due. +Boxed labels indicate an end state in which there is no network activity and +hence no need to give the user a way to abort or suspend the activity. The +circle indicates the initial state. Ovals are states with network activity. -Blue arrows are used for user-triggered actions (via UI buttons). +Blue arrows are used for user-triggered actions (via UI buttons). Purple +arrows are used to indicate externally triggered actions. Black arrows +without labels are used for the normal successful path. Red arrows indicate +failure paths. Common pending sub-states @@ -135,18 +146,18 @@ During the pending state the transaction can go through several sub-states befor reaching a final state. Some of this sub-states are shared between different transaction types: -``kyc-required``: The transaction can't proceed because the user needs to actively -finish a KYC process. Part of a withdrawal process or peer-to-peer push credit. - -``aml-required``: The transaction can't proceed because the user needs to wait for -the exchange operator to conclude an AML investigation by the staff at the exchange. -The user is not expected to take any action and should just wait for the investigation -to conclude. Part of a withdrawal process or peer-to-peer push credit. +``kyc``: The transaction cannot proceed because the user needs to actively +finish a KYC process. The wallet should show the user a hint on how to +start the KYC process. -``aml-frozen``: The staff at the exchange decided that the account needed to be frozen. -The user should contact the exchange provider's customer service department and -seek resolution (possibly through the courts) to avoid loosing the funds for good. -Part of a withdrawal process or peer-to-peer push credit. +``aml``: The transaction can't proceed because the user needs to wait for the +exchange operator to conclude an AML investigation by the staff at the +exchange. There are two AML substates. In the substate ``pending`` the user +is not expected to take any action and should just wait for the investigation +to conclude. In the substate ``frozen`` the staff at the exchange decided that +the account needed to be frozen. The user should contact the exchange +provider's customer service department and seek resolution (possibly through +the courts) to avoid loosing the funds for good. Transaction Type: Withdrawal @@ -193,15 +204,19 @@ Transaction Type: Withdrawal ``suspended(after-wired)`` (treating the ``abort`` action as a ``suspend`` action). - * ``[processed-success] => deleted``: We show a transient message that the operation was aborted. - * ``[processed-error(already-confirmed)] => suspended(after-wired)``: We keep a transaction history entry reminding the user about when the already wired funds will be returned. + * ``[processed-success] => deleted``: We show a transient message that the + operation was aborted. + * ``[processed-error(already-confirmed)] => suspended(after-wired)``: We + keep a transaction history entry reminding the user about when the already + wired funds will be returned. * ``[processed-error(unknown-transaction)] => deleted`` * ``suspended(after-wired)`` - In this state, the wallet should show to the user that the money from the withdrawal - reserve will be sent back to the originating bank account after ``$closing_delay``. - Note that the ``resume`` action should be disabled after ``$closing_delay``. + In this state, the wallet should show to the user that the money from the + withdrawal reserve will be sent back to the originating bank account after + ``$closing_delay``. Note that the ``resume`` action should be disabled + after ``$closing_delay``. * ``[action:delete] => deleted`` * ``[action:resume] => pending(exchange-wait-reserve)`` @@ -369,22 +384,31 @@ Transaction Type: Payment to Merchant is active. If auto refunds are not enabled, we immediately continue to ``done``. - * ``[timeout] => done`` -- This happens when the auto refund set by the contract expired. - * ``[action:abort] => done`` -- The user may explicitly request to abort the auto-refund processing (for example to enable subsequent deletion before the auto-refund delay expires). + * ``[timeout] => done`` -- This happens when the auto refund set by the + contract expired. + * ``[long-poll:refund] => aborting(refund)`` -- An auto-refund was detected. + * ``[action:abort] => done`` -- The user may explicitly request to abort the + auto-refund processing (for example to enable subsequent deletion before + the auto-refund delay expires). * ``aborting(refund)`` The wallet should interact with the merchant to confirm that a refund was approved. - * ``[success] => aborted(refunded)`` - * ``[failure] => aborting(refresh)`` + * ``[success] => aborting(refresh)`` + * ``[failure] => aborting(refresh)``: Try refresh anyway. + * ``[action:force-delete] => deleted``: User may loose money. * ``aborting(refresh)`` The wallet should interact with the exchange to obtain fresh coins for the refunded balance. + * ``[success] => aborted(refunded)`` + * ``[failure] => failed`` + * ``[action:force-delete] => deleted``: User may loose money. + * ``aborted(refunded)`` The purchase ended with a (partial) refund. The state (and UI) should show @@ -392,8 +416,6 @@ Transaction Type: Payment to Merchant balance (due to double-spending being detected during payment), and one or more partial or full refunds. - * ``[URI:refund] => aborting(refund)`` -- The previous refund was partial, - and we have received an additional refund for this transaction. * ``[action:delete] => deleted`` * ``done`` @@ -401,46 +423,49 @@ Transaction Type: Payment to Merchant The purchase is completed. * ``[action:delete] => deleted`` - * ``[repurchase] => pending(repurchase-session-reset)`` -- Another offer became pending for this product. + * ``[repurchase] => pending(repurchase-session-reset)``: Another offer + became pending for this product and we need to update the session so + that the user does not have to buy it again. * ``pending(repurchase-session-reset)`` - The wallet should reset the associated session for the already purchased item. + The wallet should reset the associated session for the already purchased + (digital) item. * ``[success] => done`` * ``[action:abort] => done`` -- User aborted the session reset. * ``deleted`` - When a payment is deleted, associated refunds are always deleted with it. + When a payment is deleted, associated refund transactions are always deleted + with it. .. image:: ../transaction-payment-states.png :width: 800 -Purple arrows are used to indicate transitions triggered in special ways outside -of the user interface for this transaction, such as side-effects of repurchase -detection for another purchase or opening of a refund URI. - Transaction Type: Refund ------------------------ -A refund is a pseudo-transaction that is always associated with a merchant payment transaction. +A refund is a pseudo-transaction that is always associated with a merchant +payment transaction. * ``pending(lookup-refund)`` - We received a ``refund`` URI. Download refund details (like the amount) from the merchant. If the merchant responds with a permanent failure, we only show a transient warning and delete the transaction. + We received a ``refund`` URI. Download refund details (like the amount) from + the merchant. If the merchant responds with a permanent failure, we only + show a transient warning and delete the transaction. * ``[success] => pending(user-accept)`` * ``[action:suspend] => suspended(lookup-refund)`` - * ``[failure] => deleted`` + * ``[failure] => deleted``: A transient warning is shown to the user about the failure. * ``suspended(lookup-refund)`` The user suspended while we were looking up the refund details. Allow resuming or permanent deletion. * ``[action:resume] => pending(lookup-refund)`` - * ``[action:delete] => deleted`` + * ``[action:force-delete] => deleted``: Refund funds will be lost to the user. * ``pending(user-accept)`` @@ -457,6 +482,13 @@ A refund is a pseudo-transaction that is always associated with a merchant payme * ``[processed-success] => pending(refresh)`` * ``[processed-error] => failed``: we received a permanent failure (such as money already wired to the merchant) +* ``suspended(merchant)`` + + Refund processing was suspended while waiting for the merchant. + + * ``[action:resume] => pending(merchant)`` + * ``[action:force-delete] => deleted`` + * ``pending(refresh)`` The wallet is now refreshing the coins. @@ -465,6 +497,12 @@ A refund is a pseudo-transaction that is always associated with a merchant payme * ``[action:suspend] => suspended(refresh)`` * ``[processed-error] => failed``: we received a permanent failure. +* ``suspended(refresh)`` + + Refund processing was suspended while waiting for the refresh to complete. + + * ``[action:resume] => pending(refresh)`` + * ``[action:force-delete] => deleted`` * ``failed`` @@ -497,13 +535,14 @@ the same as if the double-spending transaction had been deleted by the user. * ``[processed-success] => done`` * ``[action:suspend] => suspended`` + * ``[failed] => failed`` * ``suspended`` A refresh operation was suspended by the user. * ``[action:resume] => pending`` - * ``[action:delete] => deleted`` + * ``[action:force-delete] => deleted`` * ``done`` @@ -511,6 +550,12 @@ the same as if the double-spending transaction had been deleted by the user. * ``[action:delete] => deleted`` +* ``failed`` + + The refresh operation failed. The user lost funds. + + * ``[action:delete] => deleted`` + * ``deleted`` All memory of the refresh operation is lost, but of course the resulting @@ -536,7 +581,7 @@ Transaction Type: Tip The user suspended the operation to download the tip data. - * ``[action:delete] => deleted`` + * ``[action:force-delete] => deleted`` * ``[action:resume] => pending(query)`` * ``pending(user)`` @@ -546,7 +591,7 @@ Transaction Type: Tip * ``[tip-expired] => failed`` * ``[action:accept] => pending(pickup)`` - * ``[action:abort] => deleted`` + * ``[action:force-delete] => deleted`` * ``pending(pickup)`` @@ -561,7 +606,7 @@ Transaction Type: Tip The user suspended the operation while the tip was being picked up. - * ``[action:delete] => deleted`` + * ``[action:force-delete] => deleted`` * ``[tip-expired] => failed`` * ``[action:resume] => pending(pickup)`` @@ -579,7 +624,7 @@ Transaction Type: Tip the tip expires, as the wallet balance threshold KYC likely applies even without the tip. - * ``[action:delete] => deleted`` + * ``[action:force-delete] => deleted`` * ``[action:resume] => pending(kyc)`` * ``done`` @@ -641,7 +686,7 @@ Transaction Type: Deposit The user suspended us while we were trying to get a refund. * ``[action:resume] => aborting(refund)`` - * ``[action:delete] => deleted`` + * ``[action:force-delete] => deleted`` * ``aborting(refresh)`` @@ -654,7 +699,7 @@ Transaction Type: Deposit The user suspended us while we were trying to do the refresh. * ``[action:resume] => aborting(refresh)`` - * ``[action:delete] => deleted`` + * ``[action:force-delete] => deleted`` * ``aborted`` @@ -725,6 +770,7 @@ States and transitions: * ``[processed-success] => aborting(refresh)``: After the refund, we still need to refresh the coins. * ``[processed-failure] => aborting(refresh)``: The refund failed, we still try to refresh the coins. + * ``[action:abort-force] => failed``: The user explicitly asked us to give up and accepted the possible loss of funds. * ``aborting(refresh)`` @@ -761,7 +807,7 @@ States and transitions: All memory of the push debit operation is lost. .. image:: ../transaction-push-debit-states.png - :width: 400 + :width: 600 Transaction Type: Peer Push Credit @@ -772,34 +818,124 @@ a ``taler://pay-push`` URI. States and transitions: -* ``initial`` +* ``pending(download)`` - Wallet read the taler:// URI and the transaction was initialized + Wallet read the taler:// URI and is downloading the contract details for the user. - * ``[processed-success] => pending(withdrawing)``: Merging the reserve was successful + * ``[processed-success] => pending(user)``: Contract can be shown to the user. + * ``[action:suspend] => suspended(download)``: User suspended the operation. -* ``pending(withdrawing-coins)`` +* ``suspended(download)`` - * ``[processed-kyc-required] => pending(kyc-required)`` + The download of the purse meta data was suspended by the user. -* ``pending(kyc-required)`` + * ``[action:resume] => pending(download)`` + * ``[action:force-delete] => deleted`` + +* ``pending(user)`` + + User needs to decide about accepting the money. + + * ``[action:accept] => pending(merge)`` + * ``[action:force-delete] => deleted`` + * ``[timeout] => failed``: User took too long to decide. + +* ``pending(merge)`` + + * ``[processed-success] => pending(withdraw)``: Merging the reserve was successful. + * ``[kyc-required] => pending(merge-kyc)``: User must pass KYC checks before the purse can be merged. + * ``[timeout] => failed``: The purse expired before we could complete the merge. + * ``[failure] => failed``: The merge failed permanently. + * FIXME(CG): do we want to allow suspending here? + +* ``pending(merge-kyc)`` + + We cannot merge the purse until passing a KYC check. + The user is shown a hint where to begin the KYC + process and the wallet long-polls on the KYC status. + + * ``[poll-success] => pending(withdraw)`` + * ``[action:suspend] => suspended(kyc)`` + * ``[timeout] => failed``: The purse expired before we could complete the merge. + +* ``suspended(merge-kyc)`` + + We cannot merge the purse until passing a KYC check, + and that check was suspended by the user. + + * ``[action:resume] => pending(kyc)`` + * ``[action:force-delete] => deleted`` + * ``[timeout] => failed``: The purse expired before we could complete the merge. + +* ``pending(withdraw)`` + + The wallet is withdrawing coins from the reserve that was filled by merging + the purse. + + * ``[kyc-required] => pending(withdraw-kyc)`` + * ``[aml-required] => pending(withdraw-aml)`` + * ``[withdraw-failure] => failed`` + * ``[withdraw-success] => done`` + * ``[action:suspend] => suspended(withdraw)`` + +* ``suspended(withdraw)`` + + The user requested the withdraw operation to be suspended. + + * ``[action:resume] => pending(withdraw)`` + * ``[action:force-delete] => deleted``: Money is lost. + +* ``pending(withdraw-kyc)`` + + We cannot withdraw more coins until passing a KYC check. + The user is shown a hint where to begin the KYC + process and the wallet long-polls on the KYC status. * ``[poll-success] => pending(withdrawing-coins)`` - * ``[action:abort] => aborted``: The user will lose the coins they were not able to withdraw yet, unless they - resume the transaction again. Exchange should return non-withdrawn coins discounting closing fee. + * ``[action:suspend] => suspended(withdraw-kyc)`` -* ``aborted`` +* ``suspended(withdraw-kyc)`` + + We cannot withdraw from the reserve until passing a KYC check, + and that check was suspended by the user. + + * ``[action:resume] => pending(withdraw-kyc)`` + * ``[action:force-delete] => deleted``: Money is lost. + +* ``pending(withdraw-aml)`` - * ``[action:resume] => pending(withdrawing-coins)`` -(??) this is not possible since aborted is final + We cannot withdraw more coins until AML rules are satisfied. + The user is shown a hint as to the AML status (pending or frozen). - * ``[action:delete] => deleted``: The user will irrevocable lose coins that were not withdrawn from the reserve yet. -(??) no, i think aborting a push-credit should return to the sender, like a refund + * ``[poll-success] => pending(withdrawing-coins)`` + * ``[action:suspend] => suspended(withdraw-aml)`` + +* ``suspended(withdraw-aml)`` + + We cannot withdraw from the reserve until AML rules are satisfied, + and the status check was suspended by the user. + + * ``[action:resume] => pending(withdraw-aml)`` + * ``[action:delete] => deleted`` + +* ``failed`` + + The operation failed. Details are shown to the user. The money from the purse eventually goes to the sender (or some other wallet that merged it). + + * ``[action:delete] => deleted`` * ``done`` + The operation succeeded. + * ``[action:delete] => deleted``: No money will be lost, the withdrawn coins will be kept +* ``deleted`` + + All memory of the push credit operation is lost. + +.. image:: ../transaction-push-credit-states.png + :width: 600 Transaction Type: Peer Pull Credit diff --git a/transaction-common-states.dot b/transaction-common-states.dot @@ -6,7 +6,7 @@ digraph G { aborted[label="aborted", shape="box"]; aborting[label="aborting"]; failed[label="failed", shape="box"]; - suspended[label="suspended"]; + suspended[label="suspended", shape="box"]; subgraph { rank = same; pending;suspended; diff --git a/transaction-deposit-states.dot b/transaction-deposit-states.dot @@ -27,8 +27,8 @@ digraph G { suspended_abort_refund->aborting_refund [color="blue", label="resume"]; suspended_abort_refresh->aborting_refresh [color="blue", label="resume"]; - suspended_abort_refund->deleted [color="blue", label="delete"]; - suspended_abort_refresh->deleted [color="blue", label="delete"]; + suspended_abort_refund->deleted [color="blue", label="force-delete"]; + suspended_abort_refresh->deleted [color="blue", label="force-delete"]; suspended_deposit->pending_deposit [color="blue", label="resume"]; diff --git a/transaction-payment-states.dot b/transaction-payment-states.dot @@ -1,8 +1,8 @@ digraph G { initial[label="", shape="circle"]; + pending_pr[label="pending(proposed)", shape="box"]; pending_dp[label="pending(claim-proposal)"]; - pending_pr[label="pending(proposed)"]; pending_sp[label="pending(submit-payment)"]; pending_rf[label="pending(refundable)"]; pending_re[label="pending(repurchase-session-reset)"]; @@ -10,6 +10,7 @@ digraph G { aborting_refund[label="aborting(refund)"]; aborting_refresh[label="aborting(refresh)"]; aborted_refund[label="aborted(refunded)", shape="box"]; + failed[label="failed", shape="box"]; done[label="done", shape="box"]; deleted[label="deleted", shape="box"]; @@ -30,12 +31,16 @@ digraph G { pending_sp->aborting_refund [color="blue", label="abort"]; pending_sp->aborting_refund [color="red", label="insufficient balance"]; pending_rf->aborting_refund [label="long-poll:refund"]; aborting_refund->aborting_refresh; - aborting_refund->aborted_refund [color="red", label="failure"]; + aborting_refund->deleted [color="blue", label="force-delete"]; + aborting_refund->aborting_refresh [color="red", label="failure"]; + aborting_refresh->failed [color="red", label="failure"]; aborting_refresh->aborted_refund; + aborting_refresh->deleted [color="blue", label="force-delete"]; aborted_refund->deleted [color="blue", label="delete"]; pending_rf->done [label="timeout"]; pending_rf->done [color="blue", label="abort"]; aborting_unclaim->deleted; + failed->deleted [color="blue", label="delete"]; done->deleted [color="blue", xlabel="delete"]; done->pending_re [color="purple", label="repurchase"]; pending_re->done [color="blue", label="abort"]; diff --git a/transaction-push-credit-states.dot b/transaction-push-credit-states.dot @@ -0,0 +1,75 @@ +digraph G { + + initial[label="", shape="circle"]; + pending_download[label="pending(download)"]; + suspended_download[label="suspended(download)", shape="box"]; + pending_user[label="pending(user)", shape="box"]; + pending_merge[label="pending(merge)"]; + pending_merge_kyc[label="pending(merge-kyc)"]; + suspended_merge_kyc[label="suspended(merge-kyc)", shape="box"]; + pending_withdraw[label="pending(withdraw)"]; + suspended_withdraw[label="suspended(withdraw)", shape="box"]; + pending_withdraw_kyc[label="pending(withdraw-kyc)"]; + suspended_withdraw_kyc[label="suspended(withdraw-kyc)", shape="box"]; + pending_withdraw_aml[label="pending(withdraw-aml)"]; + suspended_withdraw_aml[label="suspended(withdraw-aml)", shape="box"]; + + failed[label="failed", shape="box"]; + done[label="done", shape="box"]; + deleted[label="deleted", shape="box"]; + + subgraph { + rank = same; pending_withdraw; failed; + } + + initial->pending_download [color="blue", label="URI trigger"]; + + pending_download->suspended_download [color="blue", label="suspend"]; + pending_download->pending_user; + + suspended_download->pending_download [color="blue", label="resume"]; + suspended_download->deleted [color="blue", label="force-delete"]; + + pending_user->pending_merge [color="blue", label="accept"]; + pending_user->deleted [color="blue", label="force-delete"]; + pending_user->failed [label="timeout"]; + + pending_merge->pending_withdraw; + pending_merge->pending_merge_kyc [label="kyc-required"]; + pending_merge->failed [label="timeout"]; + pending_merge->failed [color="red", label="failure"]; + + pending_merge_kyc->pending_merge [color="purple", label="poll-success"]; + pending_merge_kyc->suspended_merge_kyc [color="blue", label="suspend"]; + pending_merge_kyc->failed [label="timeout"]; + + suspended_merge_kyc->pending_merge_kyc [color="blue", label="resume"]; + suspended_merge_kyc->deleted [color="blue", label="force-delete"]; + suspended_merge_kyc->failed [label="timeout"]; + + pending_withdraw->pending_withdraw_kyc [label="kyc-required"]; + pending_withdraw->pending_withdraw_aml [label="aml-required"]; + pending_withdraw->done; + pending_withdraw->suspended_withdraw [color="blue", label="suspend"]; + pending_withdraw->failed [color="red", label="failure"]; + + suspended_withdraw->pending_withdraw [color="blue", label="resume"]; + suspended_withdraw->deleted [color="blue", label="force-delete"]; + + + pending_withdraw_kyc->suspended_withdraw_kyc [color="blue", label="suspend"]; + pending_withdraw_kyc->pending_withdraw [color="purple", label="poll-success"]; + + suspended_withdraw_kyc->pending_withdraw_kyc [color="blue", label="resume"]; + suspended_withdraw_kyc->deleted [color="blue", label="force-delete"]; + + pending_withdraw_aml->suspended_withdraw_aml [color="blue", label="suspend"]; + pending_withdraw_aml->pending_withdraw [color="purple", label="poll-success"]; + + suspended_withdraw_aml->pending_withdraw_aml [color="blue", label="resume"]; + suspended_withdraw_aml->deleted [color="blue", label="force-delete"]; + + failed->deleted [color="blue", label="delete"]; + done->deleted [color="blue", label="delete"]; + +} diff --git a/transaction-refresh-states.dot b/transaction-refresh-states.dot @@ -4,16 +4,19 @@ digraph G { pending[label="pending"]; suspended[label="suspended", shape="box"]; done[label="done", shape="box"]; + failed[label="failed", shape="box"]; deleted[label="deleted", shape="box"]; initial->pending [color="blue", label="trigger"]; pending->done; pending->suspended [color="blue", label="suspend"]; + pending->failed [color="red", label="failure"]; suspended->pending [color="blue", label="resume"]; - suspended->deleted [color="blue", label="delete"]; + suspended->deleted [color="blue", label="force-delete"]; + failed->deleted [color="blue", label="delete"]; done->deleted [color="blue", label="delete"]; } diff --git a/transaction-refund-states.dot b/transaction-refund-states.dot @@ -2,7 +2,7 @@ digraph G { initial[label="", shape="circle"]; pending_in[label="pending(lookup-refund)"]; - pending_ar[label="pending(user-accept)"]; + pending_ar[label="pending(user-accept)", shape="box"]; pending_me[label="pending(merchant)"]; pending_re[label="pending(refresh)"]; suspended_in[label="suspended(lookup-refund)", shape="box"]; @@ -23,26 +23,27 @@ digraph G { pending_in->pending_ar; pending_in->suspended_in [color="blue", label="suspend"]; + pending_in->deleted [color="red", label="failure"]; suspended_in->pending_in [color="blue", label="resume"]; - suspended_in->deleted [color="blue", label="delete"]; + suspended_in->deleted [color="blue", label="force-delete"]; pending_ar->pending_me [color="blue", label="accept"]; - pending_ar->deleted [color="blue", label="delete"]; + pending_ar->deleted [color="blue", label="force-delete"]; pending_me->pending_re; pending_me->suspended_me [color="blue", label="suspend"]; pending_me->failed [color="red", label="failure"]; suspended_me->pending_me [color="blue", label="resume"]; - suspended_me->deleted [color="blue", label="delete"]; + suspended_me->deleted [color="blue", label="force-delete"]; pending_re->suspended_re [color="blue", label="suspend"]; pending_re->done; pending_re->failed [color="red", label="failure"]; suspended_re->pending_re [color="blue", label="resume"]; - suspended_re->deleted [color="blue", label="delete"]; + suspended_re->deleted [color="blue", label="force-delete"]; done->deleted [color="blue", label="delete"]; diff --git a/transaction-tip-states.dot b/transaction-tip-states.dot @@ -15,29 +15,31 @@ digraph G { initial->pending_query [color="blue", label="URI trigger"]; pending_query->pending_user; - pending_user->pending_pickup [color="blue", label="accept"]; - pending_pickup->pending_kyc; pending_query->suspended_query [color="blue", label="suspend"]; - pending_pickup->suspended_pickup [color="blue", label="suspend"]; - pending_kyc->suspended_kyc [color="blue", label="suspend"]; + pending_query->deleted [color="red", label="failure"]; - pending_kyc->pending_pickup [color="purple", label="kyc"]; + suspended_query->pending_query [color="blue", label="resume"]; + suspended_query->deleted [color="blue", label="force-delete"]; + pending_user->pending_pickup [color="blue", label="accept"]; + pending_user->deleted [color="blue", label="force-delete"]; + pending_user->failed [label="expired"]; + pending_pickup->pending_kyc [label="kyc required"]; + pending_pickup->suspended_pickup [color="blue", label="suspend"]; pending_pickup->done; + pending_pickup->failed [color="red", label="failure"]; - suspended_query->pending_query [color="blue", label="resume"]; suspended_pickup->pending_pickup [color="blue", label="resume"]; - suspended_kyc->pending_kyc [color="blue", label="resume"]; - - suspended_query->deleted [color="blue", label="delete"]; - suspended_pickup->deleted [color="blue", label="delete"]; - suspended_kyc->deleted [color="blue", label="delete"]; - pending_user->deleted [color="blue", label="abort"]; - pending_user->failed [color="red", label="expired"]; suspended_pickup->failed [color="red", label="expired"]; - pending_pickup->failed [color="red", label="failure"]; - pending_query->deleted [color="red", label="failure"]; + suspended_pickup->deleted [color="blue", label="force-delete"]; + + pending_kyc->suspended_kyc [color="blue", label="suspend"]; + + pending_kyc->pending_pickup [color="purple", label="long-poll:kyc"]; + + suspended_kyc->pending_kyc [color="blue", label="resume"]; + suspended_kyc->deleted [color="blue", label="force-delete"]; done->deleted [color="blue", label="delete"]; failed->deleted [color="blue", label="delete"]; diff --git a/transaction-withdrawal-states.dot b/transaction-withdrawal-states.dot @@ -41,8 +41,8 @@ digraph G { pending_ewr->pending_wc [label="exchange-poll:\nreserve ready"]; pending_wc->pending_kyc; pending_wc->pending_aml; - pending_kyc->pending_wc [color="blue",label="kyc"]; - pending_aml->pending_wc [color="purple",label="approve"]; + pending_kyc->pending_wc [color="purple",label="long-poll:kyc"]; + pending_aml->pending_wc [color="purple",label="long-poll:approve"]; pending_kyc->suspended_kyc [color="blue", label="suspend"]; pending_aml->suspended_aml [color="blue", label="suspend"]; suspended_aml->pending_aml [color="blue", label="resume"];