gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated (e9de3374 -> 409d3e86)


From: gnunet
Subject: [taler-exchange] branch master updated (e9de3374 -> 409d3e86)
Date: Fri, 03 Apr 2020 20:47:54 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a change to branch master
in repository exchange.

    from e9de3374 fix #6148
     new 61cfaa59 update error codes for merchant
     new 02736e40 fix ftbfs
     new 409d3e86 check amount compatibility in history logic

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/include/taler_error_codes.h |  64 +++++++++++++++---------
 src/lib/exchange_api_common.c   | 107 +++++++++++++++++++++-------------------
 src/util/amount.c               |   3 +-
 3 files changed, 98 insertions(+), 76 deletions(-)

diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index 5baf9538..3a6cb39d 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -1120,7 +1120,9 @@ enum TALER_ErrorCode
   /**
    * The exchange failed to provide a meaningful response to a /deposit
    * request.  This response is provided with HTTP status code
-   * #MHD_HTTP_SERVICE_UNAVAILABLE.
+   * #MHD_HTTP_DEPENDENCY_FAILED, or #MHD_HTTP_CONFLICT in case the
+   * exchange reports #TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS (aka double
+   * spending).
    */
   TALER_EC_PAY_EXCHANGE_FAILED = 2101,
 
@@ -1166,17 +1168,18 @@ enum TALER_ErrorCode
   TALER_EC_PAY_FEES_EXCEED_PAYMENT = 2107,
 
   /**
-   * After considering deposit fees, the payment is insufficient to
-   * satisfy the required amount for the contract. This response is
-   * provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
+   * After considering deposit and wire fees, the payment is
+   * insufficient to satisfy the required amount for the contract.  The
+   * client should revisit the logic used to calculate fees it must
+   * cover. This response is provided with HTTP status code
+   * #MHD_HTTP_BAD_REQUEST.
    */
   TALER_EC_PAY_PAYMENT_INSUFFICIENT_DUE_TO_FEES = 2108,
 
   /**
-   * While the merchant is happy to cover all applicable deposit fees,
-   * the payment is insufficient to satisfy the required amount for the
-   * contract.  This response is provided with HTTP status code
-   * #MHD_HTTP_BAD_REQUEST.
+   * Even if we do not consider deposit and wire fees, the payment is
+   * insufficient to satisfy the required amount for the contract.  This
+   * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
    */
   TALER_EC_PAY_PAYMENT_INSUFFICIENT = 2109,
 
@@ -1195,14 +1198,19 @@ enum TALER_ErrorCode
   TALER_EC_PAY_EXCHANGE_TIMEOUT = 2111,
 
   /**
-   * The signature over the contract of the merchant was invalid. This
-   * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
+   * When we tried to find information about the exchange to issue the
+   * deposit, we failed.  This usually only happens if the merchant
+   * backend is somehow unable to get its own HTTP client logic to work.
+   * This response is provided with HTTP status code
+   * #MHD_HTTP_INTERNAL_SERVER_ERROR.
    */
-  TALER_EC_PAY_MERCHANT_SIGNATURE_INVALID = 2113,
+  TALER_EC_PAY_EXCHANGE_LOOKUP_FAILED = 2112,
 
   /**
-   * The refund deadline was after the transfer deadline. This response
-   * is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
+   * The refund deadline in the contract is after the transfer deadline.
+   * This response is provided with HTTP status code
+   * #MHD_HTTP_INTERNAL_SERVER_ERROR as this should have been caught
+   * when the offer was first setup.
    */
   TALER_EC_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE = 2114,
 
@@ -1213,9 +1221,9 @@ enum TALER_ErrorCode
   TALER_EC_PAY_COINS_ARRAY_EMPTY = 2115,
 
   /**
-   * The merchant failed to fetch the merchant's previous state with
-   * respect to a /pay request from its database.  This response is
-   * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
+   * The merchant failed to fetch the contract terms from the merchant's
+   * database.  This response is provided with HTTP status code
+   * #MHD_HTTP_INTERNAL_SERVER_ERROR.
    */
   TALER_EC_PAY_DB_FETCH_PAY_ERROR = 2116,
 
@@ -1226,13 +1234,6 @@ enum TALER_ErrorCode
    */
   TALER_EC_PAY_DB_FETCH_TRANSACTION_ERROR = 2117,
 
-  /**
-   * The transaction ID was used for a conflicing transaction before.
-   * This response is provided with HTTP status code
-   * #MHD_HTTP_BAD_REQUEST.
-   */
-  TALER_EC_PAY_DB_TRANSACTION_ID_CONFLICT = 2118,
-
   /**
    * The merchant failed to store the merchant's state with respect to
    * the transaction in its database.  This response is provided with
@@ -1249,7 +1250,7 @@ enum TALER_ErrorCode
 
   /**
    * The payment is too late, the offer has expired. This response is
-   * provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
+   * provided with HTTP status code #MHD_HTTP_GONE.
    */
   TALER_EC_PAY_OFFER_EXPIRED = 2121,
 
@@ -1321,6 +1322,21 @@ enum TALER_ErrorCode
    */
   TALER_EC_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED = 2131,
 
+  /**
+   * The contract was not fully paid because of refunds. Note that
+   * clients MAY treat this as paid if, for example, contracts must be
+   * executed despite of refunds. This response is provided with HTTP
+   * status code #MHD_HTTP_PAYMENT_REQUIRED.
+   */
+  TALER_EC_PAY_REFUNDED = 2132,
+
+  /**
+   * According to our database, we have refunded more than we were paid
+   * (which should not be possible). This response is provided with HTTP
+   * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
+   */
+  TALER_EC_PAY_REFUNDS_EXCEED_PAYMENTS = 2133,
+
   /**
    * Integer overflow with specified timestamp argument detected. This
    * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 5c56f527..af77d29e 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2015-2017 Taler Systems SA
+  Copyright (C) 2015-2020 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -66,6 +66,7 @@ TALER_EXCHANGE_parse_reserve_history (
   uuid_off = 0;
   for (unsigned int off = 0; off<history_length; off++)
   {
+    struct TALER_EXCHANGE_ReserveHistory *rh = &rhistory[off];
     json_t *transaction;
     struct TALER_Amount amount;
     const char *type;
@@ -89,7 +90,13 @@ TALER_EXCHANGE_parse_reserve_history (
       return GNUNET_SYSERR;
     }
     rhistory[off].amount = amount;
-
+    if (GNUNET_YES !=
+        TALER_amount_cmp_currency (&amount,
+                                   &total_in))
+    {
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
     if (0 == strcasecmp (type,
                          "CREDIT"))
     {
@@ -109,7 +116,7 @@ TALER_EXCHANGE_parse_reserve_history (
         GNUNET_JSON_spec_end ()
       };
 
-      rhistory[off].type = TALER_EXCHANGE_RTT_CREDIT;
+      rh->type = TALER_EXCHANGE_RTT_CREDIT;
       if (GNUNET_OK !=
           TALER_amount_add (&total_in,
                             &total_in,
@@ -127,11 +134,11 @@ TALER_EXCHANGE_parse_reserve_history (
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      rhistory[off].details.in_details.sender_url = GNUNET_strdup (wire_url);
-      rhistory[off].details.in_details.wire_reference = wire_reference;
-      rhistory[off].details.in_details.wire_reference_size =
+      rh->details.in_details.sender_url = GNUNET_strdup (wire_url);
+      rh->details.in_details.wire_reference = wire_reference;
+      rh->details.in_details.wire_reference_size =
         wire_reference_size;
-      rhistory[off].details.in_details.timestamp = timestamp;
+      rh->details.in_details.timestamp = timestamp;
       /* end type==DEPOSIT */
     }
     else if (0 == strcasecmp (type,
@@ -151,7 +158,7 @@ TALER_EXCHANGE_parse_reserve_history (
         GNUNET_JSON_spec_end ()
       };
 
-      rhistory[off].type = TALER_EXCHANGE_RTT_WITHDRAWAL;
+      rh->type = TALER_EXCHANGE_RTT_WITHDRAWAL;
       if (GNUNET_OK !=
           GNUNET_JSON_parse (transaction,
                              withdraw_spec,
@@ -201,9 +208,9 @@ TALER_EXCHANGE_parse_reserve_history (
           GNUNET_JSON_parse_free (withdraw_spec);
           return GNUNET_SYSERR;
         }
-        rhistory[off].details.withdraw.fee = fee;
+        rh->details.withdraw.fee = fee;
       }
-      rhistory[off].details.withdraw.out_authorization_sig
+      rh->details.withdraw.out_authorization_sig
         = json_object_get (transaction,
                            "signature");
       /* Check check that the same withdraw transaction
@@ -248,18 +255,16 @@ TALER_EXCHANGE_parse_reserve_history (
         GNUNET_JSON_spec_fixed_auto ("coin_pub",
                                      &pc.coin_pub),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
-                                     &rhistory[off].details.recoup_details.
-                                     exchange_sig),
+                                     &rh->details.recoup_details.exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
-                                     &rhistory[off].details.recoup_details.
-                                     exchange_pub),
+                                     &rh->details.recoup_details.exchange_pub),
         GNUNET_JSON_spec_absolute_time_nbo ("timestamp",
                                             &pc.timestamp),
         GNUNET_JSON_spec_end ()
       };
 
-      rhistory[off].type = TALER_EXCHANGE_RTT_RECOUP;
-      rhistory[off].amount = amount;
+      rh->type = TALER_EXCHANGE_RTT_RECOUP;
+      rh->amount = amount;
       if (GNUNET_OK !=
           GNUNET_JSON_parse (transaction,
                              recoup_spec,
@@ -268,31 +273,30 @@ TALER_EXCHANGE_parse_reserve_history (
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      rhistory[off].details.recoup_details.coin_pub = pc.coin_pub;
+      rh->details.recoup_details.coin_pub = pc.coin_pub;
       TALER_amount_hton (&pc.recoup_amount,
                          &amount);
       pc.purpose.size = htonl (sizeof (pc));
       pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP);
       pc.reserve_pub = *reserve_pub;
       timestamp = GNUNET_TIME_absolute_ntoh (pc.timestamp);
-      rhistory[off].details.recoup_details.timestamp = timestamp;
+      rh->details.recoup_details.timestamp = timestamp;
 
       key_state = TALER_EXCHANGE_get_keys (exchange);
       if (GNUNET_OK !=
           TALER_EXCHANGE_test_signing_key (key_state,
-                                           &rhistory[off].details.
+                                           &rh->details.
                                            recoup_details.exchange_pub))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
-                                      &pc.purpose,
-                                      &rhistory[off].details.recoup_details.
-                                      exchange_sig.eddsa_signature,
-                                      &rhistory[off].details.recoup_details.
-                                      exchange_pub.eddsa_pub))
+          GNUNET_CRYPTO_eddsa_verify (
+            TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
+            &pc.purpose,
+            &rh->details.recoup_details.exchange_sig.eddsa_signature,
+            &rh->details.recoup_details.exchange_pub.eddsa_pub))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
@@ -300,7 +304,7 @@ TALER_EXCHANGE_parse_reserve_history (
       if (GNUNET_OK !=
           TALER_amount_add (&total_in,
                             &total_in,
-                            &rhistory[off].amount))
+                            &rh->amount))
       {
         /* overflow in history already!? inconceivable! Bad exchange! */
         GNUNET_break_op (0);
@@ -315,17 +319,15 @@ TALER_EXCHANGE_parse_reserve_history (
       struct TALER_ReserveCloseConfirmationPS rcc;
       struct GNUNET_TIME_Absolute timestamp;
       struct GNUNET_JSON_Specification closing_spec[] = {
-        GNUNET_JSON_spec_string ("receiver_account_details",
-                                 &rhistory[off].details.close_details.
-                                 receiver_account_details),
+        GNUNET_JSON_spec_string (
+          "receiver_account_details",
+          &rh->details.close_details.receiver_account_details),
         GNUNET_JSON_spec_fixed_auto ("wtid",
-                                     
&rhistory[off].details.close_details.wtid),
+                                     &rh->details.close_details.wtid),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
-                                     &rhistory[off].details.close_details.
-                                     exchange_sig),
+                                     &rh->details.close_details.exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
-                                     &rhistory[off].details.close_details.
-                                     exchange_pub),
+                                     &rh->details.close_details.exchange_pub),
         TALER_JSON_spec_amount_nbo ("closing_fee",
                                     &rcc.closing_fee),
         GNUNET_JSON_spec_absolute_time_nbo ("timestamp",
@@ -333,8 +335,8 @@ TALER_EXCHANGE_parse_reserve_history (
         GNUNET_JSON_spec_end ()
       };
 
-      rhistory[off].type = TALER_EXCHANGE_RTT_CLOSE;
-      rhistory[off].amount = amount;
+      rh->type = TALER_EXCHANGE_RTT_CLOSE;
+      rh->amount = amount;
       if (GNUNET_OK !=
           GNUNET_JSON_parse (transaction,
                              closing_spec,
@@ -346,34 +348,32 @@ TALER_EXCHANGE_parse_reserve_history (
       TALER_amount_hton (&rcc.closing_amount,
                          &amount);
       GNUNET_CRYPTO_hash (
-        rhistory[off].details.close_details.receiver_account_details,
-        strlen (
-          rhistory[off].details.close_details.receiver_account_details) + 1,
+        rh->details.close_details.receiver_account_details,
+        strlen (rh->details.close_details.receiver_account_details) + 1,
         &rcc.h_wire);
-      rcc.wtid = rhistory[off].details.close_details.wtid;
+      rcc.wtid = rh->details.close_details.wtid;
       rcc.purpose.size = htonl (sizeof (rcc));
       rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED);
       rcc.reserve_pub = *reserve_pub;
       timestamp = GNUNET_TIME_absolute_ntoh (rcc.timestamp);
-      rhistory[off].details.close_details.timestamp = timestamp;
-      TALER_amount_ntoh (&rhistory[off].details.close_details.fee,
+      rh->details.close_details.timestamp = timestamp;
+      TALER_amount_ntoh (&rh->details.close_details.fee,
                          &rcc.closing_fee);
       key_state = TALER_EXCHANGE_get_keys (exchange);
       if (GNUNET_OK !=
           TALER_EXCHANGE_test_signing_key (key_state,
-                                           
&rhistory[off].details.close_details.
+                                           &rh->details.close_details.
                                            exchange_pub))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
-                                      &rcc.purpose,
-                                      &rhistory[off].details.close_details.
-                                      exchange_sig.eddsa_signature,
-                                      &rhistory[off].details.close_details.
-                                      exchange_pub.eddsa_pub))
+          GNUNET_CRYPTO_eddsa_verify (
+            TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
+            &rcc.purpose,
+            &rh->details.close_details.exchange_sig.eddsa_signature,
+            &rh->details.close_details.exchange_pub.eddsa_pub))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
@@ -381,7 +381,7 @@ TALER_EXCHANGE_parse_reserve_history (
       if (GNUNET_OK !=
           TALER_amount_add (&total_out,
                             &total_out,
-                            &rhistory[off].amount))
+                            &rh->amount))
       {
         /* overflow in history already!? inconceivable! Bad exchange! */
         GNUNET_break_op (0);
@@ -505,6 +505,13 @@ TALER_EXCHANGE_verify_coin_history (
       GNUNET_break_op (0);
       return GNUNET_SYSERR;
     }
+    if (GNUNET_YES !=
+        TALER_amount_cmp_currency (&amount,
+                                   &rtotal))
+    {
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
     add = GNUNET_SYSERR;
     if (0 == strcasecmp (type,
                          "DEPOSIT"))
diff --git a/src/util/amount.c b/src/util/amount.c
index 454f3080..f96ab9c4 100644
--- a/src/util/amount.c
+++ b/src/util/amount.c
@@ -535,10 +535,9 @@ TALER_amount_normalize (struct TALER_Amount *amount)
     return GNUNET_SYSERR;
   if (amount->fraction < TALER_AMOUNT_FRAC_BASE)
     return GNUNET_NO;
-  overflow = amount->fraction / TALER_AMOUT_FRAC_BASE;
+  overflow = amount->fraction / TALER_AMOUNT_FRAC_BASE;
   amount->fraction %= TALER_AMOUNT_FRAC_BASE;
   amount->value += overflow;
-  ret = GNUNET_OK;
   if ( (amount->value < overflow) ||
        (amount->value > MAX_AMOUNT_VALUE) )
   {

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]