[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [taler-merchant] branch master updated: work on #4939: load multiple wire methods per instance,
gnunet <=