taler-docs

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

commit 836ec500bdbdb91a07110b1455f0f6cf2d26fa7c
parent 2af43b6630d630e3a93e7b7b0f1973811ead7965
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  9 Apr 2023 15:16:03 +0200

spec push debit

Diffstat:
MMakefile | 4+++-
Mdesign-documents/037-wallet-transactions-lifecycle.rst | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Atransaction-push-debit-states.dot | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 116 insertions(+), 19 deletions(-)

diff --git a/Makefile b/Makefile @@ -67,6 +67,8 @@ transaction-tip-states.png: transaction-tip-states.dot dot -Tpng transaction-tip-states.dot > transaction-tip-states.png 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 coin.png: coin.dot dot -Tpng coin.dot > coin.png deposit.png: deposit.dot @@ -74,7 +76,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 +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 # 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 @@ -686,43 +686,82 @@ States and transitions: * ``initial`` - In this state, the user is not yet able to send the payment to somebody else. + In this state, the user is asked to specify details about the payment. - * ``[action:abort] => aborted``: The payment is aborted early, before the wallet even had the chance to create a purse. - No fees are incurred. - * ``[processing-success] => pending(purse-created)``: The wallet was able to successfully create a purse. + * ``[action:form-data] => pending(purse-create)``: The wallet is creating a purse. -* ``pending(purse-created)`` +* ``pending(purse-create)`` + + * ``[process-success] => pending(qr-ready)``: The wallet has created the purse. + * ``[process-failure] => aborting(refund)``: The purse creation failed. + * ``[action:suspend] => suspended(purse-create)``: The user suspended the operation. + +* ``suspended(purse-create)`` + + * ``[action:resume] => pending(purse-create)``: The user resumed the operation. + * ``[action:abort] => aborting(refund)``: The user aborted the operation. + +* ``pending(qr-ready)`` In this state, the user can send / show the ``taler://`` URI or QR code to somebody else. * ``[action:abort] => aborting(delete-purse)``: The user aborts the P2P payment. The wallet tries to reclaim money in the purse. - * ``[purse-timeout] => aborting(refresh)``: The other party was too slow. + * ``[purse-timeout] => aborting(refresh)``: The other party was too slow and the purse has now expired. * ``[poll-success] => pending(refundable)``: The other party has accepted the payment. - * ``[poll-error] => aborting(refresh)``: The exchange claims that there is a permanent error regarding the purse. + * ``[poll-error] => aborting(refresh)``: The exchange claims that there is a permanent error regarding the purse. (FIXME(CG): not clear that this is the best transition! Could also go to ``aborting(refund)`` or ``aborting(delete-purse)``; best choice may depend on the specific error returned.) * ``aborting(delete-purse)`` + The wallet is deleting the purse to prevent the receiver from merging it and to reclaim the funds in it. + * ``[processed-success] => aborting(refresh)``: The purse was deleted successfully, and refunded coins must be refreshed. * ``[processed-failed(already-merged)] => done``: The other party claimed the funds faster that we were able to abort. * ``[processed-failed(other)] => aborting(refresh)``: The exchange reports a permanent error. We still try to refresh. - * ``[action:abort-force] => failed`` + * ``[action:abort-force] => failed``: The user explicitly asked us to give up and accepted the possible loss of funds. + +* ``aborting(refund)`` + + We abandon the purse that was never fully funded and ask for the deposited coins to be refunded. + + * ``[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. * ``aborting(refresh)`` - * ``[processed-success] => aborted)``: Refresh group finished. Aborting was successful, money was reclaimed - * ``[processed-failed] => failed)``: Refresh group failed to complete with a permanent error. - * ``[action:abort-force] => failed``: XXX will this abort the refresh session or just orphan it? + * ``[processed-success] => aborted``: Refresh group finished. Aborting was successful, money was reclaimed. + * ``[processed-failed] => failed``: Refresh group failed to complete with a permanent error. + * ``[action:abort-force] => failed``: The user explicitly asked us to give up and accepted the possible loss of funds. * ``pending(refundable)`` - * ``[auto-refund-timeout] => done`` + FIXME(CG): I do not understand this state. Left out. Remove? -* ``aborting(refund)`` + * ``[auto-refund-timeout] => done``: FIXME(CG): I do not think we should have auto-refunds with P2P payments. Remove? - * ``[processed-success] => aborted(refunded)`` - * ``[processed-failure] => aborting(refresh)`` +* ``done`` + + The transfer was successful. + * ``[action:delete] => deleted`` + +* ``aborted`` + + The transfer was aborted. Except for fees, the money was recovered. + + * ``[action:delete] => deleted`` + +* ``failed`` + + The transfer failed. Money was lost. Unless on a forced abort, we should probably complain to the auditor. + + * ``[action:delete] => deleted`` + +* ``deleted`` + + All memory of the push debit operation is lost. + +.. image:: ../transaction-push-debit-states.png + :width: 400 Transaction Type: Peer Push Credit @@ -735,7 +774,7 @@ States and transitions: * ``initial`` -Wallet read the taler:// URI and the transaction was initialized + Wallet read the taler:// URI and the transaction was initialized * ``[processed-success] => pending(withdrawing)``: Merging the reserve was successful @@ -771,7 +810,7 @@ TODO: Also specify variant where account reserve needs to be created / funded fi * ``initial`` -Wallet created the transaction + Wallet created the transaction * ``[action:success] => pending(purse-created)`` @@ -812,7 +851,7 @@ Transaction Type: Peer Pull Debit * ``initial`` -Wallet read the taler:// URI + Wallet read the taler:// URI * ``[action:success] => pending(invoice-downloaded)`` diff --git a/transaction-push-debit-states.dot b/transaction-push-debit-states.dot @@ -0,0 +1,56 @@ +digraph G { + + initial[label="", shape="circle"]; + pending_create[label="pending(purse-create)"]; + suspended_create[label="suspended(purse-create)", shape="box"]; + pending_qr[label="pending(qr-ready)"]; + aborting_delete[label="aborting(delete-purse)"]; + aborting_refresh[label="aborting(refresh)"]; + aborting_refund[label="aborting(refund)"]; + + // FIXME(CG): operation unclear + // pending_refundable[label="pending(refundable)"]; + + done[label="done", shape="box"]; + aborted[label="aborted", shape="box"]; + failed[label="failed", shape="box"]; + deleted[label="deleted", shape="box"]; + + subgraph { + rank = same; done; aborted; failed; + } + + initial->pending_create [color="blue", label="push debit form data"]; + + pending_create->suspended_create [color="blue", label="suspend"]; + pending_create->aborting_refund [color="red", label="failure"]; + pending_create->pending_qr; + + suspended_create->pending_create [color="blue", label="resume"]; + suspended_create->aborting_refund [color="blue", label="abort"]; + + pending_qr->aborting_delete [color="blue", label="abort"]; + pending_qr->aborting_refresh [label="purse-timeout"]; + pending_qr->done [label="poll-success"]; + + // FIXME(CG): or go to delete_purse? Or just retry? + pending_qr->aborting_refresh [color="red", label="poll-failure"]; + + aborting_delete->aborting_refresh; + aborting_delete->done [color="red", label="processed-failed\n(already-merged)"]; + aborting_delete->aborting_refresh [color="red", label="failed(other)"]; + aborting_delete->failed [color="blue", label="abort-force"]; + + aborting_refresh->aborted; + aborting_refresh->failed [color="red", label="failed"]; + aborting_refresh->failed [color="blue", label="abort-force"]; + + aborting_refund->aborting_refresh; + aborting_refund->aborting_refresh [color="red", label="failed"]; + aborting_refund->failed [color="blue", label="abort-force"]; + + done->deleted [color="blue", label="delete"]; + aborted->deleted [color="blue", label="delete"]; + failed->deleted [color="blue", label="delete"]; + +}