gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-merchant] branch master updated: work on #4939: load


From: gnunet
Subject: [GNUnet-SVN] [taler-merchant] branch master updated: work on #4939: load multiple wire methods per instance
Date: Fri, 19 Jan 2018 01:20:34 +0100

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 e8f4501  work on #4939: load multiple wire methods per instance
e8f4501 is described below

commit e8f45018d3edf917a234c0841391ed4bc5cedf3e
Author: Christian Grothoff <address@hidden>
AuthorDate: Fri Jan 19 01:20:30 2018 +0100

    work on #4939: load multiple wire methods per instance
---
 src/backend/taler-merchant-httpd.c          | 185 ++++++++++++++++++++--------
 src/backend/taler-merchant-httpd.h          |  51 ++++++--
 src/backend/taler-merchant-httpd_pay.c      |  59 +++++----
 src/backend/taler-merchant-httpd_proposal.c |  19 ++-
 4 files changed, 224 insertions(+), 90 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index f4a1136..5fbb54f 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2014-2017 INRIA
+  (C) 2014-2018 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
@@ -317,8 +317,17 @@ hashmap_free (void *cls,
               void *value)
 {
   struct MerchantInstance *mi = value;
+  struct WireMethod *wm;
+
+  while (NULL != (wm = (mi->wm_head)))
+  {
+    GNUNET_CONTAINER_DLL_remove (mi->wm_head,
+                                 mi->wm_tail,
+                                 wm);
+    json_decref (wm->j_wire);
+    GNUNET_free (wm);
+  }
 
-  json_decref (mi->j_wire);
   GNUNET_free (mi->id);
   GNUNET_free (mi->keyfile);
   GNUNET_free (mi->name);
@@ -571,29 +580,127 @@ locations_iterator_cb (void *cls,
 
 
 /**
+ * Closure for the #wireformat_iterator_cb().
+ */
+struct WireFormatIteratorContext
+{
+  /**
+   * The global iteration context.
+   */
+  struct IterateInstancesCls *iic;
+
+  /**
+   * The merchant instance we are currently building.
+   */
+  struct MerchantInstance *mi;
+};
+
+
+/**
+ * Callback that looks for 'merchant-instance-wireformat-*' sections,
+ * and populates our wire method according to the data
+ *
+ * @param cls closure with a `struct WireFormatIteratorContext *`
+ * @section section name this callback gets
+ */
+static void
+wireformat_iterator_cb (void *cls,
+                        const char *section)
+{
+  struct WireFormatIteratorContext *wfic = cls;
+  struct MerchantInstance *mi = wfic->mi;
+  struct IterateInstancesCls *iic = wfic->iic;
+  char *instance_wiresection;
+  struct WireMethod *wm;
+  json_t *type;
+  char *emsg;
+
+  GNUNET_asprintf (&instance_wiresection,
+                   "merchant-instance-wireformat-%s",
+                   mi->id);
+  if (0 != strncmp (section,
+                    instance_wiresection,
+                    strlen (instance_wiresection)))
+  {
+    GNUNET_free (instance_wiresection);
+    return;
+  }
+  GNUNET_free (instance_wiresection);
+
+  wm = GNUNET_new (struct WireMethod);
+  /* FIXME: maybe use sorting to address #4939-12806? */
+  GNUNET_CONTAINER_DLL_insert (mi->wm_head,
+                               mi->wm_tail,
+                               wm);
+  wm->j_wire = iic->plugin->get_wire_details (iic->plugin->cls,
+                                              iic->config,
+                                              section);
+  if ( (NULL == (type = json_object_get (wm->j_wire,
+                                         "type"))) ||
+       (! json_is_string (type)) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Malformed wireformat: lacks type\n");
+    iic->ret |= GNUNET_SYSERR;
+    return;
+  }
+  wm->wire_method = json_string_value (type);
+
+  if (TALER_EC_NONE !=
+      iic->plugin->wire_validate (iic->plugin->cls,
+                                  wm->j_wire,
+                                  NULL,
+                                  &emsg))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Malformed wireformat: %s\n",
+                emsg);
+    GNUNET_free (emsg);
+    iic->ret |= GNUNET_SYSERR;
+    return;
+  }
+
+  if (GNUNET_OK !=
+      TALER_JSON_hash (wm->j_wire,
+                       &wm->h_wire))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to hash wireformat\n");
+    iic->ret |= GNUNET_SYSERR;
+  }
+
+#define EXTRADEBUG
+#ifdef EXTRADEBUGG
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Found wireformat instance:\n");
+  json_dumpf (wm->j_wire,
+              stdout,
+              0);
+  printf ("\n");
+#endif
+}
+
+
+/**
  * Callback that looks for 'merchant-instance-*' sections,
  * and populates accordingly each instance's data
  *
- * @param cls closure
+ * @param cls closure of type `struct IterateInstancesCls`
  * @section section name this callback gets
  */
 static void
 instances_iterator_cb (void *cls,
                        const char *section)
 {
-  char *substr;
+  struct IterateInstancesCls *iic = cls;
   char *token;
-  char *instance_wiresection;
   struct MerchantInstance *mi;
-  struct IterateInstancesCls *iic;
   struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
   /* used as hashmap keys */
   struct GNUNET_HashCode h_pk;
   struct GNUNET_HashCode h_id;
-  json_t *type;
-  char *emsg;
+  const char *substr;
 
-  iic = cls;
   substr = strstr (section,
                    "merchant-instance-");
 
@@ -616,7 +723,6 @@ instances_iterator_cb (void *cls,
               "Extracted token: %s\n",
               token + 1);
   mi = GNUNET_new (struct MerchantInstance);
-
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (iic->config,
                                              section,
@@ -709,61 +815,33 @@ instances_iterator_cb (void *cls,
   GNUNET_free (pk);
 
   mi->id = GNUNET_strdup (token + 1);
-  if (0 == strcmp ("default", mi->id))
+  if (0 == strcasecmp ("default",
+                       mi->id))
     iic->default_instance = GNUNET_YES;
 
-  GNUNET_asprintf (&instance_wiresection,
-                   "merchant-instance-wireformat-%s",
-                   mi->id);
-  mi->j_wire = iic->plugin->get_wire_details (iic->plugin->cls,
-                                              iic->config,
-                                              instance_wiresection);
-  GNUNET_free (instance_wiresection);
-  if ( (NULL == (type = json_object_get (mi->j_wire,
-                                         "type"))) ||
-       (! json_is_string (type)) )
+  /* Initialize wireformats */
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Malformed wireformat: lacks type\n");
-    iic->ret |= GNUNET_SYSERR;
-  }
-  mi->wire_method = json_string_value (type);
+    struct WireFormatIteratorContext wfic = {
+      .iic = iic,
+      .mi = mi
+    };
 
-  if (TALER_EC_NONE !=
-      iic->plugin->wire_validate (iic->plugin->cls,
-                                  mi->j_wire,
-                                  NULL,
-                                  &emsg))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Malformed wireformat: %s\n",
-                emsg);
-    GNUNET_free (emsg);
-    iic->ret |= GNUNET_SYSERR;
+    GNUNET_CONFIGURATION_iterate_sections (iic->config,
+                                           &wireformat_iterator_cb,
+                                           &wfic);
   }
 
-  if (GNUNET_OK !=
-      TALER_JSON_hash (mi->j_wire,
-                       &mi->h_wire))
+  if (NULL == mi->wm_head)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to hash wireformat\n");
+                "Failed to load wire formats for instance `%s'\n",
+                mi->id);
     iic->ret |= GNUNET_SYSERR;
   }
-#define EXTRADEBUG
-#ifdef EXTRADEBUGG
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Found wireformat instance:\n");
-              json_dumpf (mi->j_wire, stdout, 0);
-              printf ("\n");
-#endif
 
   GNUNET_CRYPTO_hash (mi->id,
                       strlen (mi->id),
                       &h_id);
-  GNUNET_CRYPTO_hash (&mi->pubkey.eddsa_pub,
-                      sizeof (struct GNUNET_CRYPTO_EddsaPublicKey),
-                      &h_pk);
   if (GNUNET_OK !=
       GNUNET_CONTAINER_multihashmap_put (by_id_map,
                                          &h_id,
@@ -774,6 +852,9 @@ instances_iterator_cb (void *cls,
                 "Failed to put an entry into the 'by_id' hashmap\n");
     iic->ret |= GNUNET_SYSERR;
   }
+  GNUNET_CRYPTO_hash (&mi->pubkey.eddsa_pub,
+                      sizeof (struct GNUNET_CRYPTO_EddsaPublicKey),
+                      &h_pk);
   if (GNUNET_OK !=
       GNUNET_CONTAINER_multihashmap_put (by_kpub_map,
                                          &h_pk,
@@ -892,7 +973,7 @@ iterate_instances (const struct GNUNET_CONFIGURATION_Handle 
*config,
   iic->plugin->library_name = lib_name;
   GNUNET_CONFIGURATION_iterate_sections (config,
                                          &instances_iterator_cb,
-                                         (void *) iic);
+                                         iic);
 
   if (GNUNET_NO == iic->default_instance)
   {
diff --git a/src/backend/taler-merchant-httpd.h 
b/src/backend/taler-merchant-httpd.h
index b10b964..18b1b54 100644
--- a/src/backend/taler-merchant-httpd.h
+++ b/src/backend/taler-merchant-httpd.h
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014, 2015 INRIA
+  Copyright (C) 2014-2018 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
@@ -72,6 +72,39 @@ struct IterateInstancesCls
 
 
 /**
+ * Supported wire method.  Kept in a DLL.
+ */
+struct WireMethod
+{
+  /**
+   * Next entry in DLL.
+   */
+  struct WireMethod *next;
+
+  /**
+   * Previous entry in DLL.
+   */
+  struct WireMethod *prev;
+
+  /**
+   * Which wire method is @e j_wire using?  Points into @e j_wire.
+   */
+  const char *wire_method;
+
+  /**
+   * Wire details for this instance
+   */
+  struct json_t *j_wire;
+
+  /**
+   * Hash of our wire format details as given in #j_wire.
+   */
+  struct GNUNET_HashCode h_wire;
+
+};
+
+
+/**
  * Information that defines a merchant "instance". Tha4673t way, a single
  * backend can account for several merchants, as used to do in donation
  * shops
@@ -96,23 +129,15 @@ struct MerchantInstance
    */
   char *keyfile;
 
-  /* NOTE: the *_wire-fields should eventually be moved into a DLL
-     once we implement #4939 */
-
   /**
-   * Which wire method is @e j_wire using?
+   * Next entry in DLL.
    */
-  const char *wire_method;
-
-  /**
-   * Wire details for this instance
-   */
-  struct json_t *j_wire;
+  struct WireMethod *wm_head;
 
   /**
-   * Hash of our wire format details as given in #j_wire.
+   * Previous entry in DLL.
    */
-  struct GNUNET_HashCode h_wire;
+  struct WireMethod *wm_tail;
 
   /**
    * Merchant's private key
diff --git a/src/backend/taler-merchant-httpd_pay.c 
b/src/backend/taler-merchant-httpd_pay.c
index 539a194..51ea2ce 100644
--- a/src/backend/taler-merchant-httpd_pay.c
+++ b/src/backend/taler-merchant-httpd_pay.c
@@ -169,6 +169,12 @@ struct PayContext
   struct MerchantInstance *mi;
 
   /**
+   * What wire method (of the @e mi) was selected by the wallet?
+   * Set in #parse_pay().
+   */
+  struct WireMethod *wm;
+
+  /**
    * Proposal data for the proposal that is being
    * payed for in this context.
    */
@@ -1078,7 +1084,8 @@ process_pay_with_exchange (void *cls,
     dc->refund_fee = denom_details->fee_refund;
     dc->wire_fee = *wire_fee;
 
-    GNUNET_assert (NULL != pc->mi->j_wire);
+    GNUNET_assert (NULL != pc->wm);
+    GNUNET_assert (NULL != pc->wm->j_wire);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Timing for this payment, wire_deadline: %llu, 
refund_deadline: %llu\n",
                 (unsigned long long) pc->wire_transfer_deadline.abs_value_us,
@@ -1086,7 +1093,7 @@ process_pay_with_exchange (void *cls,
     dc->dh = TALER_EXCHANGE_deposit (mh,
                                      &dc->amount_with_fee,
                                      pc->wire_transfer_deadline,
-                                     pc->mi->j_wire,
+                                     pc->wm->j_wire,
                                      &pc->h_contract_terms,
                                      &dc->coin_pub,
                                      &dc->ub_sig,
@@ -1133,7 +1140,7 @@ find_next_exchange (struct PayContext *pc)
     {
       pc->current_exchange = dc->exchange_url;
       pc->fo = TMH_EXCHANGES_find_exchange (pc->current_exchange,
-                                           pc->mi->wire_method,
+                                           pc->wm->wire_method,
                                            &process_pay_with_exchange,
                                            pc);
       if (NULL == pc->fo)
@@ -1298,6 +1305,7 @@ parse_pay (struct MHD_Connection *connection,
     GNUNET_JSON_spec_end()
   };
   enum GNUNET_DB_QueryStatus qs;
+  const char *session_id;
 
   res = TMH_PARSE_json_data (connection,
                              root,
@@ -1308,11 +1316,10 @@ parse_pay (struct MHD_Connection *connection,
     return res;
   }
 
-  const char *session_id = json_string_value (json_object_get (root,
-                                                               "session_id"));
-  if (NULL != session_id) {
+  session_id = json_string_value (json_object_get (root,
+                                                   "session_id"));
+  if (NULL != session_id)
     pc->session_id = GNUNET_strdup (session_id);
-  }
   pc->order_id = GNUNET_strdup (order_id);
   GNUNET_assert (NULL == pc->contract_terms);
   qs = db->find_contract_terms (db->cls,
@@ -1446,17 +1453,24 @@ parse_pay (struct MHD_Connection *connection,
     }
   }
 
-  /* NOTE: In the future, iterate over all wire hashes
-     available to a given instance here! (#4939) */
-  if (0 != memcmp (&pc->h_wire,
-                   &pc->mi->h_wire,
-                   sizeof (struct GNUNET_HashCode)))
+  /* find wire method */
   {
-    GNUNET_break (0);
-    GNUNET_JSON_parse_free (spec);
-    return TMH_RESPONSE_reply_internal_error (connection,
-                                              TALER_EC_PAY_WIRE_HASH_UNKNOWN,
-                                              "Did not find matching wire 
details");
+    struct WireMethod *wm;
+
+    wm = pc->mi->wm_head;
+    while (0 != memcmp (&pc->h_wire,
+                        &wm->h_wire,
+                        sizeof (struct GNUNET_HashCode)))
+      wm = wm->next;
+    if (NULL == wm)
+    {
+      GNUNET_break (0);
+      GNUNET_JSON_parse_free (spec);
+      return TMH_RESPONSE_reply_internal_error (connection,
+                                                TALER_EC_PAY_WIRE_HASH_UNKNOWN,
+                                                "Did not find matching wire 
details");
+    }
+    pc->wm = wm;
   }
 
   /* parse optional details */
@@ -1866,12 +1880,13 @@ begin_transaction (struct PayContext *pc)
                                                             "hint", "Merchant 
database error"));
       return;
     }
+
     if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) &&
-        ( (0 != memcmp (&h_xwire,
-                        &pc->mi->h_wire,
-                        sizeof (struct GNUNET_HashCode))) ||
-          (xtimestamp.abs_value_us != pc->timestamp.abs_value_us) ||
+        ( (xtimestamp.abs_value_us != pc->timestamp.abs_value_us) ||
           (xrefund.abs_value_us != pc->refund_deadline.abs_value_us) ||
+           (0 != memcmp (&h_xwire,
+                         &pc->h_wire,
+                         sizeof (struct GNUNET_HashCode))) ||
           (0 != TALER_amount_cmp (&xtotal_amount,
                                   &pc->amount) ) ) )
     {
@@ -1917,7 +1932,7 @@ begin_transaction (struct PayContext *pc)
     qs_st = db->store_transaction (db->cls,
                                    &pc->h_contract_terms,
                                    &pc->mi->pubkey,
-                                   &pc->mi->h_wire,
+                                   &pc->h_wire,
                                    pc->timestamp,
                                    pc->refund_deadline,
                                    &pc->amount);
diff --git a/src/backend/taler-merchant-httpd_proposal.c 
b/src/backend/taler-merchant-httpd_proposal.c
index 97aa193..318801e 100644
--- a/src/backend/taler-merchant-httpd_proposal.c
+++ b/src/backend/taler-merchant-httpd_proposal.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2014, 2015, 2016, 2017 INRIA
+  (C) 2014, 2015, 2016, 2018 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
@@ -157,6 +157,7 @@ proposal_put (struct MHD_Connection *connection,
   };
   enum GNUNET_DB_QueryStatus qs;
   const char *instance;
+  struct WireMethod *wm;
 
   /* Add order_id if it doesn't exist. */
   if (NULL ==
@@ -387,12 +388,24 @@ proposal_put (struct MHD_Connection *connection,
   json_object_set (order,
                    "auditors",
                    j_auditors);
+  /* TODO (#4939-12806): add proper mechanism for selection of wire method(s) 
by merchant! */
+  wm = mi->wm_head;
+
+  if (NULL == wm)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "No wire method available for specified instance\n");
+    GNUNET_JSON_parse_free (spec);
+    return TMH_RESPONSE_reply_not_found (connection,
+                                        TALER_EC_CONTRACT_INSTANCE_UNKNOWN,
+                                        "No wire method configured for 
instance");
+  }
   json_object_set_new (order,
                        "H_wire",
-                      GNUNET_JSON_from_data_auto (&mi->h_wire));
+                      GNUNET_JSON_from_data_auto (&wm->h_wire));
   json_object_set_new (order,
                        "wire_method",
-                      json_string (mi->wire_method));
+                      json_string (wm->wire_method));
   json_object_set_new (order,
                        "merchant_pub",
                       GNUNET_JSON_from_data_auto (&mi->pubkey));

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



reply via email to

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