diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-03-03 20:31:29 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-03-03 20:31:29 +0100 |
commit | f406f96129766c144c1531dc853969664f410d8c (patch) | |
tree | 6fdbae6ed117d3057ae9101ab4f799f5e3354d59 /src/exchange-tools | |
parent | 364abbaea1383bd7d8311269d596bdc3c1d4b591 (diff) |
implement #4929: add wire transfer fee to /wire (but not yet charged by aggregator)
Diffstat (limited to 'src/exchange-tools')
-rw-r--r-- | src/exchange-tools/Makefile.am | 1 | ||||
-rw-r--r-- | src/exchange-tools/taler-exchange-keyup.c | 197 |
2 files changed, 194 insertions, 4 deletions
diff --git a/src/exchange-tools/Makefile.am b/src/exchange-tools/Makefile.am index 9c2580e77..60b2cc2c5 100644 --- a/src/exchange-tools/Makefile.am +++ b/src/exchange-tools/Makefile.am @@ -25,6 +25,7 @@ taler_exchange_keyup_LDADD = \ $(LIBGCRYPT_LIBS) \ $(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/pq/libtalerpq.la \ + $(top_builddir)/src/wire/libtalerwire.la \ $(top_builddir)/src/exchangedb/libtalerexchangedb.la \ -lgnunetutil $(XLIB) taler_exchange_keyup_LDFLAGS = $(POSTGRESQL_LDFLAGS) diff --git a/src/exchange-tools/taler-exchange-keyup.c b/src/exchange-tools/taler-exchange-keyup.c index 76801738e..c3e58db9c 100644 --- a/src/exchange-tools/taler-exchange-keyup.c +++ b/src/exchange-tools/taler-exchange-keyup.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015, 2016 GNUnet e.V. + Copyright (C) 2014-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 @@ -23,6 +23,7 @@ */ #include <platform.h> #include "taler_exchangedb_lib.h" +#include "taler_wire_lib.h" /** * When generating filenames from a cryptographic hash, we do not use @@ -189,6 +190,11 @@ static char *exchange_directory; static char *pretend_time_str; /** + * Directory where we should write the wire transfer fee structure. + */ +static char *feedir; + +/** * Handle to the exchange's configuration */ static const struct GNUNET_CONFIGURATION_Handle *kcfg; @@ -215,6 +221,11 @@ static struct TALER_MasterPublicKeyP master_public_key; static struct GNUNET_TIME_Absolute lookahead_sign_stamp; /** + * Largest duration for spending of any key. + */ +static struct GNUNET_TIME_Relative max_duration_spend; + +/** * Return value from main(). */ static int global_ret; @@ -598,6 +609,8 @@ get_cointype_params (const char *ct, return GNUNET_SYSERR; } GNUNET_TIME_round_rel (¶ms->duration_spend); + max_duration_spend = GNUNET_TIME_relative_max (max_duration_spend, + params->duration_spend); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (kcfg, ct, @@ -862,6 +875,151 @@ exchange_keys_update_denomkeys () /** + * Sign @a af with @a priv + * + * @param[in|out] af fee structure to sign + * @param priv private key to use for signing + */ +static void +sign_af (struct TALER_EXCHANGEDB_AggregateFees *af, + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) +{ + struct TALER_MasterWireFeePS wf; + + TALER_EXCHANGEDB_fees_2_wf (af, + &wf); + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_eddsa_sign (priv, + &wf.purpose, + &af->master_sig.eddsa_signature)); +} + + +/** + * Output the wire fee structure. Must be run after #max_duration_spend + * was initialized. + * + * @param cls pointer to `int`, set to #GNUNET_SYSERR on error + * @param wiremethod method to write fees for + */ +static void +create_wire_fee_for_method (void *cls, + const char *wiremethod) +{ + int *ret = cls; + struct TALER_EXCHANGEDB_AggregateFees *af_head; + struct TALER_EXCHANGEDB_AggregateFees *af_tail; + unsigned int year; + struct GNUNET_TIME_Absolute last_date; + struct GNUNET_TIME_Absolute start_date; + struct GNUNET_TIME_Absolute end_date; + char yearstr[12]; + char *fn; + char *section; + + if (GNUNET_OK != *ret) + return; + last_date = GNUNET_TIME_absolute_max (last_date, + GNUNET_TIME_absolute_add (lookahead_sign_stamp, + max_duration_spend)); + GNUNET_asprintf (§ion, + "exchange-wire-%s", + wiremethod); + GNUNET_asprintf (&fn, + "%s%s.fee", + feedir, + wiremethod); + af_head = NULL; + af_tail = NULL; + year = GNUNET_TIME_get_current_year (); + start_date = GNUNET_TIME_year_to_time (year); + while (start_date.abs_value_us < last_date.abs_value_us) + { + struct TALER_EXCHANGEDB_AggregateFees *af; + char *opt; + char *amounts; + + GNUNET_snprintf (yearstr, + sizeof (yearstr), + "%u", + year); + end_date = GNUNET_TIME_year_to_time (year + 1); + af = GNUNET_new (struct TALER_EXCHANGEDB_AggregateFees); + af->start_date = start_date; + af->end_date = end_date; + GNUNET_asprintf (&opt, + "wire-fee-%u", + year); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (kcfg, + section, + opt, + &amounts)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + section, + opt); + *ret = GNUNET_SYSERR; + GNUNET_free (opt); + break; + } + if (GNUNET_OK != + TALER_string_to_amount (amounts, + &af->wire_fee)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid amount `%s' specified in `%s' under `%s'\n", + amounts, + wiremethod, + opt); + *ret = GNUNET_SYSERR; + GNUNET_free (amounts); + GNUNET_free (opt); + break; + } + GNUNET_free (amounts); + GNUNET_free (opt); + sign_af (af, + &master_priv.eddsa_priv); + if (NULL == af_tail) + af_head = af; + else + af_tail->next = af; + af_tail = af; + start_date = end_date; + year++; + } + if ( (GNUNET_OK == *ret) && + (GNUNET_OK != + TALER_EXCHANGEDB_fees_write (fn, + af_head)) ) + *ret = GNUNET_SYSERR; + GNUNET_free (section); + GNUNET_free (fn); + TALER_EXCHANGEDB_fees_free (af_head); +} + + +/** + * Output the wire fee structure. Must be run after #max_duration_spend + * was initialized. + * + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +static int +create_wire_fees () +{ + int ret; + + ret = GNUNET_OK; + TALER_WIRE_find_enabled (kcfg, + &create_wire_fee_for_method, + &ret); + return ret; +} + + +/** * Main function that will be run. * * @param cls closure @@ -896,6 +1054,29 @@ run (void *cls, { now = GNUNET_TIME_absolute_get (); } + if (NULL == feedir) + { + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (kcfg, + "exchangedb", + "WIREFEE_BASE_DIR", + &feedir)) + { + fprintf (stderr, + "Wire fee directory not given in neither configuration nor command-line\n"); + global_ret = 1; + return; + } + } + if (GNUNET_OK != + GNUNET_DISK_directory_create (feedir)) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, + "mkdir", + feedir); + global_ret = 1; + return; + } GNUNET_TIME_round_abs (&now); if ( (NULL == masterkeyfile) && (GNUNET_OK != @@ -1022,10 +1203,10 @@ run (void *cls, global_ret = 1; return; } - if (NULL != auditor_output_file) + if (GNUNET_OK != create_wire_fees ()) { - FCLOSE (auditor_output_file); - auditor_output_file = NULL; + global_ret = 1; + return; } } @@ -1051,6 +1232,9 @@ main (int argc, {'m', "master-key", "FILE", "master key file (private key)", 1, &GNUNET_GETOPT_set_filename, &masterkeyfile}, + {'f', "feedir", "DIRNAME", + "directory where to write wire transfer fee structure", 1, + &GNUNET_GETOPT_set_filename, &feedir}, {'o', "output", "FILE", "auditor denomination key signing request file to create", 1, &GNUNET_GETOPT_set_filename, &auditorrequestfile}, @@ -1072,6 +1256,11 @@ main (int argc, options, &run, NULL)) return 1; + if (NULL != auditor_output_file) + { + FCLOSE (auditor_output_file); + auditor_output_file = NULL; + } return global_ret; } |