gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: -workshop refactoring


From: gnunet
Subject: [taler-merchant] branch master updated: -workshop refactoring
Date: Tue, 20 Jul 2021 19:34:01 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 362bf0c5 -workshop refactoring
362bf0c5 is described below

commit 362bf0c5bd2270ed6a54dfbdfd83702dca892797
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Jul 20 19:33:59 2021 +0200

    -workshop refactoring
---
 src/backend/Makefile.am                            |   2 +
 src/backend/taler-merchant-httpd.c                 |  17 ++-
 src/backend/taler-merchant-httpd.h                 |   6 +
 src/backend/taler-merchant-httpd_helper.c          | 106 +++++++++++++++
 src/backend/taler-merchant-httpd_helper.h          |  50 +++++++
 ...ler-merchant-httpd_private-patch-instances-ID.c | 146 +++++++--------------
 .../taler-merchant-httpd_private-post-instances.c  |  76 ++---------
 src/backenddb/merchant-0001.sql                    |   1 +
 src/backenddb/merchant-0002.sql                    |   2 +-
 src/backenddb/plugin_merchantdb_postgres.c         |  28 +++-
 src/backenddb/test_merchantdb.c                    |  10 +-
 src/include/taler_merchantdb_plugin.h              |   4 +
 12 files changed, 269 insertions(+), 179 deletions(-)

diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index b25b8d3d..da825d3b 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -27,6 +27,8 @@ taler_merchant_httpd_SOURCES = \
     taler-merchant-httpd_get-orders-ID.h \
   taler-merchant-httpd_get-tips-ID.c \
     taler-merchant-httpd_get-tips-ID.h \
+  taler-merchant-httpd_helper.c \
+    taler-merchant-httpd_helper.h \
   taler-merchant-httpd_private-get-tips.c \
     taler-merchant-httpd_private-get-tips.h \
   taler-merchant-httpd_private-get-tips-ID.c \
diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index bfc0337e..861b5f47 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -69,6 +69,10 @@
 #include "taler-merchant-httpd_statics.h"
 #include "taler-merchant-httpd_templating.h"
 
+/**
+ * Fixme: document.
+ */
+#define INSTANCE_STALENESS GNUNET_TIME_UNIT_MINUTES
 
 /**
  * Backlog for listen operation on unix-domain sockets.
@@ -908,6 +912,8 @@ struct TMH_MerchantInstance *
 TMH_lookup_instance (const char *instance_id)
 {
   struct GNUNET_HashCode h_instance;
+  struct TMH_MerchantInstance *mi;
+  struct GNUNET_TIME_Relative age;
 
   if (NULL == instance_id)
     instance_id = "default";
@@ -920,8 +926,14 @@ TMH_lookup_instance (const char *instance_id)
               instance_id);
   /* We're fine if that returns NULL, the calling routine knows how
      to handle that */
-  return GNUNET_CONTAINER_multihashmap_get (TMH_by_id_map,
-                                            &h_instance);
+  mi = GNUNET_CONTAINER_multihashmap_get (TMH_by_id_map,
+                                          &h_instance);
+  age = GNUNET_TIME_absolute_get_duration (mi->staleness);
+  if (age.rel_value_us > INSTANCE_STALENESS.rel_value_us)
+  {
+    // FIXME: referesh from DB
+  }
+  return mi;
 }
 
 
@@ -2038,6 +2050,7 @@ add_instance_cb (void *cls,
   else
     mi->deleted = true;
   mi->merchant_pub = *merchant_pub;
+  mi->staleness = GNUNET_TIME_absolute_get ();
   for (unsigned int i = 0; i<accounts_length; i++)
   {
     const struct TALER_MERCHANTDB_AccountDetails *acc = &accounts[i];
diff --git a/src/backend/taler-merchant-httpd.h 
b/src/backend/taler-merchant-httpd.h
index ab230783..29a67acc 100644
--- a/src/backend/taler-merchant-httpd.h
+++ b/src/backend/taler-merchant-httpd.h
@@ -137,6 +137,12 @@ struct TMH_MerchantInstance
    */
   struct TALER_MERCHANTDB_InstanceAuthSettings auth;
 
+  /**
+   * Timestamp when we last updated this instance's data
+   * with the information from the database.
+   */
+  struct GNUNET_TIME_Absolute staleness;
+
   /**
    * Reference counter on this structure. Only destroyed if the
    * counter hits zero.
diff --git a/src/backend/taler-merchant-httpd_helper.c 
b/src/backend/taler-merchant-httpd_helper.c
new file mode 100644
index 00000000..30ff4a90
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_helper.c
@@ -0,0 +1,106 @@
+/*
+  This file is part of TALER
+  (C) 2014--2020 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Lesser General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-merchant-httpd_helper.c
+ * @brief shared logic for various handlers
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "taler-merchant-httpd_helper.h"
+
+/**
+ * check @a payto_uris for well-formedness
+ *
+ * @param payto_uris JSON array of payto URIs (presumably)
+ * @return true if they are all valid URIs (and this is an array of strings)
+ */
+bool
+TMH_payto_uri_array_valid (const json_t *payto_uris)
+{
+  bool payto_ok = true;
+
+  if (! json_is_array (payto_uris))
+  {
+    GNUNET_break_op (0);
+    payto_ok = false;
+  }
+  else
+  {
+    unsigned int len = json_array_size (payto_uris);
+
+    for (unsigned int i = 0; i<len; i++)
+    {
+      json_t *payto_uri = json_array_get (payto_uris,
+                                          i);
+      const char *uri;
+
+      if (! json_is_string (payto_uri))
+        payto_ok = false;
+      uri = json_string_value (payto_uri);
+      /* Test for the same payto:// URI being given twice */
+      for (unsigned int j = 0; j<i; j++)
+      {
+        json_t *old_uri = json_array_get (payto_uris,
+                                          j);
+        if (json_equal (payto_uri,
+                        old_uri))
+        {
+          GNUNET_break_op (0);
+          payto_ok = false;
+          break;
+        }
+      }
+      if (! payto_ok)
+        break;
+      if (GNUNET_SYSERR ==
+          TALER_JSON_validate_payto (uri))
+      {
+        payto_ok = false;
+        break;
+      }
+    }
+  }
+  return payto_ok;
+}
+
+
+struct TMH_WireMethod *
+TMH_setup_wire_account (const char *payto_uri)
+{
+  struct GNUNET_HashCode salt;
+  struct TMH_WireMethod *wm;
+
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                              &salt,
+                              sizeof (salt));
+  wm = GNUNET_new (struct TMH_WireMethod);
+  wm->j_wire = json_pack ("{s:s, s:o}",
+                          "payto_uri", payto_uri,
+                          "salt", GNUNET_JSON_from_data_auto (&salt));
+  GNUNET_assert (NULL != wm->j_wire);
+  /* This also tests for things like the IBAN being malformed */
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_merchant_wire_signature_hash (wm->j_wire,
+                                                          &wm->h_wire));
+  wm->wire_method
+    = TALER_payto_get_method (payto_uri);
+  GNUNET_assert (NULL != wm->wire_method);     /* checked earlier */
+  wm->active = true;
+  return wm;
+}
diff --git a/src/backend/taler-merchant-httpd_helper.h 
b/src/backend/taler-merchant-httpd_helper.h
new file mode 100644
index 00000000..5f478c18
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_helper.h
@@ -0,0 +1,50 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2021 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file taler-merchant-httpd_helper.h
+ * @brief helpers for shared logic
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#ifndef TALER_EXCHANGE_HTTPD_HELPER_H
+#define TALER_EXCHANGE_HTTPD_HELPER_H
+
+
+#include "taler-merchant-httpd.h"
+
+/**
+ * check @a payto_uris for well-formedness
+ *
+ * @param payto_uris JSON array of payto URIs (presumably)
+ * @return true if they are all valid URIs (and this is an array of strings)
+ */
+bool
+TMH_payto_uri_array_valid (const json_t *payto_uris);
+
+
+/**
+ * Setup new wire method for the given @ payto_uri.
+ *
+ * @param payto_uri already validated payto URI
+ * @return new wire method object, never fails
+ */
+struct TMH_WireMethod *
+TMH_setup_wire_account (const char *payto_uri);
+
+
+#endif
diff --git a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c 
b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
index 0a839a3a..8b0917e7 100644
--- a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
+++ b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
@@ -24,6 +24,7 @@
  */
 #include "platform.h"
 #include "taler-merchant-httpd_private-patch-instances-ID.h"
+#include "taler-merchant-httpd_helper.h"
 #include <taler/taler_json_lib.h>
 
 
@@ -74,12 +75,12 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
                            &is.address),
     GNUNET_JSON_spec_json ("jurisdiction",
                            &is.jurisdiction),
-    TALER_JSON_spec_amount ("default_max_deposit_fee",
-                            &is.default_max_deposit_fee),
     TALER_JSON_spec_amount ("default_max_wire_fee",
                             &is.default_max_wire_fee),
     GNUNET_JSON_spec_uint32 ("default_wire_fee_amortization",
                              &is.default_wire_fee_amortization),
+    TALER_JSON_spec_amount ("default_max_deposit_fee",
+                            &is.default_max_deposit_fee),
     TALER_JSON_spec_relative_time ("default_wire_transfer_delay",
                                    &is.default_wire_transfer_delay),
     TALER_JSON_spec_relative_time ("default_pay_delay",
@@ -87,6 +88,7 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
     GNUNET_JSON_spec_end ()
   };
   enum GNUNET_DB_QueryStatus qs;
+  bool committed = false;
 
   GNUNET_assert (NULL != mi);
   {
@@ -100,7 +102,19 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
              ? MHD_YES
              : MHD_NO;
   }
-  if (! json_is_array (payto_uris))
+  if ((0 != strcasecmp (is.default_max_deposit_fee.currency,
+                        TMH_currency)) ||
+      (0 != strcasecmp (is.default_max_wire_fee.currency,
+                        TMH_currency)))
+  {
+    GNUNET_break_op (0);
+    GNUNET_JSON_parse_free (spec);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_CONFLICT,
+                                       TALER_EC_GENERIC_CURRENCY_MISMATCH,
+                                       NULL);
+  }
+  if (! TMH_payto_uri_array_valid (payto_uris))
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
@@ -119,18 +133,6 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
         free_wm (wm);
       }
     }
-    if ((0 != strcasecmp (is.default_max_deposit_fee.currency,
-                          TMH_currency)) ||
-        (0 != strcasecmp (is.default_max_wire_fee.currency,
-                          TMH_currency)))
-    {
-      GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_CONFLICT,
-                                         TALER_EC_GENERIC_CURRENCY_MISMATCH,
-                                         NULL);
-    }
     if (GNUNET_OK !=
         TMH_db->start (TMH_db->cls,
                        "PATCH /instances"))
@@ -199,31 +201,12 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
         {
           const char *str = json_string_value (json_array_get (payto_uris,
                                                                i));
-          if (NULL == str)
-          {
-            GNUNET_break_op (0);
-            TMH_db->rollback (TMH_db->cls);
-            GNUNET_JSON_parse_free (spec);
-            GNUNET_assert (NULL == wm_head);
-            return TALER_MHD_reply_with_error (connection,
-                                               MHD_HTTP_BAD_REQUEST,
-                                               
TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
-                                               NULL);
-          }
           if (0 == strcasecmp (uri,
                                str))
           {
-            if (NULL != matches[i])
-            {
-              GNUNET_break (0);
-              TMH_db->rollback (TMH_db->cls);
-              GNUNET_JSON_parse_free (spec);
-              GNUNET_assert (NULL == wm_head);
-              return TALER_MHD_reply_with_error (connection,
-                                                 MHD_HTTP_BAD_REQUEST,
-                                                 
TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
-                                                 str);
-            }
+            /* our own existing payto URIs should be unique, that is no
+               duplicates in the list, so we cannot match twice */
+            GNUNET_assert (NULL == matches[i]);
             matches[i] = wm;
             matched = true;
             break;
@@ -239,6 +222,7 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
                       uri);
           wm->deleting = true;
           qs = TMH_db->inactivate_account (TMH_db->cls,
+                                           mi->settings.id,
                                            &wm->h_wire);
           if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
           {
@@ -262,6 +246,7 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
           if (! wm->active)
           {
             qs = TMH_db->activate_account (TMH_db->cls,
+                                           mi->settings.id,
                                            &wm->h_wire);
             if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
             {
@@ -281,51 +266,7 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                     "Adding NEW account `%s'\n",
                     ad.payto_uri);
-        GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
-                                    &ad.salt,
-                                    sizeof (ad.salt));
-        wm = GNUNET_new (struct TMH_WireMethod);
-        wm->j_wire = json_pack ("{s:s, s:o}",
-                                "payto_uri", ad.payto_uri,
-                                "salt", GNUNET_JSON_from_data_auto (&ad.salt));
-        GNUNET_assert (NULL != wm->j_wire);
-        wm->wire_method
-          = TALER_payto_get_method (ad.payto_uri);
-        if (NULL == wm->wire_method)
-        {
-          GNUNET_break_op (0);
-          TMH_db->rollback (TMH_db->cls);
-          GNUNET_JSON_parse_free (spec);
-          json_decref (wm->j_wire);
-          GNUNET_free (wm);
-          return TALER_MHD_reply_with_error (connection,
-                                             MHD_HTTP_BAD_REQUEST,
-                                             
TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
-                                             ad.payto_uri);
-
-        }
-        /* This also tests for things like the IBAN being malformed */
-        if (GNUNET_OK !=
-            TALER_JSON_merchant_wire_signature_hash (wm->j_wire,
-                                                     &wm->h_wire))
-        {
-          GNUNET_break_op (0);
-          free_wm (wm);
-          while (NULL != (wm = wm_head))
-          {
-            GNUNET_CONTAINER_DLL_remove (wm_head,
-                                         wm_tail,
-                                         wm);
-            free_wm (wm);
-          }
-          TMH_db->rollback (TMH_db->cls);
-          GNUNET_JSON_parse_free (spec);
-          return TALER_MHD_reply_with_error (connection,
-                                             MHD_HTTP_BAD_REQUEST,
-                                             
TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
-                                             ad.payto_uri);
-        }
-        wm->active = true;
+        wm = TMH_setup_wire_account (ad.payto_uri);
         GNUNET_CONTAINER_DLL_insert (wm_head,
                                      wm_tail,
                                      wm);
@@ -349,10 +290,31 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
 retry:
     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
       continue;
+    if (qs >= 0)
+      committed = true;
     break;
   } /* for(... MAX_RETRIES) */
 giveup:
-  if (0 > qs)
+  /* Deactivate existing wire methods that were removed above */
+  for (struct TMH_WireMethod *wm = mi->wm_head;
+       NULL != wm;
+       wm = wm->next)
+  {
+    /* We did not flip the 'active' bits earlier because the
+       DB transaction could still fail. Now it is time to update our
+       runtime state. */
+    GNUNET_assert (! (wm->deleting & wm->enabling));
+    if (committed)
+    {
+      if (wm->deleting)
+        wm->active = false;
+      if (wm->enabling)
+        wm->active = true;
+    }
+    wm->deleting = false;
+    wm->enabling = false;
+  }
+  if (! committed)
   {
     struct TMH_WireMethod *wm;
 
@@ -369,22 +331,6 @@ giveup:
                                        TALER_EC_GENERIC_DB_COMMIT_FAILED,
                                        NULL);
   }
-  /* Deactivate existing wire methods that were removed above */
-  for (struct TMH_WireMethod *wm = mi->wm_head;
-       NULL != wm;
-       wm = wm->next)
-  {
-    /* We did not flip the 'active' bits earlier because the
-       DB transaction could still fail. Now it is time to update our
-       runtime state. */
-    GNUNET_assert (! (wm->deleting & wm->enabling));
-    if (wm->deleting)
-      wm->active = false;
-    if (wm->enabling)
-      wm->active = true;
-    wm->deleting = false;
-    wm->enabling = false;
-  }
 
   /* Update our 'settings' */
   GNUNET_free (mi->settings.name);
@@ -400,6 +346,8 @@ giveup:
   {
     struct TMH_WireMethod *wm;
 
+    /* Note: this _could_ be done more efficiently if
+       someone wrote a GNUNET_CONTAINER_DLL_merge()... */
     while (NULL != (wm = wm_head))
     {
       GNUNET_CONTAINER_DLL_remove (wm_head,
diff --git a/src/backend/taler-merchant-httpd_private-post-instances.c 
b/src/backend/taler-merchant-httpd_private-post-instances.c
index f9df3d39..71739c3d 100644
--- a/src/backend/taler-merchant-httpd_private-post-instances.c
+++ b/src/backend/taler-merchant-httpd_private-post-instances.c
@@ -24,6 +24,7 @@
  */
 #include "platform.h"
 #include "taler-merchant-httpd_private-post-instances.h"
+#include "taler-merchant-httpd_helper.h"
 #include <taler/taler_json_lib.h>
 #include <regex.h>
 
@@ -234,56 +235,11 @@ TMH_private_post_instances (const struct 
TMH_RequestHandler *rh,
   }
 
   /* check payto_uris for well-formedness */
-  {
-    bool payto_ok = true;
-
-    if (! json_is_array (payto_uris))
-    {
-      GNUNET_break_op (0);
-      payto_ok = false;
-    }
-    else
-    {
-      unsigned int len = json_array_size (payto_uris);
-
-      for (unsigned int i = 0; i<len; i++)
-      {
-        json_t *payto_uri = json_array_get (payto_uris,
-                                            i);
-        const char *uri;
-
-        if (! json_is_string (payto_uri))
-          payto_ok = false;
-        uri = json_string_value (payto_uri);
-        /* Test for the same payto:// URI being given twice */
-        for (unsigned int j = 0; j<i; j++)
-        {
-          json_t *old_uri = json_array_get (payto_uris,
-                                            j);
-          if (json_equal (payto_uri,
-                          old_uri))
-          {
-            GNUNET_break_op (0);
-            payto_ok = false;
-            break;
-          }
-        }
-        if (! payto_ok)
-          break;
-        if (GNUNET_SYSERR ==
-            TALER_JSON_validate_payto (uri))
-        {
-          payto_ok = false;
-          break;
-        }
-      }
-    }
-    if (! payto_ok)
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_BAD_REQUEST,
-                                         TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
-                                         NULL);
-  }
+  if (! TMH_payto_uri_array_valid (payto_uris))
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
+                                       NULL);
 
   /* check 'id' well-formed */
   {
@@ -402,24 +358,8 @@ TMH_private_post_instances (const struct 
TMH_RequestHandler *rh,
       json_t *payto_uri = json_array_get (payto_uris,
                                           i);
       struct TMH_WireMethod *wm;
-      struct GNUNET_HashCode salt;
-
-      GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
-                                  &salt,
-                                  sizeof (salt));
-      wm = GNUNET_new (struct TMH_WireMethod);
-      wm->j_wire = json_pack ("{s:O, s:o}",
-                              "payto_uri", payto_uri,
-                              "salt", GNUNET_JSON_from_data_auto (&salt));
-      GNUNET_assert (NULL != wm->j_wire);
-      /* This also tests for things like the IBAN being malformed */
-      GNUNET_assert (GNUNET_OK ==
-                     TALER_JSON_merchant_wire_signature_hash (wm->j_wire,
-                                                              &wm->h_wire));
-      wm->wire_method
-        = TALER_payto_get_method (json_string_value (payto_uri));
-      GNUNET_assert (NULL != wm->wire_method); /* checked earlier */
-      wm->active = true;
+
+      wm = TMH_setup_wire_account (json_string_value (payto_uri));
       GNUNET_CONTAINER_DLL_insert (wm_head,
                                    wm_tail,
                                    wm);
diff --git a/src/backenddb/merchant-0001.sql b/src/backenddb/merchant-0001.sql
index 74144e86..65ea94c9 100644
--- a/src/backenddb/merchant-0001.sql
+++ b/src/backenddb/merchant-0001.sql
@@ -101,6 +101,7 @@ CREATE TABLE IF NOT EXISTS merchant_accounts
   ,payto_uri VARCHAR NOT NULL
   ,active boolean NOT NULL
   ,UNIQUE (merchant_serial,payto_uri)
+  ,UNIQUE (h_wire)
   );
 COMMENT ON TABLE merchant_accounts
   IS 'bank accounts of the instances';
diff --git a/src/backenddb/merchant-0002.sql b/src/backenddb/merchant-0002.sql
index 1cb1d7b2..46428dd9 100644
--- a/src/backenddb/merchant-0002.sql
+++ b/src/backenddb/merchant-0002.sql
@@ -18,7 +18,7 @@
 BEGIN;
 
 -- Check patch versioning is in place.
-SELECT _v.register_patch('merchant-0002', ARRAY['merchant-0001'], NULL);
+SELECT _v.register_patch('merchant-0002', NULL, NULL);
 
 
 -- need serial IDs on various tables for exchange-auditor replication
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index ed051053..570c681a 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -795,15 +795,18 @@ postgres_update_instance_auth (
  * Set an instance's account in our database to "inactive".
  *
  * @param cls closure
+ * @param merchant_id merchant backend instance ID
  * @param h_wire hash of the wire account to set to inactive
  * @return database result code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_inactivate_account (void *cls,
+                             const char *merchant_id,
                              const struct GNUNET_HashCode *h_wire)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (merchant_id),
     GNUNET_PQ_query_param_auto_from_type (h_wire),
     GNUNET_PQ_query_param_end
   };
@@ -819,15 +822,18 @@ postgres_inactivate_account (void *cls,
  * Set an instance's account in our database to "active".
  *
  * @param cls closure
+ * @param merchant_id merchant backend instance ID
  * @param h_wire hash of the wire account to set to active
  * @return database result code
  */
 static enum GNUNET_DB_QueryStatus
 postgres_activate_account (void *cls,
+                           const char *merchant_id,
                            const struct GNUNET_HashCode *h_wire)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (merchant_id),
     GNUNET_PQ_query_param_auto_from_type (h_wire),
     GNUNET_PQ_query_param_end
   };
@@ -6375,20 +6381,30 @@ postgres_connect (void *cls)
                             "UPDATE merchant_instances SET"
                             " auth_hash=$2"
                             ",auth_salt=$3"
-                            " WHERE merchant_id = $1",
+                            " WHERE merchant_id=$1",
                             3),
-    /* for postgres_inactivate_account() */
+    /* for postgres_inactivate_account(); the merchant
+       instance is implied from the random salt that
+       is part of the h_wire calculation */
     GNUNET_PQ_make_prepare ("inactivate_account",
                             "UPDATE merchant_accounts SET"
                             " active=FALSE"
-                            " WHERE h_wire = $1",
-                            1),
+                            " WHERE h_wire=$2 AND"
+                            " merchant_serial="
+                            "   (SELECT merchant_serial"
+                            "      FROM merchant_instances"
+                            "      WHERE merchant_id=$1)",
+                            2),
     /* for postgres_activate_account() */
     GNUNET_PQ_make_prepare ("activate_account",
                             "UPDATE merchant_accounts SET"
                             " active=TRUE"
-                            " WHERE h_wire = $1",
-                            1),
+                            " WHERE h_wire=$2 AND"
+                            " merchant_serial="
+                            "   (SELECT merchant_serial"
+                            "      FROM merchant_instances"
+                            "      WHERE merchant_id=$1)",
+                            2),
     /* for postgres_lookup_products() */
     GNUNET_PQ_make_prepare ("lookup_products",
                             "SELECT"
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index b3b43062..7a930296 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -478,11 +478,13 @@ test_insert_account (const struct InstanceData *instance,
  * @return 0 on success, 1 otherwise.
  */
 static int
-test_inactivate_account (const struct TALER_MERCHANTDB_AccountDetails *account,
+test_inactivate_account (const struct InstanceData *instance,
+                         const struct TALER_MERCHANTDB_AccountDetails *account,
                          enum GNUNET_DB_QueryStatus expected_result)
 {
   TEST_COND_RET_ON_FAIL (expected_result ==
                          plugin->inactivate_account (plugin->cls,
+                                                     instance->instance.id,
                                                      &account->h_wire),
                          "Deactivate account failed\n");
   return 0;
@@ -618,9 +620,11 @@ run_test_instances (struct TestInstances_Closure *cls)
                                            1,
                                            instances));
   /* Test deactivate account */
-  TEST_RET_ON_FAIL (test_inactivate_account (&cls->accounts[0],
+  TEST_RET_ON_FAIL (test_inactivate_account (&cls->instances[0],
+                                             &cls->accounts[0],
                                              
GNUNET_DB_STATUS_SUCCESS_ONE_RESULT));
-  TEST_RET_ON_FAIL (test_inactivate_account (&cls->accounts[1],
+  TEST_RET_ON_FAIL (test_inactivate_account (&cls->instances[1],
+                                             &cls->accounts[1],
                                              
GNUNET_DB_STATUS_SUCCESS_NO_RESULTS));
   cls->accounts[0].active = false;
   TEST_RET_ON_FAIL (test_lookup_instances (false,
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index f3989790..0397b9aa 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -866,11 +866,13 @@ struct TALER_MERCHANTDB_Plugin
    * Set an instance's account in our database to "inactive".
    *
    * @param cls closure
+   * @param merchant_id merchant backend instance ID
    * @param h_wire hash of the wire account to set to inactive
    * @return database result code
    */
   enum GNUNET_DB_QueryStatus
   (*inactivate_account)(void *cls,
+                        const char *merchant_id,
                         const struct GNUNET_HashCode *h_wire);
 
 
@@ -878,11 +880,13 @@ struct TALER_MERCHANTDB_Plugin
    * Set an instance's account in our database to "active".
    *
    * @param cls closure
+   * @param merchant_id merchant backend instance ID
    * @param h_wire hash of the wire account to set to active
    * @return database result code
    */
   enum GNUNET_DB_QueryStatus
   (*activate_account)(void *cls,
+                      const char *merchant_id,
                       const struct GNUNET_HashCode *h_wire);
 
   /**

-- 
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]