gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: refactor /wire to include logic


From: gnunet
Subject: [taler-exchange] branch master updated: refactor /wire to include logic to return the wad fee (for W2W payments)
Date: Sat, 05 Mar 2022 14:36:58 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 7ff58c3d refactor /wire to include logic to return the wad fee (for 
W2W payments)
7ff58c3d is described below

commit 7ff58c3d8f2351c57142b4b65ab75304f355fc4f
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Mar 5 14:36:49 2022 +0100

    refactor /wire to include logic to return the wad fee (for W2W payments)
---
 src/auditor/taler-helper-auditor-aggregation.c     |  21 +--
 src/auditor/taler-helper-auditor-reserves.c        |   6 +-
 src/benchmark/taler-aggregator-benchmark.c         |   9 +-
 src/exchange-tools/taler-exchange-offline.c        |  41 +++---
 src/exchange/taler-exchange-aggregator.c           |  12 +-
 src/exchange/taler-exchange-closer.c               |   8 +-
 .../taler-exchange-httpd_management_wire_fees.c    |  41 ++----
 src/exchange/taler-exchange-httpd_transfers_get.c  |  12 +-
 src/exchange/taler-exchange-httpd_wire.c           |  12 +-
 src/exchangedb/exchange-0001.sql                   |  23 +++
 src/exchangedb/irbt_callbacks.c                    |  31 +++-
 src/exchangedb/lrbt_callbacks.c                    |  58 +++++++-
 src/exchangedb/plugin_exchangedb_postgres.c        | 161 ++++++++++-----------
 src/exchangedb/test_exchangedb.c                   |  31 ++--
 src/include/taler_crypto_lib.h                     |  36 ++++-
 src/include/taler_exchange_service.h               |  14 +-
 src/include/taler_exchangedb_plugin.h              | 110 +++++++++++---
 src/include/taler_signatures.h                     |  10 +-
 src/include/taler_testing_lib.h                    |   5 +-
 src/lib/exchange_api_management_set_wire_fee.c     |  11 +-
 src/lib/exchange_api_wire.c                        |  20 ++-
 src/testing/test_auditor_api.c                     |   1 +
 src/testing/test_exchange_api.c                    |   1 +
 .../test_exchange_api_keys_cherry_picking.c        |   1 +
 src/testing/test_exchange_management_api.c         |   5 +
 src/testing/test_kyc_api.c                         |   1 +
 src/testing/test_taler_exchange_aggregator.c       |   1 +
 src/testing/test_taler_exchange_wirewatch.c        |   1 +
 src/testing/testing_api_cmd_offline_sign_fees.c    |  10 +-
 src/testing/testing_api_cmd_set_wire_fee.c         |  25 ++--
 src/testing/testing_api_cmd_wire.c                 |   2 +-
 src/util/offline_signatures.c                      |  20 +--
 src/util/util.c                                    |  40 +++++
 33 files changed, 503 insertions(+), 277 deletions(-)

diff --git a/src/auditor/taler-helper-auditor-aggregation.c 
b/src/auditor/taler-helper-auditor-aggregation.c
index 33c51731..da10ae76 100644
--- a/src/auditor/taler-helper-auditor-aggregation.c
+++ b/src/auditor/taler-helper-auditor-aggregation.c
@@ -305,14 +305,9 @@ struct WireFeeInfo
   struct GNUNET_TIME_Timestamp end_date;
 
   /**
-   * How high is the wire fee.
+   * How high are the wire fees.
    */
-  struct TALER_Amount wire_fee;
-
-  /**
-   * How high is the closing fee.
-   */
-  struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
 
 };
 
@@ -911,7 +906,7 @@ get_wire_fee (struct AggregationContext *ac,
         GNUNET_TIME_timestamp_cmp (pos->end_date,
                                    >,
                                    timestamp) )
-      return &pos->wire_fee;
+      return &pos->fees.wire;
     if (GNUNET_TIME_timestamp_cmp (pos->start_date,
                                    >,
                                    timestamp))
@@ -926,8 +921,7 @@ get_wire_fee (struct AggregationContext *ac,
                                    timestamp,
                                    &wfi->start_date,
                                    &wfi->end_date,
-                                   &wfi->wire_fee,
-                                   &wfi->closing_fee,
+                                   &wfi->fees,
                                    &master_sig))
   {
     GNUNET_break (0);
@@ -944,8 +938,7 @@ get_wire_fee (struct AggregationContext *ac,
           method,
           wfi->start_date,
           wfi->end_date,
-          &wfi->wire_fee,
-          &wfi->closing_fee,
+          &wfi->fees,
           &TALER_ARL_master_pub,
           &master_sig))
     {
@@ -958,7 +951,7 @@ get_wire_fee (struct AggregationContext *ac,
   /* Established fee, keep in sorted list */
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Wire fee is %s starting at %s\n",
-              TALER_amount2s (&wfi->wire_fee),
+              TALER_amount2s (&wfi->fees.wire),
               GNUNET_TIME_timestamp2s (wfi->start_date));
   if ( (NULL == pos) ||
        (NULL == pos->prev) )
@@ -999,7 +992,7 @@ get_wire_fee (struct AggregationContext *ac,
                         TALER_JSON_pack_time_abs_human ("time",
                                                         
wfi->end_date.abs_time)));
   }
-  return &wfi->wire_fee;
+  return &wfi->fees.wire;
 }
 
 
diff --git a/src/auditor/taler-helper-auditor-reserves.c 
b/src/auditor/taler-helper-auditor-reserves.c
index f14a3999..f34f0c46 100644
--- a/src/auditor/taler-helper-auditor-reserves.c
+++ b/src/auditor/taler-helper-auditor-reserves.c
@@ -862,7 +862,7 @@ get_closing_fee (const char *receiver_account,
   struct TALER_MasterSignatureP master_sig;
   struct GNUNET_TIME_Timestamp start_date;
   struct GNUNET_TIME_Timestamp end_date;
-  struct TALER_Amount wire_fee;
+  struct TALER_WireFeeSet fees;
   char *method;
 
   method = TALER_payto_get_method (receiver_account);
@@ -875,8 +875,7 @@ get_closing_fee (const char *receiver_account,
                                    atime,
                                    &start_date,
                                    &end_date,
-                                   &wire_fee,
-                                   fee,
+                                   &fees,
                                    &master_sig))
   {
     char *diag;
@@ -892,6 +891,7 @@ get_closing_fee (const char *receiver_account,
     GNUNET_free (method);
     return GNUNET_SYSERR;
   }
+  *fee = fees.closing;
   GNUNET_free (method);
   return GNUNET_OK;
 }
diff --git a/src/benchmark/taler-aggregator-benchmark.c 
b/src/benchmark/taler-aggregator-benchmark.c
index 1437dafa..046be321 100644
--- a/src/benchmark/taler-aggregator-benchmark.c
+++ b/src/benchmark/taler-aggregator-benchmark.c
@@ -574,7 +574,7 @@ run (void *cls,
   }
 
   {
-    struct TALER_Amount wire_fee;
+    struct TALER_WireFeeSet fees;
     struct TALER_MasterSignatureP master_sig;
     unsigned int year;
     struct GNUNET_TIME_Timestamp ws;
@@ -585,7 +585,9 @@ run (void *cls,
     {
       ws = GNUNET_TIME_absolute_to_timestamp (GNUNET_TIME_year_to_time (y - 
1));
       we = GNUNET_TIME_absolute_to_timestamp (GNUNET_TIME_year_to_time (y));
-      make_amount (0, 5, &wire_fee);
+      make_amount (0, 5, &fees.wire);
+      make_amount (0, 5, &fees.wad);
+      make_amount (0, 5, &fees.closing);
       memset (&master_sig,
               0,
               sizeof (master_sig));
@@ -594,8 +596,7 @@ run (void *cls,
                                    "x-taler-bank",
                                    ws,
                                    we,
-                                   &wire_fee,
-                                   &wire_fee,
+                                   &fees,
                                    &master_sig))
       {
         GNUNET_break (0);
diff --git a/src/exchange-tools/taler-exchange-offline.c 
b/src/exchange-tools/taler-exchange-offline.c
index 0c1e84dd..7cbb20e8 100644
--- a/src/exchange-tools/taler-exchange-offline.c
+++ b/src/exchange-tools/taler-exchange-offline.c
@@ -1491,8 +1491,7 @@ upload_wire_fee (const char *exchange_url,
   struct WireFeeRequest *wfr;
   const char *err_name;
   unsigned int err_line;
-  struct TALER_Amount wire_fee;
-  struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
   struct GNUNET_TIME_Timestamp start_time;
   struct GNUNET_TIME_Timestamp end_time;
   struct GNUNET_JSON_Specification spec[] = {
@@ -1500,10 +1499,13 @@ upload_wire_fee (const char *exchange_url,
                              &wire_method),
     TALER_JSON_spec_amount ("wire_fee",
                             currency,
-                            &wire_fee),
+                            &fees.wire),
+    TALER_JSON_spec_amount ("wad_fee",
+                            currency,
+                            &fees.wad),
     TALER_JSON_spec_amount ("closing_fee",
                             currency,
-                            &closing_fee),
+                            &fees.closing),
     GNUNET_JSON_spec_timestamp ("start_time",
                                 &start_time),
     GNUNET_JSON_spec_timestamp ("end_time",
@@ -1539,8 +1541,7 @@ upload_wire_fee (const char *exchange_url,
                                              wire_method,
                                              start_time,
                                              end_time,
-                                             &wire_fee,
-                                             &closing_fee,
+                                             &fees,
                                              &master_sig,
                                              &wire_fee_cb,
                                              wfr);
@@ -2360,8 +2361,8 @@ do_del_wire (char *const *args)
  * Set wire fees for the given year.
  *
  * @param args the array of command-line arguments to process next;
- *        args[0] must be the year, args[1] the wire fee and args[2]
- *        the closing fee.
+ *        args[0] must be the year, args[1] the wire method, args[2] the wire 
fee and args[3]
+ *        the closing fee and args[4] the wad fee.
  */
 static void
 do_set_wire_fee (char *const *args)
@@ -2369,8 +2370,7 @@ do_set_wire_fee (char *const *args)
   struct TALER_MasterSignatureP master_sig;
   char dummy;
   unsigned int year;
-  struct TALER_Amount wire_fee;
-  struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
   struct GNUNET_TIME_Timestamp start_time;
   struct GNUNET_TIME_Timestamp end_time;
 
@@ -2386,6 +2386,7 @@ do_set_wire_fee (char *const *args)
        (NULL == args[1]) ||
        (NULL == args[2]) ||
        (NULL == args[3]) ||
+       (NULL == args[4]) ||
        ( (1 != sscanf (args[0],
                        "%u%c",
                        &year,
@@ -2394,13 +2395,16 @@ do_set_wire_fee (char *const *args)
                            args[0])) ) ||
        (GNUNET_OK !=
         TALER_string_to_amount (args[2],
-                                &wire_fee)) ||
+                                &fees.wire)) ||
        (GNUNET_OK !=
         TALER_string_to_amount (args[3],
-                                &closing_fee)) )
+                                &fees.closing)) ||
+       (GNUNET_OK !=
+        TALER_string_to_amount (args[4],
+                                &fees.wad)) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must use YEAR, METHOD, WIRE-FEE and CLOSING-FEE as 
arguments for this subcommand\n");
+                "You must use YEAR, METHOD, WIRE-FEE, CLOSING-FEE and WAD-FEE 
as arguments for this subcommand\n");
     test_shutdown ();
     global_ret = EXIT_INVALIDARGUMENT;
     return;
@@ -2419,8 +2423,7 @@ do_set_wire_fee (char *const *args)
   TALER_exchange_offline_wire_fee_sign (args[1],
                                         start_time,
                                         end_time,
-                                        &wire_fee,
-                                        &closing_fee,
+                                        &fees,
                                         &master_priv,
                                         &master_sig);
   output_operation (OP_SET_WIRE_FEE,
@@ -2432,12 +2435,14 @@ do_set_wire_fee (char *const *args)
                       GNUNET_JSON_pack_timestamp ("end_time",
                                                   end_time),
                       TALER_JSON_pack_amount ("wire_fee",
-                                              &wire_fee),
+                                              &fees.wire),
+                      TALER_JSON_pack_amount ("wad_fee",
+                                              &fees.wad),
                       TALER_JSON_pack_amount ("closing_fee",
-                                              &closing_fee),
+                                              &fees.closing),
                       GNUNET_JSON_pack_data_auto ("master_sig",
                                                   &master_sig)));
-  next (args + 4);
+  next (args + 5);
 }
 
 
diff --git a/src/exchange/taler-exchange-aggregator.c 
b/src/exchange/taler-exchange-aggregator.c
index 40653f9b..abab347f 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -43,7 +43,7 @@ struct AggregationUnit
   struct TALER_MerchantPublicKeyP merchant_pub;
 
   /**
-   * Total amount to be transferred, before subtraction of @e wire_fee and 
rounding down.
+   * Total amount to be transferred, before subtraction of @e fees.wire and 
rounding down.
    */
   struct TALER_Amount total_amount;
 
@@ -55,7 +55,7 @@ struct AggregationUnit
   /**
    * Wire fee we charge for @e wp at @e execution_time.
    */
-  struct TALER_Amount wire_fee;
+  struct TALER_WireFeeSet fees;
 
   /**
    * Wire transfer identifier we use.
@@ -454,7 +454,6 @@ deposit_cb (void *cls,
   /* make sure we have current fees */
   au->execution_time = GNUNET_TIME_timestamp_get ();
   {
-    struct TALER_Amount closing_fee;
     struct GNUNET_TIME_Timestamp start_date;
     struct GNUNET_TIME_Timestamp end_date;
     struct TALER_MasterSignatureP master_sig;
@@ -465,8 +464,7 @@ deposit_cb (void *cls,
                                   au->execution_time,
                                   &start_date,
                                   &end_date,
-                                  &au->wire_fee,
-                                  &closing_fee,
+                                  &au->fees,
                                   &master_sig);
     if (0 >= qs)
     {
@@ -482,7 +480,7 @@ deposit_cb (void *cls,
               "Aggregator starts aggregation for deposit %llu to %s with wire 
fee %s\n",
               (unsigned long long) row_id,
               TALER_B2S (&au->wtid),
-              TALER_amount2s (&au->wire_fee));
+              TALER_amount2s (&au->fees.wire));
   qs = db_plugin->insert_aggregation_tracking (db_plugin->cls,
                                                &au->wtid,
                                                row_id);
@@ -820,7 +818,7 @@ run_aggregation (void *cls)
   if ( (0 >=
         TALER_amount_subtract (&au_active.final_amount,
                                &au_active.total_amount,
-                               &au_active.wire_fee)) ||
+                               &au_active.fees.wire)) ||
        (GNUNET_SYSERR ==
         TALER_amount_round_down (&au_active.final_amount,
                                  &currency_round_unit)) ||
diff --git a/src/exchange/taler-exchange-closer.c 
b/src/exchange/taler-exchange-closer.c
index 3847e05b..92ba7bab 100644
--- a/src/exchange/taler-exchange-closer.c
+++ b/src/exchange/taler-exchange-closer.c
@@ -217,6 +217,7 @@ expired_reserve_cb (void *cls,
   struct TALER_WireTransferIdentifierRawP wtid;
   struct TALER_Amount amount_without_fee;
   struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
   enum TALER_AmountArithmeticResult ret;
   enum GNUNET_DB_QueryStatus qs;
   const struct TALER_EXCHANGEDB_AccountInfo *wa;
@@ -241,10 +242,9 @@ expired_reserve_cb (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
-  /* lookup `closing_fee` from time of actual reserve expiration
+  /* lookup `fees` from time of actual reserve expiration
      (we may be lagging behind!) */
   {
-    struct TALER_Amount wire_fee;
     struct GNUNET_TIME_Timestamp start_date;
     struct GNUNET_TIME_Timestamp end_date;
     struct TALER_MasterSignatureP master_sig;
@@ -255,8 +255,7 @@ expired_reserve_cb (void *cls,
                                   expiration_date,
                                   &start_date,
                                   &end_date,
-                                  &wire_fee,
-                                  &closing_fee,
+                                  &fees,
                                   &master_sig);
     if (0 >= qs)
     {
@@ -269,6 +268,7 @@ expired_reserve_cb (void *cls,
   }
 
   /* calculate transfer amount */
+  closing_fee = fees.closing;
   ret = TALER_amount_subtract (&amount_without_fee,
                                left,
                                &closing_fee);
diff --git a/src/exchange/taler-exchange-httpd_management_wire_fees.c 
b/src/exchange/taler-exchange-httpd_management_wire_fees.c
index c14500e8..1e96353c 100644
--- a/src/exchange/taler-exchange-httpd_management_wire_fees.c
+++ b/src/exchange/taler-exchange-httpd_management_wire_fees.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2020, 2021 Taler Systems SA
+  Copyright (C) 2020, 2021, 2022 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
@@ -58,14 +58,9 @@ struct AddFeeContext
   struct GNUNET_TIME_Timestamp end_time;
 
   /**
-   * Wire fee amount.
+   * Wire fee amounts.
    */
-  struct TALER_Amount wire_fee;
-
-  /**
-   * Closing fee amount.
-   */
-  struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
 
 };
 
@@ -91,16 +86,14 @@ add_fee (void *cls,
 {
   struct AddFeeContext *afc = cls;
   enum GNUNET_DB_QueryStatus qs;
-  struct TALER_Amount wire_fee;
-  struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
 
   qs = TEH_plugin->lookup_wire_fee_by_time (
     TEH_plugin->cls,
     afc->wire_method,
     afc->start_time,
     afc->end_time,
-    &wire_fee,
-    &closing_fee);
+    &fees);
   if (qs < 0)
   {
     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -115,13 +108,10 @@ add_fee (void *cls,
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs)
   {
     if ( (GNUNET_OK ==
-          TALER_amount_is_valid (&wire_fee)) &&
-         (0 ==
-          TALER_amount_cmp (&wire_fee,
-                            &afc->wire_fee)) &&
+          TALER_amount_is_valid (&fees.wire)) &&
          (0 ==
-          TALER_amount_cmp (&closing_fee,
-                            &afc->closing_fee)) )
+          TALER_wire_fee_set_cmp (&fees,
+                                  &afc->fees)) )
     {
       /* this will trigger the 'success' response */
       return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
@@ -142,8 +132,7 @@ add_fee (void *cls,
     afc->wire_method,
     afc->start_time,
     afc->end_time,
-    &afc->wire_fee,
-    &afc->closing_fee,
+    &afc->fees,
     &afc->master_sig);
   if (qs < 0)
   {
@@ -175,12 +164,15 @@ TEH_handler_management_post_wire_fees (
                                 &afc.start_time),
     GNUNET_JSON_spec_timestamp ("fee_end",
                                 &afc.end_time),
+    TALER_JSON_spec_amount ("wire_fee",
+                            TEH_currency,
+                            &afc.fees.wire),
     TALER_JSON_spec_amount ("closing_fee",
                             TEH_currency,
-                            &afc.closing_fee),
-    TALER_JSON_spec_amount ("wire_fee",
+                            &afc.fees.closing),
+    TALER_JSON_spec_amount ("wad_fee",
                             TEH_currency,
-                            &afc.wire_fee),
+                            &afc.fees.wad),
     GNUNET_JSON_spec_end ()
   };
 
@@ -201,8 +193,7 @@ TEH_handler_management_post_wire_fees (
         afc.wire_method,
         afc.start_time,
         afc.end_time,
-        &afc.wire_fee,
-        &afc.closing_fee,
+        &afc.fees,
         &TEH_master_public_key,
         &afc.master_sig))
   {
diff --git a/src/exchange/taler-exchange-httpd_transfers_get.c 
b/src/exchange/taler-exchange-httpd_transfers_get.c
index 5b914c41..0a4b1f54 100644
--- a/src/exchange/taler-exchange-httpd_transfers_get.c
+++ b/src/exchange/taler-exchange-httpd_transfers_get.c
@@ -211,9 +211,9 @@ struct WtidTransactionContext
   struct TALER_MerchantPublicKeyP merchant_pub;
 
   /**
-   * Wire fee applicable at @e exec_time.
+   * Wire fees applicable at @e exec_time.
    */
-  struct TALER_Amount wire_fee;
+  struct TALER_WireFeeSet fees;
 
   /**
    * Execution time of the wire transfer
@@ -401,7 +401,6 @@ get_transfer_deposits (void *cls,
   struct GNUNET_TIME_Timestamp wire_fee_start_date;
   struct GNUNET_TIME_Timestamp wire_fee_end_date;
   struct TALER_MasterSignatureP wire_fee_master_sig;
-  struct TALER_Amount closing_fee;
 
   /* resetting to NULL/0 in case transaction was repeated after
      serialization failure */
@@ -457,8 +456,7 @@ get_transfer_deposits (void *cls,
                                    ctx->exec_time,
                                    &wire_fee_start_date,
                                    &wire_fee_end_date,
-                                   &ctx->wire_fee,
-                                   &closing_fee,
+                                   &ctx->fees,
                                    &wire_fee_master_sig);
     GNUNET_free (wire_method);
   }
@@ -478,7 +476,7 @@ get_transfer_deposits (void *cls,
   if (0 >
       TALER_amount_subtract (&ctx->total,
                              &ctx->total,
-                             &ctx->wire_fee))
+                             &ctx->fees.wire))
   {
     GNUNET_break (0);
     *mhd_ret = TALER_MHD_reply_with_error (connection,
@@ -528,7 +526,7 @@ TEH_handler_transfers_get (struct TEH_RequestContext *rc,
                                     &ctx.total,
                                     &ctx.merchant_pub,
                                     ctx.payto_uri,
-                                    &ctx.wire_fee,
+                                    &ctx.fees.wire,
                                     ctx.exec_time,
                                     ctx.wdd_head);
   free_ctx (&ctx);
diff --git a/src/exchange/taler-exchange-httpd_wire.c 
b/src/exchange/taler-exchange-httpd_wire.c
index e80c775e..e1adde22 100644
--- a/src/exchange/taler-exchange-httpd_wire.c
+++ b/src/exchange/taler-exchange-httpd_wire.c
@@ -200,8 +200,7 @@ add_wire_account (void *cls,
  * Add information about a wire account to @a cls.
  *
  * @param cls a `json_t *` array to expand with wire account details
- * @param wire_fee the wire fee we charge
- * @param closing_fee the closing fee we charge
+ * @param fees the wire fees we charge
  * @param start_date from when are these fees valid (start date)
  * @param end_date until when are these fees valid (end date, exclusive)
  * @param master_sig master key signature affirming that this is the correct
@@ -209,8 +208,7 @@ add_wire_account (void *cls,
  */
 static void
 add_wire_fee (void *cls,
-              const struct TALER_Amount *wire_fee,
-              const struct TALER_Amount *closing_fee,
+              const struct TALER_WireFeeSet *fees,
               struct GNUNET_TIME_Timestamp start_date,
               struct GNUNET_TIME_Timestamp end_date,
               const struct TALER_MasterSignatureP *master_sig)
@@ -222,9 +220,11 @@ add_wire_fee (void *cls,
         a,
         GNUNET_JSON_PACK (
           TALER_JSON_pack_amount ("wire_fee",
-                                  wire_fee),
+                                  &fees->wire),
+          TALER_JSON_pack_amount ("wad_fee",
+                                  &fees->wad),
           TALER_JSON_pack_amount ("closing_fee",
-                                  closing_fee),
+                                  &fees->closing),
           GNUNET_JSON_pack_timestamp ("start_date",
                                       start_date),
           GNUNET_JSON_pack_timestamp ("end_date",
diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql
index 3331eada..a3996d12 100644
--- a/src/exchangedb/exchange-0001.sql
+++ b/src/exchangedb/exchange-0001.sql
@@ -835,6 +835,8 @@ CREATE TABLE IF NOT EXISTS wire_fee
   ,wire_fee_frac INT4 NOT NULL
   ,closing_fee_val INT8 NOT NULL
   ,closing_fee_frac INT4 NOT NULL
+  ,wad_fee_val INT8 NOT NULL
+  ,wad_fee_frac INT4 NOT NULL
   ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
   ,PRIMARY KEY (wire_method, start_date)
   );
@@ -848,6 +850,27 @@ CREATE INDEX IF NOT EXISTS wire_fee_by_end_date_index
   (end_date);
 
 
+CREATE TABLE IF NOT EXISTS global_fee
+  (global_fee_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
+  ,start_date INT8 NOT NULL
+  ,end_date INT8 NOT NULL
+  ,history_fee_val INT8 NOT NULL
+  ,history_fee_frac INT4 NOT NULL
+  ,kyc_fee_val INT8 NOT NULL
+  ,kyc_fee_frac INT4 NOT NULL
+  ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
+  ,PRIMARY KEY (start_date)
+  );
+COMMENT ON TABLE global_fee
+  IS 'list of the global fees of this exchange, by date';
+COMMENT ON COLUMN global_fee.global_fee_serial
+  IS 'needed for exchange-auditor replication logic';
+
+CREATE INDEX IF NOT EXISTS global_fee_by_end_date_index
+  ON global_fee
+  (end_date);
+
+
 CREATE TABLE IF NOT EXISTS recoup
   (recoup_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY -- UNIQUE
   ,known_coin_id INT8 NOT NULL -- REFERENCES known_coins (known_coin_id)
diff --git a/src/exchangedb/irbt_callbacks.c b/src/exchangedb/irbt_callbacks.c
index deab3cfc..ae486343 100644
--- a/src/exchangedb/irbt_callbacks.c
+++ b/src/exchangedb/irbt_callbacks.c
@@ -635,8 +635,9 @@ irbt_cb_table_wire_fee (struct PostgresClosure *pg,
     GNUNET_PQ_query_param_string (td->details.wire_fee.wire_method),
     GNUNET_PQ_query_param_timestamp (&td->details.wire_fee.start_date),
     GNUNET_PQ_query_param_timestamp (&td->details.wire_fee.end_date),
-    TALER_PQ_query_param_amount (&td->details.wire_fee.wire_fee),
-    TALER_PQ_query_param_amount (&td->details.wire_fee.closing_fee),
+    TALER_PQ_query_param_amount (&td->details.wire_fee.fees.wire),
+    TALER_PQ_query_param_amount (&td->details.wire_fee.fees.closing),
+    TALER_PQ_query_param_amount (&td->details.wire_fee.fees.wad),
     GNUNET_PQ_query_param_auto_from_type (&td->details.wire_fee.master_sig),
     GNUNET_PQ_query_param_end
   };
@@ -647,6 +648,32 @@ irbt_cb_table_wire_fee (struct PostgresClosure *pg,
 }
 
 
+/**
+ * Function called with wire_fee records to insert into table.
+ *
+ * @param pg plugin context
+ * @param td record to insert
+ */
+static enum GNUNET_DB_QueryStatus
+irbt_cb_table_global_fee (struct PostgresClosure *pg,
+                          const struct TALER_EXCHANGEDB_TableData *td)
+{
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&td->serial),
+    GNUNET_PQ_query_param_timestamp (&td->details.global_fee.start_date),
+    GNUNET_PQ_query_param_timestamp (&td->details.global_fee.end_date),
+    TALER_PQ_query_param_amount (&td->details.global_fee.fees.history),
+    TALER_PQ_query_param_amount (&td->details.global_fee.fees.kyc),
+    GNUNET_PQ_query_param_auto_from_type (&td->details.wire_fee.master_sig),
+    GNUNET_PQ_query_param_end
+  };
+
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "insert_into_table_global_fee",
+                                             params);
+}
+
+
 /**
  * Function called with recoup records to insert into table.
  *
diff --git a/src/exchangedb/lrbt_callbacks.c b/src/exchangedb/lrbt_callbacks.c
index 7f1d2fdb..233ecbc1 100644
--- a/src/exchangedb/lrbt_callbacks.c
+++ b/src/exchangedb/lrbt_callbacks.c
@@ -1173,9 +1173,11 @@ lrbt_cb_table_wire_fee (void *cls,
       GNUNET_PQ_result_spec_timestamp ("end_date",
                                        &td.details.wire_fee.end_date),
       TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
-                                   &td.details.wire_fee.wire_fee),
+                                   &td.details.wire_fee.fees.wire),
       TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
-                                   &td.details.wire_fee.closing_fee),
+                                   &td.details.wire_fee.fees.closing),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee",
+                                   &td.details.wire_fee.fees.wad),
       GNUNET_PQ_result_spec_auto_from_type ("master_sig",
                                             &td.details.wire_fee.master_sig),
       GNUNET_PQ_result_spec_end
@@ -1197,6 +1199,58 @@ lrbt_cb_table_wire_fee (void *cls,
 }
 
 
+/**
+ * Function called with wire_fee table entries.
+ *
+ * @param cls closure
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+lrbt_cb_table_global_fee (void *cls,
+                          PGresult *result,
+                          unsigned int num_results)
+{
+  struct LookupRecordsByTableContext *ctx = cls;
+  struct PostgresClosure *pg = ctx->pg;
+  struct TALER_EXCHANGEDB_TableData td = {
+    .table = TALER_EXCHANGEDB_RT_GLOBAL_FEE
+  };
+
+  for (unsigned int i = 0; i<num_results; i++)
+  {
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_uint64 ("serial",
+                                    &td.serial),
+      GNUNET_PQ_result_spec_timestamp ("start_date",
+                                       &td.details.global_fee.start_date),
+      GNUNET_PQ_result_spec_timestamp ("end_date",
+                                       &td.details.global_fee.end_date),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
+                                   &td.details.global_fee.fees.history),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("kyc_fee",
+                                   &td.details.global_fee.fees.kyc),
+      GNUNET_PQ_result_spec_auto_from_type ("master_sig",
+                                            &td.details.global_fee.master_sig),
+      GNUNET_PQ_result_spec_end
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      ctx->error = true;
+      return;
+    }
+    ctx->cb (ctx->cb_cls,
+             &td);
+    GNUNET_PQ_cleanup_result (rs);
+  }
+}
+
+
 /**
  * Function called with recoup table entries.
  *
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 9a3229f4..cdc383bf 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -1347,6 +1347,8 @@ prepare_statements (struct PostgresClosure *pg)
       ",wire_fee_frac"
       ",closing_fee_val"
       ",closing_fee_frac"
+      ",wad_fee_val"
+      ",wad_fee_frac"
       ",master_sig"
       " FROM wire_fee"
       " WHERE wire_method=$1"
@@ -1364,10 +1366,12 @@ prepare_statements (struct PostgresClosure *pg)
       ",wire_fee_frac"
       ",closing_fee_val"
       ",closing_fee_frac"
+      ",wad_fee_val"
+      ",wad_fee_frac"
       ",master_sig"
       ") VALUES "
-      "($1, $2, $3, $4, $5, $6, $7, $8);",
-      8),
+      "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);",
+      10),
     /* Used in #postgres_store_wire_transfer_out */
     GNUNET_PQ_make_prepare (
       "insert_wire_out",
@@ -1826,6 +1830,8 @@ prepare_statements (struct PostgresClosure *pg)
       ",wire_fee_frac"
       ",closing_fee_val"
       ",closing_fee_frac"
+      ",wad_fee_val"
+      ",wad_fee_frac"
       ",start_date"
       ",end_date"
       ",master_sig"
@@ -1936,6 +1942,8 @@ prepare_statements (struct PostgresClosure *pg)
       ",wire_fee_frac"
       ",closing_fee_val"
       ",closing_fee_frac"
+      ",wad_fee_val"
+      ",wad_fee_frac"
       " FROM wire_fee"
       " WHERE wire_method=$1"
       " AND end_date > $2"
@@ -2421,6 +2429,8 @@ prepare_statements (struct PostgresClosure *pg)
       ",wire_fee_frac"
       ",closing_fee_val"
       ",closing_fee_frac"
+      ",wad_fee_val"
+      ",wad_fee_frac"
       ",master_sig"
       " FROM wire_fee"
       " WHERE wire_fee_serial > $1"
@@ -2711,10 +2721,12 @@ prepare_statements (struct PostgresClosure *pg)
       ",wire_fee_frac"
       ",closing_fee_val"
       ",closing_fee_frac"
+      ",wad_fee_val"
+      ",wad_fee_frac"
       ",master_sig"
       ") VALUES "
-      "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
-      9),
+      "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);",
+      11),
     GNUNET_PQ_make_prepare (
       "insert_into_table_recoup",
       "INSERT INTO recoup"
@@ -7554,8 +7566,7 @@ postgres_insert_aggregation_tracking (
  * @param date for which date do we want the fee?
  * @param[out] start_date when does the fee go into effect
  * @param[out] end_date when does the fee end being valid
- * @param[out] wire_fee how high is the wire transfer fee
- * @param[out] closing_fee how high is the closing fee
+ * @param[out] fees how high are the wire fees
  * @param[out] master_sig signature over the above by the exchange master key
  * @return status of the transaction
  */
@@ -7565,8 +7576,7 @@ postgres_get_wire_fee (void *cls,
                        struct GNUNET_TIME_Timestamp date,
                        struct GNUNET_TIME_Timestamp *start_date,
                        struct GNUNET_TIME_Timestamp *end_date,
-                       struct TALER_Amount *wire_fee,
-                       struct TALER_Amount *closing_fee,
+                       struct TALER_WireFeeSet *fees,
                        struct TALER_MasterSignatureP *master_sig)
 {
   struct PostgresClosure *pg = cls;
@@ -7576,11 +7586,18 @@ postgres_get_wire_fee (void *cls,
     GNUNET_PQ_query_param_end
   };
   struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_timestamp ("start_date", start_date),
-    GNUNET_PQ_result_spec_timestamp ("end_date", end_date),
-    TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee", wire_fee),
-    TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee", closing_fee),
-    GNUNET_PQ_result_spec_auto_from_type ("master_sig", master_sig),
+    GNUNET_PQ_result_spec_timestamp ("start_date",
+                                     start_date),
+    GNUNET_PQ_result_spec_timestamp ("end_date",
+                                     end_date),
+    TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
+                                 &fees->wire),
+    TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee",
+                                 &fees->wad),
+    TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
+                                 &fees->closing),
+    GNUNET_PQ_result_spec_auto_from_type ("master_sig",
+                                          master_sig),
     GNUNET_PQ_result_spec_end
   };
 
@@ -7598,8 +7615,7 @@ postgres_get_wire_fee (void *cls,
  * @param type type of wire transfer this fee applies for
  * @param start_date when does the fee go into effect
  * @param end_date when does the fee end being valid
- * @param wire_fee how high is the wire transfer fee
- * @param closing_fee how high is the closing fee
+ * @param fees how high are the wire fees
  * @param master_sig signature over the above by the exchange master key
  * @return transaction status code
  */
@@ -7608,8 +7624,7 @@ postgres_insert_wire_fee (void *cls,
                           const char *type,
                           struct GNUNET_TIME_Timestamp start_date,
                           struct GNUNET_TIME_Timestamp end_date,
-                          const struct TALER_Amount *wire_fee,
-                          const struct TALER_Amount *closing_fee,
+                          const struct TALER_WireFeeSet *fees,
                           const struct TALER_MasterSignatureP *master_sig)
 {
   struct PostgresClosure *pg = cls;
@@ -7617,13 +7632,13 @@ postgres_insert_wire_fee (void *cls,
     GNUNET_PQ_query_param_string (type),
     GNUNET_PQ_query_param_timestamp (&start_date),
     GNUNET_PQ_query_param_timestamp (&end_date),
-    TALER_PQ_query_param_amount (wire_fee),
-    TALER_PQ_query_param_amount (closing_fee),
+    TALER_PQ_query_param_amount (&fees->wire),
+    TALER_PQ_query_param_amount (&fees->closing),
+    TALER_PQ_query_param_amount (&fees->wad),
     GNUNET_PQ_query_param_auto_from_type (master_sig),
     GNUNET_PQ_query_param_end
   };
-  struct TALER_Amount wf;
-  struct TALER_Amount cf;
+  struct TALER_WireFeeSet wx;
   struct TALER_MasterSignatureP sig;
   struct GNUNET_TIME_Timestamp sd;
   struct GNUNET_TIME_Timestamp ed;
@@ -7634,8 +7649,7 @@ postgres_insert_wire_fee (void *cls,
                               start_date,
                               &sd,
                               &ed,
-                              &wf,
-                              &cf,
+                              &wx,
                               &sig);
   if (qs < 0)
     return qs;
@@ -7647,14 +7661,9 @@ postgres_insert_wire_fee (void *cls,
       GNUNET_break (0);
       return GNUNET_DB_STATUS_HARD_ERROR;
     }
-    if (0 != TALER_amount_cmp (wire_fee,
-                               &wf))
-    {
-      GNUNET_break (0);
-      return GNUNET_DB_STATUS_HARD_ERROR;
-    }
-    if (0 != TALER_amount_cmp (closing_fee,
-                               &cf))
+    if (0 !=
+        TALER_wire_fee_set_cmp (fees,
+                                &wx))
     {
       GNUNET_break (0);
       return GNUNET_DB_STATUS_HARD_ERROR;
@@ -10230,15 +10239,16 @@ get_wire_fees_cb (void *cls,
   for (unsigned int i = 0; i < num_results; i++)
   {
     struct TALER_MasterSignatureP master_sig;
-    struct TALER_Amount wire_fee;
-    struct TALER_Amount closing_fee;
+    struct TALER_WireFeeSet fees;
     struct GNUNET_TIME_Timestamp start_date;
     struct GNUNET_TIME_Timestamp end_date;
     struct GNUNET_PQ_ResultSpec rs[] = {
       TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
-                                   &wire_fee),
+                                   &fees.wire),
       TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
-                                   &closing_fee),
+                                   &fees.closing),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee",
+                                   &fees.wad),
       GNUNET_PQ_result_spec_timestamp ("start_date",
                                        &start_date),
       GNUNET_PQ_result_spec_timestamp ("end_date",
@@ -10258,8 +10268,7 @@ get_wire_fees_cb (void *cls,
       return;
     }
     ctx->cb (ctx->cb_cls,
-             &wire_fee,
-             &closing_fee,
+             &fees,
              start_date,
              end_date,
              &master_sig);
@@ -10604,16 +10613,10 @@ struct WireFeeLookupContext
 {
 
   /**
-   * Set to the wire fee. Set to invalid if fees conflict over
+   * Set to the wire fees. Set to invalid if fees conflict over
    * the given time period.
    */
-  struct TALER_Amount *wire_fee;
-
-  /**
-   * Set to the closing fee. Set to invalid if fees conflict over
-   * the given time period.
-   */
-  struct TALER_Amount *closing_fee;
+  struct TALER_WireFeeSet *fees;
 
   /**
    * Plugin context.
@@ -10640,13 +10643,14 @@ wire_fee_by_time_helper (void *cls,
 
   for (unsigned int i = 0; i<num_results; i++)
   {
-    struct TALER_Amount wf;
-    struct TALER_Amount cf;
+    struct TALER_WireFeeSet fs;
     struct GNUNET_PQ_ResultSpec rs[] = {
       TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
-                                   &wf),
+                                   &fs.wire),
       TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
-                                   &cf),
+                                   &fs.closing),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee",
+                                   &fs.wad),
       GNUNET_PQ_result_spec_end
     };
 
@@ -10657,40 +10661,24 @@ wire_fee_by_time_helper (void *cls,
     {
       GNUNET_break (0);
       /* invalidate */
-      memset (wlc->wire_fee,
-              0,
-              sizeof (struct TALER_Amount));
-      memset (wlc->closing_fee,
+      memset (wlc->fees,
               0,
-              sizeof (struct TALER_Amount));
+              sizeof (struct TALER_WireFeeSet));
       return;
     }
     if (0 == i)
     {
-      *wlc->wire_fee = wf;
-      *wlc->closing_fee = cf;
+      *wlc->fees = fs;
       continue;
     }
-    if ( (GNUNET_YES !=
-          TALER_amount_cmp_currency (&wf,
-                                     wlc->wire_fee)) ||
-         (GNUNET_YES !=
-          TALER_amount_cmp_currency (&cf,
-                                     wlc->closing_fee)) ||
-         (0 !=
-          TALER_amount_cmp (&wf,
-                            wlc->wire_fee)) ||
-         (0 !=
-          TALER_amount_cmp (&cf,
-                            wlc->closing_fee)) )
+    if (0 !=
+        TALER_wire_fee_set_cmp (&fs,
+                                wlc->fees))
     {
       /* invalidate */
-      memset (wlc->wire_fee,
+      memset (wlc->fees,
               0,
-              sizeof (struct TALER_Amount));
-      memset (wlc->closing_fee,
-              0,
-              sizeof (struct TALER_Amount));
+              sizeof (struct TALER_WireFeeSet));
       return;
     }
   }
@@ -10700,7 +10688,7 @@ wire_fee_by_time_helper (void *cls,
 /**
  * Lookup information about known wire fees.  Finds all applicable
  * fees in the given range. If they are identical, returns the
- * respective @a wire_fee and @a closing_fee. If any of the fees
+ * respective @a fees. If any of the fees
  * differ between @a start_time and @a end_time, the transaction
  * succeeds BUT returns an invalid amount for both fees.
  *
@@ -10708,11 +10696,8 @@ wire_fee_by_time_helper (void *cls,
  * @param wire_method the wire method to lookup fees for
  * @param start_time starting time of fee
  * @param end_time end time of fee
- * @param[out] wire_fee wire fee for that time period; if
- *             different wire fee exists within this time
- *             period, an 'invalid' amount is returned.
- * @param[out] closing_fee wire fee for that time period; if
- *             different wire fee exists within this time
+ * @param[out] fees wire fees for that time period; if
+ *             different fees exists within this time
  *             period, an 'invalid' amount is returned.
  * @return transaction status code
  */
@@ -10722,8 +10707,7 @@ postgres_lookup_wire_fee_by_time (
   const char *wire_method,
   struct GNUNET_TIME_Timestamp start_time,
   struct GNUNET_TIME_Timestamp end_time,
-  struct TALER_Amount *wire_fee,
-  struct TALER_Amount *closing_fee)
+  struct TALER_WireFeeSet *fees)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
@@ -10733,9 +10717,8 @@ postgres_lookup_wire_fee_by_time (
     GNUNET_PQ_query_param_end
   };
   struct WireFeeLookupContext wlc = {
-    .wire_fee = wire_fee,
-    .closing_fee = closing_fee,
-    .pg = pg,
+    .fees = fees,
+    .pg = pg
   };
 
   return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
@@ -10834,6 +10817,9 @@ postgres_lookup_serial_by_table (void *cls,
   case TALER_EXCHANGEDB_RT_WIRE_FEE:
     statement = "select_serial_by_table_wire_fee";
     break;
+  case TALER_EXCHANGEDB_RT_GLOBAL_FEE:
+    statement = "select_serial_by_table_global_fee";
+    break;
   case TALER_EXCHANGEDB_RT_RECOUP:
     statement = "select_serial_by_table_recoup";
     break;
@@ -11003,6 +10989,10 @@ postgres_lookup_records_by_table (void *cls,
     statement = "select_above_serial_by_table_wire_fee";
     rh = &lrbt_cb_table_wire_fee;
     break;
+  case TALER_EXCHANGEDB_RT_GLOBAL_FEE:
+    statement = "select_above_serial_by_table_global_fee";
+    rh = &lrbt_cb_table_global_fee;
+    break;
   case TALER_EXCHANGEDB_RT_RECOUP:
     statement = "select_above_serial_by_table_recoup";
     rh = &lrbt_cb_table_recoup;
@@ -11138,6 +11128,9 @@ postgres_insert_records_by_table (void *cls,
   case TALER_EXCHANGEDB_RT_WIRE_FEE:
     rh = &irbt_cb_table_wire_fee;
     break;
+  case TALER_EXCHANGEDB_RT_GLOBAL_FEE:
+    rh = &irbt_cb_table_global_fee;
+    break;
   case TALER_EXCHANGEDB_RT_RECOUP:
     rh = &irbt_cb_table_recoup;
     break;
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 10390b7f..012cac64 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -915,23 +915,24 @@ test_wire_fees (void)
 {
   struct GNUNET_TIME_Timestamp start_date;
   struct GNUNET_TIME_Timestamp end_date;
-  struct TALER_Amount wire_fee;
-  struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
   struct TALER_MasterSignatureP master_sig;
   struct GNUNET_TIME_Timestamp sd;
   struct GNUNET_TIME_Timestamp ed;
-  struct TALER_Amount fee;
-  struct TALER_Amount fee2;
+  struct TALER_WireFeeSet fees2;
   struct TALER_MasterSignatureP ms;
 
   start_date = GNUNET_TIME_timestamp_get ();
   end_date = GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES);
   GNUNET_assert (GNUNET_OK ==
                  TALER_string_to_amount (CURRENCY ":1.424242",
-                                         &wire_fee));
+                                         &fees.wire));
   GNUNET_assert (GNUNET_OK ==
                  TALER_string_to_amount (CURRENCY ":2.424242",
-                                         &closing_fee));
+                                         &fees.closing));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount (CURRENCY ":3.424242",
+                                         &fees.wad));
   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
                               &master_sig,
                               sizeof (master_sig));
@@ -940,8 +941,7 @@ test_wire_fees (void)
                                "wire-method",
                                start_date,
                                end_date,
-                               &wire_fee,
-                               &closing_fee,
+                               &fees,
                                &master_sig))
   {
     GNUNET_break (0);
@@ -952,8 +952,7 @@ test_wire_fees (void)
                                "wire-method",
                                start_date,
                                end_date,
-                               &wire_fee,
-                               &closing_fee,
+                               &fees,
                                &master_sig))
   {
     GNUNET_break (0);
@@ -967,8 +966,7 @@ test_wire_fees (void)
                             end_date,
                             &sd,
                             &ed,
-                            &fee,
-                            &fee2,
+                            &fees2,
                             &ms))
   {
     GNUNET_break (0);
@@ -980,8 +978,7 @@ test_wire_fees (void)
                             start_date,
                             &sd,
                             &ed,
-                            &fee,
-                            &fee2,
+                            &fees2,
                             &ms))
   {
     GNUNET_break (0);
@@ -993,10 +990,8 @@ test_wire_fees (void)
        (GNUNET_TIME_timestamp_cmp (ed,
                                    !=,
                                    end_date)) ||
-       (0 != TALER_amount_cmp (&fee,
-                               &wire_fee)) ||
-       (0 != TALER_amount_cmp (&fee2,
-                               &closing_fee)) ||
+       (0 != TALER_wire_fee_set_cmp (&fees,
+                                     &fees2)) ||
        (0 != GNUNET_memcmp (&ms,
                             &master_sig)) )
   {
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 1beada69..40f407b6 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -830,6 +830,18 @@ TALER_global_fee_set_ntoh (struct TALER_GlobalFeeSet *fees,
                            const struct TALER_GlobalFeeSetNBOP *nbo);
 
 
+/**
+ * Compare global fee sets.
+ *
+ * @param f1 first set to compare
+ * @param f2 second set to compare
+ * @return 0 if sets are equal
+ */
+int
+TALER_global_fee_set_cmp (const struct TALER_GlobalFeeSet *f1,
+                          const struct TALER_GlobalFeeSet *f2);
+
+
 /**
  * Convert wire fee set from host to network byte order.
  *
@@ -852,6 +864,18 @@ TALER_wire_fee_set_ntoh (struct TALER_WireFeeSet *fees,
                          const struct TALER_WireFeeSetNBOP *nbo);
 
 
+/**
+ * Compare wire fee sets.
+ *
+ * @param f1 first set to compare
+ * @param f2 second set to compare
+ * @return 0 if sets are equal
+ */
+int
+TALER_wire_fee_set_cmp (const struct TALER_WireFeeSet *f1,
+                        const struct TALER_WireFeeSet *f2);
+
+
 /**
  * Hash @a rsa.
  *
@@ -3231,8 +3255,7 @@ TALER_auditor_denom_validity_verify (
  * @param payment_method the payment method
  * @param start_time when do the fees start to apply
  * @param end_time when do the fees start to apply
- * @param wire_fee the wire fee
- * @param closing_fee the closing fee
+ * @param fees the wire fees
  * @param master_priv private key to sign with
  * @param[out] master_sig where to write the signature
  */
@@ -3241,8 +3264,7 @@ TALER_exchange_offline_wire_fee_sign (
   const char *payment_method,
   struct GNUNET_TIME_Timestamp start_time,
   struct GNUNET_TIME_Timestamp end_time,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_Amount *closing_fee,
+  const struct TALER_WireFeeSet *fees,
   const struct TALER_MasterPrivateKeyP *master_priv,
   struct TALER_MasterSignatureP *master_sig);
 
@@ -3253,8 +3275,7 @@ TALER_exchange_offline_wire_fee_sign (
  * @param payment_method the payment method
  * @param start_time when do the fees start to apply
  * @param end_time when do the fees start to apply
- * @param wire_fee the wire fee
- * @param closing_fee the closing fee
+ * @param fees the wire fees
  * @param master_pub public key to verify against
  * @param master_sig the signature the signature
  * @return #GNUNET_OK if the signature is valid
@@ -3264,8 +3285,7 @@ TALER_exchange_offline_wire_fee_verify (
   const char *payment_method,
   struct GNUNET_TIME_Timestamp start_time,
   struct GNUNET_TIME_Timestamp end_time,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_Amount *closing_fee,
+  const struct TALER_WireFeeSet *fees,
   const struct TALER_MasterPublicKeyP *master_pub,
   const struct TALER_MasterSignatureP *master_sig);
 
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 88be1ee3..00115e12 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -642,13 +642,7 @@ struct TALER_EXCHANGE_WireAggregateFees
   /**
    * Fee to be paid whenever the exchange wires funds to the merchant.
    */
-  struct TALER_Amount wire_fee;
-
-  /**
-   * Fee to be paid when the exchange closes a reserve and wires funds
-   * back to a customer.
-   */
-  struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
 
   /**
    * Time when this fee goes into effect (inclusive)
@@ -3501,8 +3495,7 @@ struct TALER_EXCHANGE_ManagementSetWireFeeHandle;
  * @param wire_method for which wire method are fees provided
  * @param validity_start start date for the provided wire fees
  * @param validity_end end date for the provided wire fees
- * @param wire_fee the wire fee for this time period
- * @param closing_fee the closing fee for this time period
+ * @param fees the wire fees for this time period
  * @param master_sig signature affirming the wire fees;
  *        of purpose #TALER_SIGNATURE_MASTER_WIRE_FEES
  * @param cb function to call with the exchange's result
@@ -3516,8 +3509,7 @@ TALER_EXCHANGE_management_set_wire_fees (
   const char *wire_method,
   struct GNUNET_TIME_Timestamp validity_start,
   struct GNUNET_TIME_Timestamp validity_end,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_Amount *closing_fee,
+  const struct TALER_WireFeeSet *fees,
   const struct TALER_MasterSignatureP *master_sig,
   TALER_EXCHANGE_ManagementWireEnableCallback cb,
   void *cb_cls);
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 878cfe2f..d890cd0b 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -168,6 +168,7 @@ enum TALER_EXCHANGEDB_ReplicatedTable
   TALER_EXCHANGEDB_RT_WIRE_OUT,
   TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING,
   TALER_EXCHANGEDB_RT_WIRE_FEE,
+  TALER_EXCHANGEDB_RT_GLOBAL_FEE,
   TALER_EXCHANGEDB_RT_RECOUP,
   TALER_EXCHANGEDB_RT_RECOUP_REFRESH,
   TALER_EXCHANGEDB_RT_EXTENSIONS,
@@ -384,11 +385,18 @@ struct TALER_EXCHANGEDB_TableData
       char *wire_method;
       struct GNUNET_TIME_Timestamp start_date;
       struct GNUNET_TIME_Timestamp end_date;
-      struct TALER_Amount wire_fee;
-      struct TALER_Amount closing_fee;
+      struct TALER_WireFeeSet fees;
       struct TALER_MasterSignatureP master_sig;
     } wire_fee;
 
+    struct
+    {
+      struct GNUNET_TIME_Timestamp start_date;
+      struct GNUNET_TIME_Timestamp end_date;
+      struct TALER_GlobalFeeSet fees;
+      struct TALER_MasterSignatureP master_sig;
+    } global_fee;
+
     struct
     {
       uint64_t known_coin_id;
@@ -1899,8 +1907,7 @@ typedef void
  * Provide information about wire fees.
  *
  * @param cls closure
- * @param wire_fee the wire fee we charge
- * @param closing_fee the closing fee we charge
+ * @param fees the wire fees we charge
  * @param start_date from when are these fees valid (start date)
  * @param end_date until when are these fees valid (end date, exclusive)
  * @param master_sig master key signature affirming that this is the correct
@@ -1909,8 +1916,26 @@ typedef void
 typedef void
 (*TALER_EXCHANGEDB_WireFeeCallback)(
   void *cls,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_Amount *closing_fee,
+  const struct TALER_WireFeeSet *fees,
+  struct GNUNET_TIME_Timestamp start_date,
+  struct GNUNET_TIME_Timestamp end_date,
+  const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Provide information about global fees.
+ *
+ * @param cls closure
+ * @param fees the global fees we charge
+ * @param start_date from when are these fees valid (start date)
+ * @param end_date until when are these fees valid (end date, exclusive)
+ * @param master_sig master key signature affirming that this is the correct
+ *                   fee (of purpose #TALER_SIGNATURE_MASTER_GLOBAL_FEES)
+ */
+typedef void
+(*TALER_EXCHANGEDB_GlobalFeeCallback)(
+  void *cls,
+  const struct TALER_GlobalFeeSet *fees,
   struct GNUNET_TIME_Timestamp start_date,
   struct GNUNET_TIME_Timestamp end_date,
   const struct TALER_MasterSignatureP *master_sig);
@@ -3256,8 +3281,7 @@ struct TALER_EXCHANGEDB_Plugin
    * @param wire_method which wire method is the fee about?
    * @param start_date when does the fee go into effect
    * @param end_date when does the fee end being valid
-   * @param wire_fee how high is the wire transfer fee
-   * @param closing_fee how high is the closing fee
+   * @param fees how high is are the wire fees
    * @param master_sig signature over the above by the exchange master key
    * @return transaction status code
    */
@@ -3266,11 +3290,28 @@ struct TALER_EXCHANGEDB_Plugin
                      const char *wire_method,
                      struct GNUNET_TIME_Timestamp start_date,
                      struct GNUNET_TIME_Timestamp end_date,
-                     const struct TALER_Amount *wire_fee,
-                     const struct TALER_Amount *closing_fee,
+                     const struct TALER_WireFeeSet *fees,
                      const struct TALER_MasterSignatureP *master_sig);
 
 
+  /**
+   * Insert global fee set into database.
+   *
+   * @param cls closure
+   * @param start_date when does the fee go into effect
+   * @param end_date when does the fee end being valid
+   * @param fees how high is are the global fees
+   * @param master_sig signature over the above by the exchange master key
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_global_fee)(void *cls,
+                       struct GNUNET_TIME_Timestamp start_date,
+                       struct GNUNET_TIME_Timestamp end_date,
+                       const struct TALER_GlobalFeeSet *fees,
+                       const struct TALER_MasterSignatureP *master_sig);
+
+
   /**
    * Obtain wire fee from database.
    *
@@ -3279,8 +3320,7 @@ struct TALER_EXCHANGEDB_Plugin
    * @param date for which date do we want the fee?
    * @param[out] start_date when does the fee go into effect
    * @param[out] end_date when does the fee end being valid
-   * @param[out] wire_fee how high is the wire transfer fee
-   * @param[out] closing_fee how high is the closing fee
+   * @param[out] fees how high are the wire fees
    * @param[out] master_sig signature over the above by the exchange master key
    * @return query status of the transaction
    */
@@ -3290,11 +3330,31 @@ struct TALER_EXCHANGEDB_Plugin
                   struct GNUNET_TIME_Timestamp date,
                   struct GNUNET_TIME_Timestamp *start_date,
                   struct GNUNET_TIME_Timestamp *end_date,
-                  struct TALER_Amount *wire_fee,
-                  struct TALER_Amount *closing_fee,
+                  struct TALER_WireFeeSet *fees,
                   struct TALER_MasterSignatureP *master_sig);
 
 
+  /**
+   * Obtain global fees from database.
+   *
+   * @param cls closure
+   * @param date for which date do we want the fee?
+   * @param[out] start_date when does the fee go into effect
+   * @param[out] end_date when does the fee end being valid
+   * @param[out] fees how high are the global fees
+   * @param[out] master_sig signature over the above by the exchange master key
+   * @return query status of the transaction
+   */
+  enum GNUNET_DB_QueryStatus
+  (*get_global_fee)(void *cls,
+                    const char *type,
+                    struct GNUNET_TIME_Timestamp date,
+                    struct GNUNET_TIME_Timestamp *start_date,
+                    struct GNUNET_TIME_Timestamp *end_date,
+                    struct TALER_GlobalFeeSet *fees,
+                    struct TALER_MasterSignatureP *master_sig);
+
+
   /**
    * Obtain information about expired reserves and their
    * remaining balances.
@@ -3874,6 +3934,20 @@ struct TALER_EXCHANGEDB_Plugin
                    void *cb_cls);
 
 
+  /**
+   * Obtain information about the global fee structure of the exchange.
+   *
+   * @param cls closure
+   * @param cb function to call on each account
+   * @param cb_cls closure for @a cb
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*get_global_fees)(void *cls,
+                     TALER_EXCHANGEDB_GlobalFeeCallback cb,
+                     void *cb_cls);
+
+
   /**
    * Store information about a revoked online signing key.
    *
@@ -4012,10 +4086,7 @@ struct TALER_EXCHANGEDB_Plugin
    * @param wire_method the wire method to lookup fees for
    * @param start_time starting time of fee
    * @param end_time end time of fee
-   * @param[out] wire_fee wire fee for that time period; if
-   *             different wire fee exists within this time
-   *             period, an 'invalid' amount is returned.
-   * @param[out] closing_fee wire fee for that time period; if
+   * @param[out] fees set to wire fees for that time period; if
    *             different wire fee exists within this time
    *             period, an 'invalid' amount is returned.
    * @return transaction status code
@@ -4026,8 +4097,7 @@ struct TALER_EXCHANGEDB_Plugin
     const char *wire_method,
     struct GNUNET_TIME_Timestamp start_time,
     struct GNUNET_TIME_Timestamp end_time,
-    struct TALER_Amount *wire_fee,
-    struct TALER_Amount *closing_fee);
+    struct TALER_WireFeeSet *fees);
 
 
   /**
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index ed985938..77a23421 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -1244,14 +1244,10 @@ struct TALER_MasterWireFeePS
   struct GNUNET_TIME_TimestampNBO end_date;
 
   /**
-   * Fee charged to the merchant per wire transfer.
-   */
-  struct TALER_AmountNBO wire_fee;
-
-  /**
-   * Closing fee charged when we wire back funds of a reserve.
+   * Fees charged for wire transfers using the
+   * given wire method.
    */
-  struct TALER_AmountNBO closing_fee;
+  struct TALER_WireFeeSetNBOP fees;
 
 };
 
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index 081a9347..5d5cff49 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -2107,6 +2107,7 @@ TALER_TESTING_cmd_set_wire_fee (const char *label,
                                 const char *wire_method,
                                 const char *wire_fee,
                                 const char *closing_fee,
+                                const char *wad_fee,
                                 unsigned int expected_http_status,
                                 bool bad_sig);
 
@@ -2180,13 +2181,15 @@ TALER_TESTING_cmd_exec_offline_sign_keys (const char 
*label,
  * @param config_filename configuration filename.
  * @param wire_fee the wire fee to affirm (for the current year)
  * @param closing_fee the closing fee to affirm (for the current year)
+ * @param wad_fee the wad fee to affirm
  * @return the command
  */
 struct TALER_TESTING_Command
 TALER_TESTING_cmd_exec_offline_sign_fees (const char *label,
                                           const char *config_filename,
                                           const char *wire_fee,
-                                          const char *closing_fee);
+                                          const char *closing_fee,
+                                          const char *wad_fee);
 
 
 /**
diff --git a/src/lib/exchange_api_management_set_wire_fee.c 
b/src/lib/exchange_api_management_set_wire_fee.c
index 807c6723..cd32a483 100644
--- a/src/lib/exchange_api_management_set_wire_fee.c
+++ b/src/lib/exchange_api_management_set_wire_fee.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2020-2021 Taler Systems SA
+  Copyright (C) 2020-2022 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
@@ -129,8 +129,7 @@ TALER_EXCHANGE_management_set_wire_fees (
   const char *wire_method,
   struct GNUNET_TIME_Timestamp validity_start,
   struct GNUNET_TIME_Timestamp validity_end,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_Amount *closing_fee,
+  const struct TALER_WireFeeSet *fees,
   const struct TALER_MasterSignatureP *master_sig,
   TALER_EXCHANGE_ManagementWireEnableCallback cb,
   void *cb_cls)
@@ -163,9 +162,11 @@ TALER_EXCHANGE_management_set_wire_fees (
     GNUNET_JSON_pack_timestamp ("fee_end",
                                 validity_end),
     TALER_JSON_pack_amount ("closing_fee",
-                            closing_fee),
+                            &fees->closing),
+    TALER_JSON_pack_amount ("wad_fee",
+                            &fees->wad),
     TALER_JSON_pack_amount ("wire_fee",
-                            wire_fee));
+                            &fees->wire));
   eh = TALER_EXCHANGE_curl_easy_get_ (swfh->url);
   GNUNET_assert (NULL != eh);
   if (GNUNET_OK !=
diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c
index 453b576b..0390623f 100644
--- a/src/lib/exchange_api_wire.c
+++ b/src/lib/exchange_api_wire.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2020 Taler Systems SA
+  Copyright (C) 2014-2022 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
@@ -144,9 +144,11 @@ parse_fees (json_t *fees)
         GNUNET_JSON_spec_fixed_auto ("sig",
                                      &wa->master_sig),
         TALER_JSON_spec_amount_any ("wire_fee",
-                                    &wa->wire_fee),
+                                    &wa->fees.wire),
+        TALER_JSON_spec_amount_any ("wad_fee",
+                                    &wa->fees.wad),
         TALER_JSON_spec_amount_any ("closing_fee",
-                                    &wa->closing_fee),
+                                    &wa->fees.closing),
         GNUNET_JSON_spec_timestamp ("start_date",
                                     &wa->start_date),
         GNUNET_JSON_spec_timestamp ("end_date",
@@ -230,8 +232,10 @@ handle_wire_finished (void *cls,
       struct FeeMap *fm;
       const struct TALER_EXCHANGE_Keys *key_state;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_json ("accounts", &accounts),
-        GNUNET_JSON_spec_json ("fees", &fees),
+        GNUNET_JSON_spec_json ("accounts",
+                               &accounts),
+        GNUNET_JSON_spec_json ("fees",
+                               &fees),
         GNUNET_JSON_spec_end ()
       };
 
@@ -277,8 +281,10 @@ handle_wire_finished (void *cls,
           struct TALER_EXCHANGE_WireAccount *wa = &was[i];
           json_t *account;
           struct GNUNET_JSON_Specification spec_account[] = {
-            GNUNET_JSON_spec_string ("payto_uri", &wa->payto_uri),
-            GNUNET_JSON_spec_fixed_auto ("master_sig", &wa->master_sig),
+            GNUNET_JSON_spec_string ("payto_uri",
+                                     &wa->payto_uri),
+            GNUNET_JSON_spec_fixed_auto ("master_sig",
+                                         &wa->master_sig),
             GNUNET_JSON_spec_end ()
           };
           char *method;
diff --git a/src/testing/test_auditor_api.c b/src/testing/test_auditor_api.c
index 9ab78664..e103697e 100644
--- a/src/testing/test_auditor_api.c
+++ b/src/testing/test_auditor_api.c
@@ -651,6 +651,7 @@ run (void *cls,
     TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
                                               config_file,
                                               "EUR:0.01",
+                                              "EUR:0.01",
                                               "EUR:0.01"),
     TALER_TESTING_cmd_auditor_add ("add-auditor-OK",
                                    MHD_HTTP_NO_CONTENT,
diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c
index 46419193..f3a9fdd5 100644
--- a/src/testing/test_exchange_api.c
+++ b/src/testing/test_exchange_api.c
@@ -1169,6 +1169,7 @@ run (void *cls,
       TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
                                                 config_file,
                                                 "EUR:0.01",
+                                                "EUR:0.01",
                                                 "EUR:0.01"),
       TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
                                                   1),
diff --git a/src/testing/test_exchange_api_keys_cherry_picking.c 
b/src/testing/test_exchange_api_keys_cherry_picking.c
index 63114c60..25bdad06 100644
--- a/src/testing/test_exchange_api_keys_cherry_picking.c
+++ b/src/testing/test_exchange_api_keys_cherry_picking.c
@@ -69,6 +69,7 @@ run (void *cls,
     TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
                                               config_file,
                                               "EUR:0.01",
+                                              "EUR:0.01",
                                               "EUR:0.01"),
     TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
                                               config_file),
diff --git a/src/testing/test_exchange_management_api.c 
b/src/testing/test_exchange_management_api.c
index 71251a57..9fe5cf59 100644
--- a/src/testing/test_exchange_management_api.c
+++ b/src/testing/test_exchange_management_api.c
@@ -85,30 +85,35 @@ run (void *cls,
                                     "foo-method",
                                     "EUR:1",
                                     "EUR:5",
+                                    "EUR:3",
                                     MHD_HTTP_NO_CONTENT,
                                     false),
     TALER_TESTING_cmd_set_wire_fee ("set-fee-conflicting",
                                     "foo-method",
                                     "EUR:1",
                                     "EUR:1",
+                                    "EUR:3",
                                     MHD_HTTP_CONFLICT,
                                     false),
     TALER_TESTING_cmd_set_wire_fee ("set-fee-bad-signature",
                                     "bar-method",
                                     "EUR:1",
                                     "EUR:1",
+                                    "EUR:3",
                                     MHD_HTTP_FORBIDDEN,
                                     true),
     TALER_TESTING_cmd_set_wire_fee ("set-fee-other-method",
                                     "bar-method",
                                     "EUR:1",
                                     "EUR:1",
+                                    "EUR:3",
                                     MHD_HTTP_NO_CONTENT,
                                     false),
     TALER_TESTING_cmd_set_wire_fee ("set-fee-idempotent",
                                     "bar-method",
                                     "EUR:1",
                                     "EUR:1",
+                                    "EUR:3",
                                     MHD_HTTP_NO_CONTENT,
                                     false),
     TALER_TESTING_cmd_wire_add ("add-wire-account",
diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c
index 3a828646..669101d8 100644
--- a/src/testing/test_kyc_api.c
+++ b/src/testing/test_kyc_api.c
@@ -210,6 +210,7 @@ run (void *cls,
     TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
                                               CONFIG_FILE,
                                               "EUR:0.01",
+                                              "EUR:0.01",
                                               "EUR:0.01"),
     TALER_TESTING_cmd_auditor_add ("add-auditor-OK",
                                    MHD_HTTP_NO_CONTENT,
diff --git a/src/testing/test_taler_exchange_aggregator.c 
b/src/testing/test_taler_exchange_aggregator.c
index bf28375b..ce0c7340 100644
--- a/src/testing/test_taler_exchange_aggregator.c
+++ b/src/testing/test_taler_exchange_aggregator.c
@@ -99,6 +99,7 @@ run (void *cls,
     TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
                                               config_filename,
                                               "EUR:0.01",
+                                              "EUR:0.01",
                                               "EUR:0.01"),
     // check no aggregation happens on a empty database
     CMD_EXEC_AGGREGATOR ("run-aggregator-on-empty-db",
diff --git a/src/testing/test_taler_exchange_wirewatch.c 
b/src/testing/test_taler_exchange_wirewatch.c
index 30c2cf27..ad5151e2 100644
--- a/src/testing/test_taler_exchange_wirewatch.c
+++ b/src/testing/test_taler_exchange_wirewatch.c
@@ -85,6 +85,7 @@ run (void *cls,
     TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
                                               config_filename,
                                               "EUR:0.01",
+                                              "EUR:0.01",
                                               "EUR:0.01"),
     TALER_TESTING_cmd_auditor_add ("add-auditor-OK",
                                    MHD_HTTP_NO_CONTENT,
diff --git a/src/testing/testing_api_cmd_offline_sign_fees.c 
b/src/testing/testing_api_cmd_offline_sign_fees.c
index 95f52a00..8cf9fffe 100644
--- a/src/testing/testing_api_cmd_offline_sign_fees.c
+++ b/src/testing/testing_api_cmd_offline_sign_fees.c
@@ -51,6 +51,11 @@ struct OfflineSignState
    */
   const char *wire_fee_s;
 
+  /**
+   * The wad fee to sign.
+   */
+  const char *wad_fee_s;
+
   /**
    * The closing fee to sign.
    */
@@ -86,6 +91,7 @@ offlinesign_run (void *cls,
         "x-taler-bank",
         ks->wire_fee_s,
         ks->closing_fee_s,
+        ks->wad_fee_s,
         "upload",
         NULL);
   if (NULL == ks->offlinesign_proc)
@@ -157,13 +163,15 @@ struct TALER_TESTING_Command
 TALER_TESTING_cmd_exec_offline_sign_fees (const char *label,
                                           const char *config_filename,
                                           const char *wire_fee,
-                                          const char *closing_fee)
+                                          const char *closing_fee,
+                                          const char *wad_fee)
 {
   struct OfflineSignState *ks;
 
   ks = GNUNET_new (struct OfflineSignState);
   ks->config_filename = config_filename;
   ks->wire_fee_s = wire_fee;
+  ks->wad_fee_s = wad_fee;
   ks->closing_fee_s = closing_fee;
   {
     struct TALER_TESTING_Command cmd = {
diff --git a/src/testing/testing_api_cmd_set_wire_fee.c 
b/src/testing/testing_api_cmd_set_wire_fee.c
index b458d10c..8eb99387 100644
--- a/src/testing/testing_api_cmd_set_wire_fee.c
+++ b/src/testing/testing_api_cmd_set_wire_fee.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2020 Taler Systems SA
+  Copyright (C) 2020, 2022 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
@@ -60,6 +60,11 @@ struct WireFeeState
    */
   const char *closing_fee;
 
+  /**
+   * Wad fee amount to use.
+   */
+  const char *wad_fee;
+
   /**
    * Expected HTTP response code.
    */
@@ -121,8 +126,7 @@ wire_add_run (void *cls,
   struct GNUNET_TIME_Absolute now;
   struct GNUNET_TIME_Timestamp start_time;
   struct GNUNET_TIME_Timestamp end_time;
-  struct TALER_Amount wire_fee;
-  struct TALER_Amount closing_fee;
+  struct TALER_WireFeeSet fees;
 
   (void) cmd;
   ds->is = is;
@@ -135,10 +139,13 @@ wire_add_run (void *cls,
                               GNUNET_TIME_UNIT_HOURS));
   if ( (GNUNET_OK !=
         TALER_string_to_amount (ds->closing_fee,
-                                &closing_fee)) ||
+                                &fees.closing)) ||
+       (GNUNET_OK !=
+        TALER_string_to_amount (ds->wad_fee,
+                                &fees.wad)) ||
        (GNUNET_OK !=
         TALER_string_to_amount (ds->wire_fee,
-                                &wire_fee)) )
+                                &fees.wire)) )
   {
     GNUNET_break (0);
     TALER_TESTING_interpreter_fail (is);
@@ -156,8 +163,7 @@ wire_add_run (void *cls,
     TALER_exchange_offline_wire_fee_sign (ds->wire_method,
                                           start_time,
                                           end_time,
-                                          &wire_fee,
-                                          &closing_fee,
+                                          &fees,
                                           &is->master_priv,
                                           &master_sig);
   }
@@ -167,8 +173,7 @@ wire_add_run (void *cls,
     ds->wire_method,
     start_time,
     end_time,
-    &wire_fee,
-    &closing_fee,
+    &fees,
     &master_sig,
     &wire_add_cb,
     ds);
@@ -212,6 +217,7 @@ TALER_TESTING_cmd_set_wire_fee (const char *label,
                                 const char *wire_method,
                                 const char *wire_fee,
                                 const char *closing_fee,
+                                const char *wad_fee,
                                 unsigned int expected_http_status,
                                 bool bad_sig)
 {
@@ -223,6 +229,7 @@ TALER_TESTING_cmd_set_wire_fee (const char *label,
   ds->wire_method = wire_method;
   ds->wire_fee = wire_fee;
   ds->closing_fee = closing_fee;
+  ds->wad_fee = wad_fee;
   {
     struct TALER_TESTING_Command cmd = {
       .cls = ds,
diff --git a/src/testing/testing_api_cmd_wire.c 
b/src/testing/testing_api_cmd_wire.c
index 66d018c7..4b0a177b 100644
--- a/src/testing/testing_api_cmd_wire.c
+++ b/src/testing/testing_api_cmd_wire.c
@@ -119,7 +119,7 @@ wire_cb (void *cls,
                NULL != waf;
                waf = waf->next)
           {
-            if (0 != TALER_amount_cmp (&waf->wire_fee,
+            if (0 != TALER_amount_cmp (&waf->fees.wire,
                                        &expected_fee))
             {
               GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c
index 5aef4ac3..2a358bbf 100644
--- a/src/util/offline_signatures.c
+++ b/src/util/offline_signatures.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2020, 2021 Taler Systems SA
+  Copyright (C) 2020-2022 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
@@ -415,8 +415,7 @@ TALER_exchange_offline_wire_fee_sign (
   const char *payment_method,
   struct GNUNET_TIME_Timestamp start_time,
   struct GNUNET_TIME_Timestamp end_time,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_Amount *closing_fee,
+  const struct TALER_WireFeeSet *fees,
   const struct TALER_MasterPrivateKeyP *master_priv,
   struct TALER_MasterSignatureP *master_sig)
 {
@@ -430,10 +429,8 @@ TALER_exchange_offline_wire_fee_sign (
   GNUNET_CRYPTO_hash (payment_method,
                       strlen (payment_method) + 1,
                       &kv.h_wire_method);
-  TALER_amount_hton (&kv.wire_fee,
-                     wire_fee);
-  TALER_amount_hton (&kv.closing_fee,
-                     closing_fee);
+  TALER_wire_fee_set_hton (&kv.fees,
+                           fees);
   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
                             &kv,
                             &master_sig->eddsa_signature);
@@ -445,8 +442,7 @@ TALER_exchange_offline_wire_fee_verify (
   const char *payment_method,
   struct GNUNET_TIME_Timestamp start_time,
   struct GNUNET_TIME_Timestamp end_time,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_Amount *closing_fee,
+  const struct TALER_WireFeeSet *fees,
   const struct TALER_MasterPublicKeyP *master_pub,
   const struct TALER_MasterSignatureP *master_sig)
 {
@@ -460,10 +456,8 @@ TALER_exchange_offline_wire_fee_verify (
   GNUNET_CRYPTO_hash (payment_method,
                       strlen (payment_method) + 1,
                       &wf.h_wire_method);
-  TALER_amount_hton (&wf.wire_fee,
-                     wire_fee);
-  TALER_amount_hton (&wf.closing_fee,
-                     closing_fee);
+  TALER_wire_fee_set_hton (&wf.fees,
+                           fees);
   return
     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
                                 &wf,
diff --git a/src/util/util.c b/src/util/util.c
index 6dfd6557..33b0a77c 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -124,6 +124,46 @@ TALER_wire_fee_set_ntoh (struct TALER_WireFeeSet *fees,
 }
 
 
+int
+TALER_global_fee_set_cmp (const struct TALER_GlobalFeeSet *f1,
+                          const struct TALER_GlobalFeeSet *f2)
+{
+  int ret;
+
+  ret = TALER_amount_cmp (&f1->history,
+                          &f2->history);
+  if (0 != ret)
+    return ret;
+  ret = TALER_amount_cmp (&f1->kyc,
+                          &f2->kyc);
+  if (0 != ret)
+    return ret;
+  return 0;
+}
+
+
+int
+TALER_wire_fee_set_cmp (const struct TALER_WireFeeSet *f1,
+                        const struct TALER_WireFeeSet *f2)
+{
+  int ret;
+
+  ret = TALER_amount_cmp (&f1->wire,
+                          &f2->wire);
+  if (0 != ret)
+    return ret;
+  ret = TALER_amount_cmp (&f1->closing,
+                          &f2->closing);
+  if (0 != ret)
+    return ret;
+  ret = TALER_amount_cmp (&f1->wad,
+                          &f2->wad);
+  if (0 != ret)
+    return ret;
+  return 0;
+}
+
+
 enum GNUNET_GenericReturnValue
 TALER_denom_fee_check_currency (
   const char *currency,

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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