aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchangedb')
-rw-r--r--src/exchangedb/exchangedb.conf7
-rw-r--r--src/exchangedb/exchangedb_fees.c243
-rw-r--r--src/exchangedb/test_exchangedb_fees.c46
3 files changed, 296 insertions, 0 deletions
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;
+}