aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/benchmark/taler-exchange-benchmark.conf9
-rw-r--r--src/exchange-lib/test_exchange_api.conf13
-rw-r--r--src/exchange/exchange.conf4
-rw-r--r--src/exchange/test-taler-exchange-aggregator-postgres.conf8
-rw-r--r--src/exchange/test_taler_exchange_httpd.conf8
-rw-r--r--src/exchangedb/exchangedb.conf7
-rw-r--r--src/exchangedb/exchangedb_fees.c243
-rw-r--r--src/exchangedb/test_exchangedb_fees.c46
-rw-r--r--src/include/taler_wire_lib.h24
-rw-r--r--src/wire/wire-sepa.conf6
-rw-r--r--src/wire/wire-test.conf6
-rw-r--r--src/wire/wire.c78
12 files changed, 426 insertions, 26 deletions
diff --git a/src/benchmark/taler-exchange-benchmark.conf b/src/benchmark/taler-exchange-benchmark.conf
index 16a26d8ae..a77df46a2 100644
--- a/src/benchmark/taler-exchange-benchmark.conf
+++ b/src/benchmark/taler-exchange-benchmark.conf
@@ -11,11 +11,6 @@ CURRENCY = KUDOS
[exchange]
-# Wire format supported by the exchange
-# We use 'test' for testing of the actual
-# coin operations, and 'sepa' to test SEPA-specific routines.
-WIREFORMAT = test
-
# HTTP port the exchange listens to
PORT = 8081
# How to access our database
@@ -27,6 +22,9 @@ MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG
[exchangedb-postgres]
DB_CONN_STR = "postgres:///talercheck"
+[exchange-wire-test]
+# Enable 'test' for testing of the actual coin operations.
+ENABLE = YES
[exchange-wire-outgoing-test]
# What is the main website of the bank?
@@ -88,4 +86,3 @@ fee_deposit = KUDOS:0.00
fee_refresh = KUDOS:0.00
fee_refund = KUDOS:0.00
rsa_keysize = 1024
-
diff --git a/src/exchange-lib/test_exchange_api.conf b/src/exchange-lib/test_exchange_api.conf
index 83be7c410..76ade18fe 100644
--- a/src/exchange-lib/test_exchange_api.conf
+++ b/src/exchange-lib/test_exchange_api.conf
@@ -10,11 +10,6 @@ CURRENCY = EUR
[exchange]
-# Wire format supported by the exchange
-# We use 'test' for testing of the actual
-# coin operations, and 'sepa' to test SEPA-specific routines.
-WIREFORMAT = test sepa
-
# HTTP port the exchange listens to
PORT = 8081
@@ -31,11 +26,19 @@ BASE_URL = "https://exchange.com/"
[exchangedb-postgres]
DB_CONN_STR = "postgres:///talercheck"
+[exchange-wire-sepa]
+# Enable 'sepa' to test SEPA-specific routines.
+ENABLE = YES
+
[exchange-wire-incoming-sepa]
# This is the response we give out for the /wire request. It provides
# wallets with the bank information for transfers to the exchange.
SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json
+[exchange-wire-test]
+# Enable 'test' for testing of the actual coin operations.
+ENABLE = YES
+
[exchange-wire-incoming-test]
# This is the response we give out for the /wire request. It provides
# wallets with the bank information for transfers to the exchange.
diff --git a/src/exchange/exchange.conf b/src/exchange/exchange.conf
index a226d4149..4c10b31aa 100644
--- a/src/exchange/exchange.conf
+++ b/src/exchange/exchange.conf
@@ -7,10 +7,6 @@
# in respective subdirectories.)
KEYDIR = ${TALER_DATA_HOME}/exchange/live-keys/
-# Wire format supported by the exchange. We use 'test' for testing of
-# the actual coin operations.
-# WIREFORMAT = test
-
# Master public key used to sign the exchange's various keys
# MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG
diff --git a/src/exchange/test-taler-exchange-aggregator-postgres.conf b/src/exchange/test-taler-exchange-aggregator-postgres.conf
index 7bcadc157..4aa74b037 100644
--- a/src/exchange/test-taler-exchange-aggregator-postgres.conf
+++ b/src/exchange/test-taler-exchange-aggregator-postgres.conf
@@ -10,11 +10,6 @@ CURRENCY = EUR
# The DB plugin to use
DB = postgres
-# Wire format supported by the exchange
-# We use 'test' for testing of the actual
-# coin operations.
-WIREFORMAT = test
-
# HTTP port the exchange listens to
PORT = 8081
@@ -30,6 +25,9 @@ BASE_URL = "https://exchange.taler.net/"
DB_CONN_STR = postgres:///talercheck
+[exchange-wire-test]
+# Enable 'test' for testing of the actual coin operations.
+ENABLE = YES
[exchange-wire-outgoing-test]
# What is the main website of the bank?
diff --git a/src/exchange/test_taler_exchange_httpd.conf b/src/exchange/test_taler_exchange_httpd.conf
index e1c30615b..945031dd1 100644
--- a/src/exchange/test_taler_exchange_httpd.conf
+++ b/src/exchange/test_taler_exchange_httpd.conf
@@ -9,11 +9,6 @@ CURRENCY = EUR
[exchange]
-# Wire format supported by the exchange
-# We use 'test' for testing of the actual
-# coin operations.
-WIREFORMAT = test
-
# HTTP port the exchange listens to
PORT = 8081
@@ -27,6 +22,9 @@ DB = postgres
[exchangedb-postgres]
DB_CONN_STR = "postgres:///talercheck"
+[exchange-wire-test]
+# Enable 'test' for testing of the actual coin operations.
+ENABLE = YES
[exchange-wire-outgoing-test]
# What is the main website of the bank?
diff --git a/src/exchangedb/exchangedb.conf b/src/exchangedb/exchangedb.conf
index 19277ed23..4640507dc 100644
--- a/src/exchangedb/exchangedb.conf
+++ b/src/exchangedb/exchangedb.conf
@@ -5,3 +5,10 @@
[exchangedb]
# Where do we expect to find information about auditors?
AUDITOR_BASE_DIR = ${TALER_DATA_HOME}/auditors/
+
+# Where do we expect to find information about wire transfer fees
+# for aggregate payments? These are the amounts we charge (subtract)
+# the merchant per wire transfer. The directory is expected to
+# contain files "$METHOD.fee" with the cost structure, where
+# $METHOD corresponds to a wire transfer method.
+WIREFEE_BASE_DIR = ${TALER_DATA_HOME}/wirefees/
diff --git a/src/exchangedb/exchangedb_fees.c b/src/exchangedb/exchangedb_fees.c
new file mode 100644
index 000000000..938b61c19
--- /dev/null
+++ b/src/exchangedb/exchangedb_fees.c
@@ -0,0 +1,243 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2017 GNUnet e.V.
+
+ 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
+ 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 exchangedb/exchangedb_fees.c
+ * @brief Logic to read/write/convert aggregation wire fees (not other fees!)
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_exchangedb_lib.h"
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Structure for wire fees on disk.
+ */
+struct TALER_WireFeeDiskP
+{
+
+ /**
+ * Wire fee details.
+ */
+ struct TALER_MasterWireFeePS wf;
+
+
+ /**
+ * Signature affirming the above fee structure.
+ */
+ struct TALER_MasterSignatureP master_sig;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+/**
+ * Convert @a wd disk format to host format.
+ *
+ * @param wd aggregate fees, disk format
+ * @return fees in host format
+ */
+static struct TALER_EXCHANGEDB_AggregateFees *
+wd2af (const struct TALER_WireFeeDiskP *wd)
+{
+ struct TALER_EXCHANGEDB_AggregateFees *af;
+
+ af = GNUNET_new (struct TALER_EXCHANGEDB_AggregateFees);
+ af->start_date = GNUNET_TIME_absolute_ntoh (wd->wf.start_date);
+ af->end_date = GNUNET_TIME_absolute_ntoh (wd->wf.end_date);
+ TALER_amount_ntoh (&af->wire_fee,
+ &wd->wf.wire_fee);
+ af->master_sig = wd->master_sig;
+ return af;
+}
+
+
+/**
+ * Read the current fee structure from disk.
+ *
+ * @param cfg configuration to use
+ * @param wireplugin name of the wire plugin to read fees for
+ * @return sorted list of aggregation fees, NULL on error
+ */
+struct TALER_EXCHANGEDB_AggregateFees *
+TALER_EXCHANGEDB_fees_read (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *wireplugin)
+{
+ char *wirefee_base_dir;
+ char *fn;
+ struct GNUNET_DISK_FileHandle *fh;
+ struct TALER_WireFeeDiskP wd;
+ struct TALER_EXCHANGEDB_AggregateFees *af;
+ struct TALER_EXCHANGEDB_AggregateFees *endp;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (cfg,
+ "exchangedb",
+ "WIREFEE_BASE_DIR",
+ &wirefee_base_dir))
+ return NULL;
+ GNUNET_asprintf (&fn,
+ "%s" DIR_SEPARATOR_STR "%s.fee",
+ wirefee_base_dir,
+ wireplugin);
+ GNUNET_free (wirefee_base_dir);
+ fh = GNUNET_DISK_file_open (fn,
+ GNUNET_DISK_OPEN_READ,
+ GNUNET_DISK_PERM_NONE);
+ GNUNET_free (fn);
+ if (NULL == fh)
+ return NULL;
+
+ af = NULL;
+ endp = NULL;
+ while (sizeof (wd) ==
+ GNUNET_DISK_file_read (fh,
+ &wd,
+ sizeof (wd)))
+ {
+ struct TALER_EXCHANGEDB_AggregateFees *n;
+
+ n = wd2af (&wd);
+ if ( ( (NULL == af) ||
+ (endp->end_date.abs_value_us == n->start_date.abs_value_us) ) &&
+ (n->start_date.abs_value_us < n->end_date.abs_value_us) )
+ {
+ /* append to list */
+ if (NULL != endp)
+ endp->next = n;
+ else
+ af = n;
+ endp = n;
+ }
+ else
+ {
+ /* We expect file to be in chronological order! */
+ GNUNET_break (0);
+ GNUNET_DISK_file_close (fh);
+ GNUNET_free (n);
+ TALER_EXCHANGEDB_fees_free (af);
+ return NULL;
+ }
+ }
+ GNUNET_DISK_file_close (fh);
+ return af;
+}
+
+
+/**
+ * Convert @a af to @a wf.
+ *
+ * @param[in,out] af aggregate fees, host format (updated to round time)
+ * @param[out] wf aggregate fees, disk / signature format
+ */
+void
+TALER_EXCHANGEDB_fees_2_wf (struct TALER_EXCHANGEDB_AggregateFees *af,
+ struct TALER_MasterWireFeePS *wf)
+{
+ (void) GNUNET_TIME_round_abs (&af->start_date);
+ (void) GNUNET_TIME_round_abs (&af->end_date);
+ wf->purpose.size = htonl (sizeof (*wf));
+ wf->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES);
+ wf->start_date = GNUNET_TIME_absolute_hton (af->start_date);
+ wf->end_date = GNUNET_TIME_absolute_hton (af->end_date);
+ TALER_amount_hton (&wf->wire_fee,
+ &af->wire_fee);
+}
+
+
+/**
+ * Write given fee structure to disk.
+ *
+ * @param filename where to write the fees
+ * @param af fee structure to write
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+int
+TALER_EXCHANGEDB_fees_write (const char *filename,
+ struct TALER_EXCHANGEDB_AggregateFees *af)
+{
+ struct GNUNET_DISK_FileHandle *fh;
+ struct TALER_WireFeeDiskP wd;
+ struct TALER_EXCHANGEDB_AggregateFees *last;
+
+ if (GNUNET_OK !=
+ GNUNET_DISK_directory_create_for_file (filename))
+ return GNUNET_SYSERR;
+
+ fh = GNUNET_DISK_file_open (filename,
+ GNUNET_DISK_OPEN_WRITE |
+ GNUNET_DISK_OPEN_TRUNCATE |
+ GNUNET_DISK_OPEN_CREATE,
+ GNUNET_DISK_PERM_USER_READ |
+ GNUNET_DISK_PERM_USER_WRITE);
+ if (NULL == fh)
+ return GNUNET_SYSERR;
+
+ last = NULL;
+ while (NULL != af)
+ {
+ if ( ( (NULL != last) &&
+ (last->end_date.abs_value_us != af->start_date.abs_value_us) ) ||
+ (af->start_date.abs_value_us >= af->end_date.abs_value_us) )
+ {
+ /* @a af malformed, refusing to write file that will be rejected */
+ GNUNET_break (0);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_file_close (fh));
+ return GNUNET_SYSERR;
+ }
+ TALER_EXCHANGEDB_fees_2_wf (af,
+ &wd.wf);
+ wd.master_sig = af->master_sig;
+ af = af->next;
+ if (sizeof (wd) !=
+ GNUNET_DISK_file_write (fh,
+ &wd,
+ sizeof (wd)))
+ {
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_file_close (fh));
+ return GNUNET_SYSERR;
+ }
+ }
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_file_close (fh));
+ return GNUNET_OK;
+}
+
+
+/**
+ * Free @a af data structure
+ *
+ * @param af list to free
+ */
+void
+TALER_EXCHANGEDB_fees_free (struct TALER_EXCHANGEDB_AggregateFees *af)
+{
+ struct TALER_EXCHANGEDB_AggregateFees *next;
+
+ while (NULL != af)
+ {
+ next = af->next;
+ GNUNET_free (af);
+ af = next;
+ }
+}
+
+
+/* end of exchangedb_fees.c */
diff --git a/src/exchangedb/test_exchangedb_fees.c b/src/exchangedb/test_exchangedb_fees.c
new file mode 100644
index 000000000..e23879ead
--- /dev/null
+++ b/src/exchangedb/test_exchangedb_fees.c
@@ -0,0 +1,46 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2017 Inria & GNUnet e. V.
+
+ 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
+ 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 exchangedb/test_exchangedb_fees.c
+ * @brief test cases for functions in exchangedb/exchangedb_fees.c
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet/gnunet_util_lib.h"
+#include "taler_signatures.h"
+#include "taler_exchangedb_lib.h"
+
+
+int
+main (int argc,
+ const char *const argv[])
+{
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+ int ret;
+
+ ret = 1;
+ GNUNET_log_setup ("test-exchangedb-fees",
+ "WARNING",
+ NULL);
+ cfg = GNUNET_CONFIGURATION_create ();
+
+ GNUNET_CONFIGURATION_set_value_string (cfg,
+ "exchangedb",
+ "AUDITOR_BASE_DIR",
+ tmpdir);
+ ret = 0;
+ return ret;
+}
diff --git a/src/include/taler_wire_lib.h b/src/include/taler_wire_lib.h
index b67f620f4..68c36e889 100644
--- a/src/include/taler_wire_lib.h
+++ b/src/include/taler_wire_lib.h
@@ -45,4 +45,28 @@ void
TALER_WIRE_plugin_unload (struct TALER_WIRE_Plugin *plugin);
+/**
+ * Signature of a function to be called on each enabled
+ * wire plugin.
+ *
+ * @param cls closure
+ * @param name name of the enabled plugin
+ */
+typedef void
+(*TALER_WIRE_EnabledCallback)(void *cls,
+ const char *name);
+
+
+/**
+ * Check which wire plugins are enabled in @a cfg and call @a cb for each one.
+ *
+ * @param cfg configuration to use
+ * @param cb callback to invoke
+ * @param cb_cls closure for @a cb
+ */
+void
+TALER_WIRE_find_enabled (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ TALER_WIRE_EnabledCallback cb,
+ void *cb_cls);
+
#endif
diff --git a/src/wire/wire-sepa.conf b/src/wire/wire-sepa.conf
index b7c09153f..88d2ac03c 100644
--- a/src/wire/wire-sepa.conf
+++ b/src/wire/wire-sepa.conf
@@ -1,5 +1,11 @@
+# This file is in the public domain.
+#
# Configuration for SEPA wire plugin.
+[exchange-wire-sepa]
+# Set to "YES" to activate the 'sepa' plugin.
+ENABLE = NO
+
[exchange-wire-incoming-sepa]
# This is the response we give out for the /wire request. It provides
# wallets with the bank information for transfers to the exchange.
diff --git a/src/wire/wire-test.conf b/src/wire/wire-test.conf
index fc03f1b83..fcc156426 100644
--- a/src/wire/wire-test.conf
+++ b/src/wire/wire-test.conf
@@ -1,5 +1,11 @@
# This file is in the public domain.
#
+# Configuration for TEST wire plugin.
+#
+[exchange-wire-test]
+# Set to "YES" to activate the 'test' plugin.
+ENABLE = NO
+
[exchange-wire-incoming-test]
# This is the response we give out for the /wire request. It provides
# wallets with the bank information for transfers to the exchange.
diff --git a/src/wire/wire.c b/src/wire/wire.c
index 4d53b0d0b..c799334f9 100644
--- a/src/wire/wire.c
+++ b/src/wire/wire.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2015, 2016 GNUnet e.V.
+ (C) 2015, 2016, 2017 GNUnet e.V.
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
@@ -69,4 +69,80 @@ TALER_WIRE_plugin_unload (struct TALER_WIRE_Plugin *plugin)
}
+/**
+ * Closure of #check_for_wire.
+ */
+struct FindEnabledWireContext
+{
+ /**
+ * Configuration we are usign.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * Callback to invoke.
+ */
+ TALER_WIRE_EnabledCallback cb;
+
+ /**
+ * Closure for @e cb.
+ */
+ void *cb_cls;
+};
+
+
+/**
+ * Check if @a section begins with "exchange-wire-", and if
+ * so if the "ENABLE" option is set to "YES". If both are
+ * true, call the callback from the context with the
+ * rest of the section name.
+ *
+ * @param cls our `struct FindEnabledWireContext`
+ * @param section name of a section in the configuration
+ */
+static void
+check_for_wire (void *cls,
+ const char *section)
+{
+ struct FindEnabledWireContext *ctx = cls;
+ const char *name;
+
+ if (0 != strncasecmp (section,
+ "exchange-wire-",
+ strlen ("exchange-wire-")))
+ return;
+ if (GNUNET_YES !=
+ GNUNET_CONFIGURATION_get_value_yesno (ctx->cfg,
+ section,
+ "ENABLE"))
+ return;
+ name = &section[strlen ("exchange-wire-")];
+ ctx->cb (ctx->cb_cls,
+ name);
+}
+
+
+/**
+ * Check which wire plugins are enabled in @a cfg and call @a cb for each one.
+ *
+ * @param cfg configuration to use
+ * @param cb callback to invoke
+ * @param cb_cls closure for @a cb
+ */
+void
+TALER_WIRE_find_enabled (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ TALER_WIRE_EnabledCallback cb,
+ void *cb_cls)
+{
+ struct FindEnabledWireContext ctx;
+
+ ctx.cfg = cfg;
+ ctx.cb = cb;
+ ctx.cb_cls = cb_cls;
+ GNUNET_CONFIGURATION_iterate_sections (cfg,
+ &check_for_wire,
+ &ctx);
+}
+
+
/* end of wire.c */