gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 04/06: work towards multi-currency support


From: gnunet
Subject: [taler-merchant] 04/06: work towards multi-currency support
Date: Fri, 13 Oct 2023 21:16:59 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit a5f50083e65a3e9a0945b150701349afa81a0e9e
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Fri Oct 13 14:43:50 2023 +0200

    work towards multi-currency support
---
 src/backend/kudos.conf                             |   4 -
 src/backend/taler-merchant-exchange.c              |  29 ++++--
 src/backend/taler-merchant-httpd_exchanges.c       |  32 +++++-
 .../taler-merchant-httpd_post-rewards-ID-pickup.c  |  19 +++-
 ...-merchant-httpd_private-post-orders-ID-refund.c | 112 ++++++++++-----------
 .../taler-merchant-httpd_private-post-orders.c     |  94 ++++++++++++++---
 src/backenddb/pg_authorize_reward.c                |   2 +-
 src/backenddb/pg_increase_refund.c                 |   8 ++
 src/backenddb/pg_insert_pickup.c                   |   7 ++
 src/backenddb/plugin_merchantdb_postgres.c         |   7 ++
 src/include/taler_merchantdb_plugin.h              |   5 +
 src/testing/test_merchant_api.conf                 |   3 +
 src/testing/test_merchant_instance_auth.sh         |   3 +-
 src/testing/test_merchant_kyc.sh                   |  11 +-
 src/testing/test_merchant_order_creation.sh        |   6 +-
 src/testing/test_merchant_reserve_creation.sh      |   4 +-
 src/testing/test_template.conf                     |   3 +
 17 files changed, 249 insertions(+), 100 deletions(-)

diff --git a/src/backend/kudos.conf b/src/backend/kudos.conf
index 424209d0..71ed232a 100644
--- a/src/backend/kudos.conf
+++ b/src/backend/kudos.conf
@@ -1,9 +1,5 @@
-
-
 # Trust Taler project for "KUDOS" currency so that demos work out-of-the-box
 [merchant-exchange-kudos]
 EXCHANGE_BASE_URL = https://exchange.demo.taler.net/
 MASTER_KEY = JFX1NE38C65A5XT8VSNQXX7R7BBG4GNZ63F5T7Y6859V4J8KBKF0
-# If currency does not match [TALER] section, the exchange
-# will be ignored!
 CURRENCY = KUDOS
diff --git a/src/backend/taler-merchant-exchange.c 
b/src/backend/taler-merchant-exchange.c
index 4db8f92d..bc475031 100644
--- a/src/backend/taler-merchant-exchange.c
+++ b/src/backend/taler-merchant-exchange.c
@@ -613,14 +613,18 @@ check_wire_fee (struct Inquiry *w,
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     break;
   }
-  if (0 <= TALER_amount_cmp (&fees.wire,
-                             wire_fee))
+  if ( (GNUNET_OK !=
+        TALER_amount_cmp_currency (&fees.wire,
+                                   wire_fee)) ||
+       (0 > TALER_amount_cmp (&fees.wire,
+                               wire_fee)) )
   {
+    GNUNET_break_op (0);
     GNUNET_free (wire_method);
-    return GNUNET_OK;   /* expected_fee >= wire_fee */
+    return GNUNET_SYSERR;   /* expected_fee >= wire_fee */
   }
   GNUNET_free (wire_method);
-  return GNUNET_SYSERR;
+  return GNUNET_OK;
 }
 
 
@@ -698,8 +702,14 @@ check_transfer (void *cls,
     GNUNET_break (0);
     return;   /* already had a serious issue; odd that we're called more than 
once as well... */
   }
-  if ( (0 != TALER_amount_cmp (amount_with_fee,
+  if ( (GNUNET_OK !=
+        TALER_amount_cmp_currency (amount_with_fee,
+                                   &ttd->coin_value)) ||
+       (0 != TALER_amount_cmp (amount_with_fee,
                                &ttd->coin_value)) ||
+       (GNUNET_OK !=
+        TALER_amount_cmp_currency (deposit_fee,
+                                   &ttd->coin_fee)) ||
        (0 != TALER_amount_cmp (deposit_fee,
                                &ttd->coin_fee)) )
   {
@@ -905,9 +915,12 @@ wire_transfer_cb (void *cls,
     return;
   }
 
-  if (0 !=
-      TALER_amount_cmp (&td->total_amount,
-                        &w->total))
+  if ( (GNUNET_OK !=
+        TALER_amount_cmp_currency (&td->total_amount,
+                                   &w->total)) ||
+       (0 !=
+        TALER_amount_cmp (&td->total_amount,
+                          &w->total)) )
   {
     GNUNET_break_op (0);
     update_transaction_status (w,
diff --git a/src/backend/taler-merchant-httpd_exchanges.c 
b/src/backend/taler-merchant-httpd_exchanges.c
index 170e59f8..0ac2234c 100644
--- a/src/backend/taler-merchant-httpd_exchanges.c
+++ b/src/backend/taler-merchant-httpd_exchanges.c
@@ -37,6 +37,9 @@
 #define RETRY_BACKOFF_THRESHOLD GNUNET_TIME_relative_multiply ( \
     GNUNET_TIME_UNIT_SECONDS, 60)
 
+#define FAST_FAIL_THRESHOLD GNUNET_TIME_relative_multiply ( \
+    GNUNET_TIME_UNIT_SECONDS, 2)
+
 
 /**
  * Information we keep for a pending #MMH_EXCHANGES_keys4exchange() operation.
@@ -796,6 +799,21 @@ TMH_EXCHANGES_keys4exchange (
                                  exchange);
     return fo;
   }
+  if ( (NULL == exchange->conn) &&
+       (GNUNET_TIME_relative_cmp (
+          GNUNET_TIME_absolute_get_remaining (
+            exchange->first_retry),
+          >,
+          FAST_FAIL_THRESHOLD)) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Already waiting for `%skeys' for a while, failing query 
instantly\n",
+                exchange->url);
+    GNUNET_assert (NULL == fo->at);
+    fo->at = GNUNET_SCHEDULER_add_now (&return_keys,
+                                       fo);
+    return fo;
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Next /keys request scheduled for %s\n",
               GNUNET_TIME_absolute2s (
@@ -911,6 +929,7 @@ free_exchange_entry (struct TMH_Exchange *exchange)
   }
   GNUNET_assert (NULL == exchange->keys_head);
   GNUNET_assert (NULL == exchange->keys_tail);
+  GNUNET_free (exchange->currency);
   GNUNET_free (exchange->url);
   GNUNET_free (exchange);
 }
@@ -1118,8 +1137,10 @@ keys_mgmt_cb (void *cls,
     TALER_EXCHANGE_keys_decref (keys);
     return;
   }
+  if (NULL == exchange->currency)
+    exchange->currency = GNUNET_strdup (keys->currency);
   if (0 != strcmp (exchange->currency,
-                   keys->currency))
+                     keys->currency))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "/keys response from `%s' is for currency `%s', but we 
expected `%s'\n",
@@ -1286,6 +1307,8 @@ TMH_test_exchange_configured_for_currency (
   {
     if (! exchange->trusted)
       continue;
+    if (NULL == exchange->currency)
+      continue;
     if (0 == strcmp (currency,
                      exchange->currency))
       return true;
@@ -1317,6 +1340,11 @@ accept_exchanges (void *cls,
                         "merchant-exchange-",
                         strlen ("merchant-exchange-")))
     return;
+  if (GNUNET_YES ==
+      GNUNET_CONFIGURATION_get_value_yesno (cfg,
+                                            section,
+                                            "DISABLED"))
+    return;
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (cfg,
                                              section,
@@ -1435,6 +1463,8 @@ update_exchange_keys (void *cls,
     GNUNET_break (0);
     return;
   }
+  if (NULL == exchange->currency)
+    exchange->currency = GNUNET_strdup (keys->currency);
   if (0 != strcmp (keys->currency,
                    exchange->currency))
   {
diff --git a/src/backend/taler-merchant-httpd_post-rewards-ID-pickup.c 
b/src/backend/taler-merchant-httpd_post-rewards-ID-pickup.c
index 16bd5940..1a21790d 100644
--- a/src/backend/taler-merchant-httpd_post-rewards-ID-pickup.c
+++ b/src/backend/taler-merchant-httpd_post-rewards-ID-pickup.c
@@ -537,7 +537,7 @@ compute_total_requested (void *cls,
       {
         pc->http_status = MHD_HTTP_BAD_REQUEST;
         pc->response =
-          TALER_MHD_make_error (TALER_EC_GENERIC_CURRENCY_MISMATCH,
+          TALER_MHD_make_error (TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH,
                                 "Must not mix currencies when picking up 
rewards");
         MHD_resume_connection (pc->connection);
         TALER_MHD_daemon_trigger ();   /* we resumed, kick MHD */
@@ -920,6 +920,23 @@ RETRY:
                                        
TALER_EC_MERCHANT_REWARD_PICKUP_HAS_EXPIRED,
                                        hc->infix);
   }
+  if (GNUNET_OK !=
+      TALER_amount_cmp_currency (&total_authorized,
+                                 &total_picked_up))
+  {
+    /* This could theoretically happen if the exchange changed
+       its currency between us approving the reward
+       and the client then picks it up with the new
+       exchange currency. And of course the backend
+       would have had to get the new /keys of the
+       exchange already as well. Very theoretical case. */
+    GNUNET_break_op (0);
+    TMH_db->rollback (TMH_db->cls);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_CONFLICT,
+                                       
TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH,
+                                       "picked up amount does not use same 
currency as authorized amount");
+  }
   if (0 >
       TALER_amount_subtract (&total_remaining,
                              &total_authorized,
diff --git a/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c 
b/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c
index 1b2aa460..58fa96f4 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c
@@ -132,6 +132,20 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
   json_t *contract_terms;
   struct GNUNET_TIME_Timestamp timestamp;
 
+  {
+    enum GNUNET_GenericReturnValue res;
+
+    res = TALER_MHD_parse_json_data (connection,
+                                     hc->request_body,
+                                     spec);
+    if (GNUNET_OK != res)
+    {
+      return (GNUNET_NO == res)
+             ? MHD_YES
+             : MHD_NO;
+    }
+  }
+
   {
     enum GNUNET_DB_QueryStatus qs;
     uint64_t order_serial;
@@ -145,9 +159,34 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
                                         &order_serial,
                                         &paid,
                                         NULL);
-    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
+    {
+      if (qs < 0)
+      {
+        GNUNET_break (0);
+        return TALER_MHD_reply_with_error (connection,
+                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                           TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                           "lookup_contract_terms");
+      }
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_NOT_FOUND,
+                                         
TALER_EC_MERCHANT_GENERIC_ORDER_UNKNOWN,
+                                         hc->infix);
+    }
+    if (GNUNET_OK !=
+        TALER_JSON_contract_hash (contract_terms,
+                                  &h_contract))
+    {
+      GNUNET_break (0);
+      json_decref (contract_terms);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         
TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH,
+                                         "Could not hash contract terms");
+    }
     {
-      struct GNUNET_JSON_Specification spec[] = {
+      struct GNUNET_JSON_Specification cspec[] = {
         GNUNET_JSON_spec_timestamp ("refund_deadline",
                                     &refund_deadline),
         GNUNET_JSON_spec_timestamp ("timestamp",
@@ -157,11 +196,10 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
 
       if (GNUNET_YES !=
           GNUNET_JSON_parse (contract_terms,
-                             spec,
+                             cspec,
                              NULL, NULL))
       {
         GNUNET_break (0);
-        GNUNET_JSON_parse_free (spec);
         json_decref (contract_terms);
         return TALER_MHD_reply_with_error (
           connection,
@@ -188,28 +226,6 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
            wire the funds, so we will try to give the refund anyway */
       }
     }
-    else
-    {
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_NOT_FOUND,
-                                         
TALER_EC_MERCHANT_GENERIC_ORDER_UNKNOWN,
-                                         hc->infix);
-    }
-  }
-
-  {
-    enum GNUNET_GenericReturnValue res;
-
-    res = TALER_MHD_parse_json_data (connection,
-                                     hc->request_body,
-                                     spec);
-    if (GNUNET_OK != res)
-    {
-      json_decref (contract_terms);
-      return (GNUNET_NO == res)
-             ? MHD_YES
-             : MHD_NO;
-    }
   }
 
   TMH_db->preflight (TMH_db->cls);
@@ -293,6 +309,14 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
 
   switch (rs)
   {
+  case TALER_MERCHANTDB_RS_BAD_CURRENCY:
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Refund amount %s is not in the currency of the original 
payment\n",
+                TALER_amount2s (&refund));
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_CONFLICT,
+                                       
TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH,
+                                       "Order was paid in a different 
currency");
   case TALER_MERCHANTDB_RS_TOO_HIGH:
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Refusing refund amount %s that is larger than original 
payment\n",
@@ -318,41 +342,9 @@ TMH_private_post_orders_ID_refund (const struct 
TMH_RequestHandler *rh,
       TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_ORDER_UNPAID,
       hc->infix);
   case TALER_MERCHANTDB_RS_SUCCESS:
-    {
-      enum GNUNET_DB_QueryStatus qs;
-      json_t *contract_terms;
-      uint64_t order_serial;
-      bool paid;
-
-      qs = TMH_db->lookup_contract_terms (TMH_db->cls,
-                                          hc->instance->settings.id,
-                                          hc->infix,
-                                          &contract_terms,
-                                          &order_serial,
-                                          &paid,
-                                          NULL);
-      if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
-      {
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_NOT_FOUND,
-                                           
TALER_EC_MERCHANT_GENERIC_ORDER_UNKNOWN,
-                                           hc->infix);
-      }
-      if (GNUNET_OK !=
-          TALER_JSON_contract_hash (contract_terms,
-                                    &h_contract))
-      {
-        GNUNET_break (0);
-        json_decref (contract_terms);
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                           
TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH,
-                                           "Could not hash contract terms");
-      }
-      json_decref (contract_terms);
-    }
+    /* continued below */
     break;
-  }
+  } /* end switch */
 
   {
     struct GNUNET_TIME_Timestamp timestamp;
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c 
b/src/backend/taler-merchant-httpd_private-post-orders.c
index 61051b9a..09c709e9 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -38,6 +38,11 @@
  */
 #define MAX_RETRIES 3
 
+/**
+ * How long do we wait for /keys from the exchange?
+ */
+#define KEYS_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
2)
+
 /**
  * What is the label under which we find/place the merchant's
  * jurisdiction in the locations list by default?
@@ -124,6 +129,11 @@ struct RekeyExchange
    */
   struct TMH_EXCHANGES_KeysOperation *fo;
 
+  /**
+   * Timeout task handle.
+   */
+  struct GNUNET_SCHEDULER_Task *tx;
+ 
 };
 
 
@@ -419,6 +429,7 @@ clean_order (void *cls)
                                  oc->pending_reload_tail,
                                  rx);
     TMH_EXCHANGES_keys4exchange_cancel (rx->fo);
+    GNUNET_SCHEDULER_cancel (rx->tx);
     GNUNET_free (rx->url);
     GNUNET_free (rx);
   }
@@ -963,6 +974,28 @@ get_acceptable (void *cls,
 }
 
 
+/**
+ * Exchange `/keys` processing is done, resume handling
+ * the order.
+ *
+ * @param[in,out] oc context to resume
+ */
+static void
+resume_with_keys (struct OrderContext *oc)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Resuming order processing after /keys downloads (now have %u 
accounts)\n",
+              (unsigned int) json_array_size (oc->exchanges));
+  GNUNET_assert (GNUNET_YES == oc->suspended);
+  GNUNET_CONTAINER_DLL_remove (oc_head,
+                               oc_tail,
+                               oc);
+  oc->suspended = GNUNET_NO;
+  MHD_resume_connection (oc->connection);
+  TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */
+}
+
+
 /**
  * Function called with the result of a #TMH_EXCHANGES_keys4exchange()
  * operation.
@@ -983,13 +1016,15 @@ keys_cb (
     &oc->hc->instance->settings;
 
   rx->fo = NULL;
+  GNUNET_SCHEDULER_cancel (rx->tx);
+  rx->tx = NULL;
   GNUNET_CONTAINER_DLL_remove (oc->pending_reload_head,
                                oc->pending_reload_tail,
                                rx);
   if (NULL == keys)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Failed to download %s/keys\n",
+                "Failed to download %skeys\n",
                 rx->url);
   }
   else
@@ -999,24 +1034,41 @@ keys_cb (
           TALER_amount_is_valid (&oc->max_fee)) )
       update_stefan (oc,
                      keys);
+    get_acceptable (oc,
+                    rx->url,
+                    exchange);
   }
-  get_acceptable (oc,
-                  rx->url,
-                  exchange);
   GNUNET_free (rx->url);
   GNUNET_free (rx);
   if (NULL != oc->pending_reload_head)
     return;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Resuming order processing after /keys downloads (now have %u 
accounts)\n",
-              (unsigned int) json_array_size (oc->exchanges));
-  GNUNET_assert (GNUNET_YES == oc->suspended);
-  GNUNET_CONTAINER_DLL_remove (oc_head,
-                               oc_tail,
-                               oc);
-  oc->suspended = GNUNET_NO;
-  MHD_resume_connection (oc->connection);
-  TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */
+  resume_with_keys (oc);
+}
+
+
+/**
+ * A `/keys` request to an exchange is taking too
+ * long, ignore the exchange for now.
+ *
+ * @param cls a `struct RekeyExchange *`
+ */
+static void
+keys_timeout (void *cls)
+{
+  struct RekeyExchange *rx = cls;
+  struct OrderContext *oc = rx->oc;
+
+  rx->tx = NULL;
+  TMH_EXCHANGES_keys4exchange_cancel (rx->fo);
+  rx->fo = NULL;
+  GNUNET_CONTAINER_DLL_remove (oc->pending_reload_head,
+                               oc->pending_reload_tail,
+                               rx);
+  GNUNET_free (rx->url);
+  GNUNET_free (rx);
+  if (NULL != oc->pending_reload_head)
+    return;
+  resume_with_keys (oc);
 }
 
 
@@ -1050,6 +1102,10 @@ get_exchange_keys (void *cls,
                                         oc->forced_reload,
                                         &keys_cb,
                                         rx);
+  rx->tx
+    = GNUNET_SCHEDULER_add_delayed (KEYS_TIMEOUT,
+                                    &keys_timeout,
+                                    rx);
 }
 
 
@@ -1247,6 +1303,16 @@ patch_order (struct OrderContext *oc)
                      ret);
     return;
   }
+  if (! TMH_test_exchange_configured_for_currency (oc->brutto.currency))
+  {
+    GNUNET_break_op (0);
+    GNUNET_JSON_parse_free (spec);
+    reply_with_error (oc,
+                      MHD_HTTP_BAD_REQUEST,
+                      TALER_EC_GENERIC_CURRENCY_MISMATCH,
+                      NULL);
+    return;
+  }
 
   /* Add order_id if it doesn't exist. */
   if (NULL == order_id)
diff --git a/src/backenddb/pg_authorize_reward.c 
b/src/backenddb/pg_authorize_reward.c
index 336112cb..5038f4fa 100644
--- a/src/backenddb/pg_authorize_reward.c
+++ b/src/backenddb/pg_authorize_reward.c
@@ -130,7 +130,7 @@ lookup_reserve_for_reward_cb (void *cls,
       /* insufficient balance */
       if (lac->ok)
         continue;  /* got another reserve */
-      lac->ec = TALER_EC_GENERIC_CURRENCY_MISMATCH;
+      lac->ec = TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH;
       continue;
     }
     if (0 >
diff --git a/src/backenddb/pg_increase_refund.c 
b/src/backenddb/pg_increase_refund.c
index f1813e9b..832a84eb 100644
--- a/src/backenddb/pg_increase_refund.c
+++ b/src/backenddb/pg_increase_refund.c
@@ -223,6 +223,14 @@ process_deposits_for_refund_cb (
       return;
     }
 
+    if (0 != strcmp (rcd[i].deposited_with_fee.currency,
+                     ctx->refund->currency))
+    {
+      GNUNET_break_op (0);
+      ctx->rs = TALER_MERCHANTDB_RS_BAD_CURRENCY;
+      return;
+    }
+
     {
       enum GNUNET_DB_QueryStatus ires;
       struct GNUNET_PQ_QueryParam params[] = {
diff --git a/src/backenddb/pg_insert_pickup.c b/src/backenddb/pg_insert_pickup.c
index 73b97c6d..4094d748 100644
--- a/src/backenddb/pg_insert_pickup.c
+++ b/src/backenddb/pg_insert_pickup.c
@@ -134,6 +134,13 @@ TMH_PG_insert_pickup (
       if (0 > qs)
         return qs;
     }
+    if (GNUNET_OK !=
+        TALER_amount_cmp_currency (&reserve_picked_up,
+                                   total_requested))
+    {
+      GNUNET_break (0);
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
     if (0 >=
         TALER_amount_add (&reserve_picked_up,
                           &reserve_picked_up,
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index 30def849..c2c99cd1 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -1172,6 +1172,13 @@ postgres_lookup_transfer (
   {
     *have_exchange_sig = ! no_sig;
     *verified = (0 != verified8);
+    if (GNUNET_OK !=
+        TALER_amount_cmp_currency (&credit_amount,
+                                   wire_fee))
+    {
+      GNUNET_break (0);
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
     if ( (! no_sig) &&
          (0 >
           TALER_amount_add (total_amount,
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index fd29edba..7d589123 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -711,6 +711,11 @@ typedef void
 enum TALER_MERCHANTDB_RefundStatus
 {
 
+  /**
+   * Refund amount currency does not match original payment.
+   */
+  TALER_MERCHANTDB_RS_BAD_CURRENCY = -4,
+
   /**
    * Refund amount exceeds original payment.
    */
diff --git a/src/testing/test_merchant_api.conf 
b/src/testing/test_merchant_api.conf
index bf84e4ec..00f287fb 100644
--- a/src/testing/test_merchant_api.conf
+++ b/src/testing/test_merchant_api.conf
@@ -7,6 +7,9 @@ TALER_TEST_HOME = test_merchant_api_home/
 CURRENCY = EUR
 CURRENCY_ROUND_UNIT = EUR:0.01
 
+[merchant-exchange-kudos]
+DISABLED = YES
+
 [taler-helper-crypto-rsa]
 LOOKAHEAD_SIGN = 10 days
 
diff --git a/src/testing/test_merchant_instance_auth.sh 
b/src/testing/test_merchant_instance_auth.sh
index 58cee79d..ce6b1e07 100755
--- a/src/testing/test_merchant_instance_auth.sh
+++ b/src/testing/test_merchant_instance_auth.sh
@@ -33,7 +33,6 @@ function my_cleanup()
 
 . setup.sh
 
-# Launch only the merchant.
 setup -c test_template.conf -m
 CONF="test_template.conf.edited"
 LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX)
@@ -69,6 +68,8 @@ kill -TERM "$SETUP_PID"
 wait
 unset SETUP_PID
 
+setup -c test_template.conf -ef -u "exchange-account-2"
+
 NEW_SECRET=secret-token:different_value
 
 taler-merchant-httpd -a "${NEW_SECRET}" -c "${CONF}" -L DEBUG 2> 
taler-merchant-httpd.log &
diff --git a/src/testing/test_merchant_kyc.sh b/src/testing/test_merchant_kyc.sh
index 663590b1..c76f1387 100755
--- a/src/testing/test_merchant_kyc.sh
+++ b/src/testing/test_merchant_kyc.sh
@@ -21,7 +21,7 @@ set -eu
 . setup.sh
 
 # Launch system.
-setup -c "test_template.conf" -m -u "exchange-account-1"
+setup -c "test_template.conf" -mef -u "exchange-account-2"
 LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX)
 
 echo -n "Configuring a merchant default instance ..."
@@ -89,12 +89,13 @@ STATUS=$(curl 
'http://localhost:9966/instances/default/private/orders' \
 
 if [ "$STATUS" != "200" ]
 then
-    echo 'should respond 200 OK, order created. got:' $STATUS `cat 
"$LAST_RESPONSE"`
+    echo "Should respond 200 OK, order created. got: $STATUS"
+    jq < "$LAST_RESPONSE"
     exit 1
 fi
 
-ORDER_ID=`jq -r .order_id < "$LAST_RESPONSE"`
-TOKEN=`jq -r .token < "$LAST_RESPONSE"`
+ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE")
+TOKEN=$(jq -r .token < "$LAST_RESPONSE")
 
 if [ "$TOKEN" != "null" ]
 then
@@ -108,7 +109,7 @@ echo -n "Checking created order without TOKEN..."
 STATUS=$(curl http://localhost:9966/orders/$ORDER_ID \
     -w "%{http_code}" -s -o "$LAST_RESPONSE")
 
-PAY_URI=`jq -r .taler_pay_uri < "$LAST_RESPONSE"`
+PAY_URI=$(jq -r .taler_pay_uri < "$LAST_RESPONSE")
 
 if [ "$PAY_URI" == "null" ]
 then
diff --git a/src/testing/test_merchant_order_creation.sh 
b/src/testing/test_merchant_order_creation.sh
index 3fadd358..02185c62 100755
--- a/src/testing/test_merchant_order_creation.sh
+++ b/src/testing/test_merchant_order_creation.sh
@@ -326,7 +326,7 @@ fi
 echo "OK"
 
 #
-# CREATE INVALID ORDER
+# Create product in another currency
 #
 
 
@@ -334,9 +334,9 @@ STATUS=$(curl 
'http://localhost:9966/instances/default/private/products' \
     -d '{"product_id":"1","description":"product with id 1 and price 
:15","price":"USD:15","total_stock":1,"description_i18n":{},"unit":"","image":"","taxes":[],"address":{},"next_restock":{"t_s":"never"}}'
 \
     -w "%{http_code}" -s -o /dev/null)
 
-if [ "$STATUS" != "400" ]
+if [ "$STATUS" != "204" ]
 then
-    exit_fail "Expected 400 bad request, product price is in another currency. 
got: $STATUS"
+    exit_fail "Expected 204 no content. got: $STATUS"
 fi
 
 #
diff --git a/src/testing/test_merchant_reserve_creation.sh 
b/src/testing/test_merchant_reserve_creation.sh
index c910ba9c..8fafb551 100755
--- a/src/testing/test_merchant_reserve_creation.sh
+++ b/src/testing/test_merchant_reserve_creation.sh
@@ -220,9 +220,9 @@ STATUS=$(curl 
'http://localhost:9966/instances/default/private/reserves' \
     -d 
'{"initial_balance":"INVALID:2","exchange_url":"http://localhost:8081/","wire_method":"iban"}'
 \
     -w "%{http_code}" -s -o "$LAST_RESPONSE")
 
-if [ "$STATUS" != "400" ]
+if [ "$STATUS" != "409" ]
 then
-    exit_fail "Expected 400, bad currency. got: $STATUS"
+    exit_fail "Expected 409, bad currency. got: $STATUS"
 fi
 echo "FAILED (which is expected)"
 
diff --git a/src/testing/test_template.conf b/src/testing/test_template.conf
index 3723f898..a278ea58 100644
--- a/src/testing/test_template.conf
+++ b/src/testing/test_template.conf
@@ -5,6 +5,9 @@ TALER_TEST_HOME = test_merchant_api_home/
 CURRENCY = TESTKUDOS
 CURRENCY_ROUND_UNIT = TESTKUDOS:0.01
 
+[merchant-exchange-kudos]
+DISABLED = YES
+
 [exchange]
 AML_THRESHOLD = TESTKUDOS:1000000
 MAX_KEYS_CACHING = forever

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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