From 2746d09ef06cc06581f5448727ed8bd8d47706ed Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 20 Jan 2021 22:19:11 +0100 Subject: working on DD13 --- design-documents/013-peer-to-peer-payments.rst | 154 +++++++++++++++++++++++-- 1 file changed, 145 insertions(+), 9 deletions(-) (limited to 'design-documents') diff --git a/design-documents/013-peer-to-peer-payments.rst b/design-documents/013-peer-to-peer-payments.rst index c5e529d6..89216449 100644 --- a/design-documents/013-peer-to-peer-payments.rst +++ b/design-documents/013-peer-to-peer-payments.rst @@ -11,8 +11,8 @@ Motivation ========== To be usable as an electronic payment system with cash-like properties, -customers should be able to transfer money between themselves without any -external provider. +customers should be able to transfer money between themselves without +needing to setup anything beyond their wallet(s). Requirements @@ -23,15 +23,109 @@ Requirements direct communication channel between payer and payee should be required. * This customer-to-customer payment must be possible without trusting the other party beyond the point where the money has been received by the payee. Thus, - sharing of coin private keys is not sufficient. + sharing of coin private keys is not sufficient, we need transactional semantics + resulting in exclusive control over the funds by the recipient. * The P2P payment protocol must not allow users to circumvent income transparency. That is, each P2P transaction must be visible on a KYCed transaction ledger (such as a bank account). * The money received via a P2P payment must be usable for further Taler payments with minimal delay. -Proposed Solution -================= +Proposed Solution (CG) +====================== + +.. note:: + + The notion of ``pouch`` used in this proposal differs completely from + the notion of ``pouch`` in the Dold approach. In this proposal, + pouches are used to represent aggregated wire transfers combining + multiple p2p payments between pairs of exchanges. WE NEED A BETTER + WORD. + +A complete solution for customer-to-customer payments consists of three +separate parts: + +1. The payee generates a ``payto://taler/$EXCHANGE_BASE_URL/$RESERVE_PUB`` + target address for which the payee knows the corresponding reserve + private key. The parties must also create a fixed-form contract. + The the contract must specify the amount, a nonce, the reserve public key, + and may include further a **forgettable** details like a subject. + The required information should still be sufficiently compact for a + small QR code or NFC transmission. +2. The payer then performs an ordinary ``/deposit`` operation. +3. The exchange detects the use of the ``taler`` wire method, and if the base + URL of the target exchange differs, initiates a wire transfer to the + ``/wire`` endpoint of the target exchange. For this wire transfer, + the wire transfer subject is set to provide the exchange base URL and + a WTID as with other outgoing wire transfers. Aggregation is possible. + An inbound wire transfer of this type creates a **pouch**. +4. If the (aggregated) wire transfer fails (say the + ``/wire`` endpoint does not resolve to a valid bank account, or + the target exchange closed the pouch), the originating exchange + automatically creates a full refund for the deposit (refund fees still + apply). + + .. note:: + + While the refund **fee** can be reused, these types of refunds + are not approved by a merchant's signature. Thus, we will need + a new message type in the coin history to represent these events. + +5. When the exchange is requested to provide information about + aggregated transfers under the WTID, it provides the contract's + 512-bit hash and the amount. +6. The exchange wire gateway is extended with a request to check the KYC + status of a customer based on a RESERVE_PUB. Possible replies are + in-progress, failed and succeeded. Failed KYCs ultimately result in + pouches being closed. An in-progress status should be accompanied with + information how the customer may complete the KYC check. + + .. note:: + + If a target exchange closes a pouch, the closing fee + applies for every non-merged contract hash associated with the pouch. + Closing a pouch requires the target exchange to perform + a wire transfer for each (non-merged) contract hash, using + a truncated 256-bit contract hash for the wire transfer subject. + That way, the originating exchange can refund the respective + coins. + +7. A new exchange endpoint allows wallets to request a KYC for a + RESERVE_PUB. Such a request may include the requirement to pay + a KYC fee. The KYC fee may be charged to that reserve (if it exists), + or could be waved if the reserve was established via a wire transfer + from a partner bank. +8. When an exchange receives a wire transfer with an exchange base URL + and a WTID (instead of a RESERVE_PUB), it performs a request to the + ``/transfers/$WTID`` API of the originating exchange to obtain a + list of contract hashes. +9. The payee can try to merge incoming payments into a KYC'ed reserve by + POSTing to a new ``/reserve/$RESERVE_PUB/merge`` endpoint. + The POSTing must include a signature by the reserve private key + over the 512-bit contract hash and the (maximally ``forgotten``) + contract (so only nonce, amount and RESERVE_PUB are in the clear). + By doing so, the receiver demonstrates knowledge of the full contract + (the ``forgotten`` fields provide privacy for details irrelevant to + the exchange). + + .. note:: + + A possible optimization is to forgo including the reserve public key + field in the transmitted exchange contract, as it is already in the URL; + however, the RESERVE_PUB MUST be in a well-defined + field of the contract when hashing the contract. + +10. If the exchange has received a matching inbound wire transfer, it adds the + respective balance to the reserve's balance, allowing the KYC'ed customer + to withdraw the funds. The new ``merge`` endpoint should also allow + long-polling. Note that long-polling should be limited to short durations, + as inbound transfers via ``taler-exchange-wirewatch`` cannot cause the long + polling to be resumed, only transfers within the same exchange can benefit + from long polling acceleration. + + +Proposed Solution (Dold) +======================== A complete solution for customer-to-customer payments consists of three separate parts: @@ -39,8 +133,8 @@ separate parts: 1. The mechanism whereby coins are deposited into some address associated with the receiver. 2. A mechanism to ensure that the receiver of a customer-to-customer - payment must have undergone a KYC check. -3. If more than once exchange should be supported, there must be a real-time + payment has undergone a KYC check. +3. If more than once exchange is involved, there must be a real-time settlement layer between involved exchanges. @@ -122,9 +216,51 @@ Alternatives to transfer via a QR code or short text message. -Drawbacks -========= +Drawbacks (Dold) +================ +* pouches introduce new 'pouch' loophole, which could allow a customer + to collect 'income' into a pouch and then 'pay' a merchant by allowing + the merchant to empty the pouches. * The exchange needs to be extended with customer-to-customer pouches (probably the easy part) and bound reserves (possibly falls into the responsibility of LibEuFin). +* error handling (failure in exchange-to-exchange wire transfer, + failure to drain reserve, etc) is unclear from the proposal. Can money get + lost in the case of failures (bad keys, failed KYC)? + + + +Drawbacks (Grothoff) +==================== + +The overall changes required are not small: + +* New KYC fee required in ``/keys`` endpoint (similar to closing and wire fees), + requires extensive work across toolchain (offline signature, etc.) +* New ``taler`` wire method needs special case to possibly bypass + (same exchange scenario, with long-poll trigger) the usual aggregation logic. +* New exchange table(s) required to store inbound amounts by contract hash. + Maybe two tables, one for local exchange p2p and one for remote exchange p2p + payments. +* New exchange table for pouches required (for remote p2p payments). +* New exchange logic required to make ``transfers`` requests for pouches + (another separate process). +* New ``/reserve/$RESERVE_PUB/kyc`` endpoint required. +* New ``/reserve/$RESERVE_PUB/merge`` endpoint required. +* New type of reserve history entries required (``merge``). +* Additional tables to be verified by the auditor. +* ``taler-exchange-closer`` needs additional logic to ``close`` pouches. +* ``taler-exchange-wirewatch`` needs to support receiving pouch closures + and exchange-to-exchange wire transfers with WTIDs. +* A new type of ``refund`` (better name needed) is required to handle + coins re-gaining value from closed pouches. + +Aside from implementation complexity, the solution has the following drawbacks: + +* We have no good way to determine that a p2p payment failed and that the + wallets should try to refresh the spent coin to get the ``refund``. + Wallets will have to basically 'probe' for a plausible time period to + recover funds from failed p2p payments. Alternatively, we may create a + special URI that the payee wallet will generate to inform the payer + about failed p2p payments. Alas, that seems to not be very user-friendly. -- cgit v1.2.3