gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: amount rounding a la Christian


From: gnunet
Subject: [taler-exchange] branch master updated: amount rounding a la Christian
Date: Fri, 17 Jan 2020 18:59:21 +0100

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

dold pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 7378b5a0 amount rounding a la Christian
7378b5a0 is described below

commit 7378b5a081a0d839c3bd63f6ddd359bca50be695
Author: Florian Dold <address@hidden>
AuthorDate: Fri Jan 17 18:59:15 2020 +0100

    amount rounding a la Christian
---
 src/auditor/taler-auditor.c              | 31 ++++++++++++++++---------------
 src/exchange/taler-exchange-aggregator.c | 32 +++++++++++++++++---------------
 src/include/taler_amount_lib.h           |  7 +++++--
 src/util/amount.c                        | 16 ++++++++++------
 src/util/test_amount.c                   | 15 ++++++++++++---
 5 files changed, 60 insertions(+), 41 deletions(-)

diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index 8b2c2c37..f3bb0e2b 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -88,7 +88,7 @@ static char *currency;
 /**
  * How many fractional digits does the currency use?
  */
-static uint8_t currency_rounding_fractional_digits;
+static struct TALER_Amount currency_round_unit;
 
 /**
  * Our configuration.
@@ -2894,7 +2894,7 @@ check_wire_out_cb
 
   /* Round down to amount supported by wire method */
   GNUNET_break (TALER_amount_round_down (&final_amount,
-                                         currency_rounding_fractional_digits));
+                                         &currency_round_unit));
 
   /* Calculate the exchange's gain as the fees plus rounding differences! */
   if (GNUNET_OK !=
@@ -5205,28 +5205,29 @@ run (void *cls,
     return;
   }
   {
-    unsigned long long num;
+    char *rounding_str;
     if (GNUNET_OK !=
-        GNUNET_CONFIGURATION_get_value_number (cfg,
+        GNUNET_CONFIGURATION_get_value_string (cfg,
                                                "taler",
-                                               
"CURRENCY_ROUNDING_FRACTIONAL_DIGITS",
-                                               &num))
+                                               "CURRENCY_ROUND_UNIT",
+                                               &rounding_str))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "No [taler]/CURRENCY_ROUNDING_FRACTIONAL_DIGITS specified, 
defaulting to 2 digits.\n");
-      currency_rounding_fractional_digits = 2;
+                  "No [taler]/CURRENCY_ROUND_UNIT specified, defaulting to 
'0.01'.\n");
+      TALER_amount_get_zero (currency, &currency_round_unit);
+      currency_round_unit.fraction = TALER_AMOUNT_FRAC_BASE / 100;
     }
-    else if (num > TALER_AMOUNT_FRAC_LEN)
+    else if (GNUNET_OK !=
+             TALER_string_to_amount (rounding_str,
+                                     &currency_round_unit))
     {
-      global_ret = 1;
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Value of CURRENCY_ROUNDING_FRACTIONAL_DIGITS too big.\n");
+                  "Invalid amount `%s' specified in `TALER' under 
`CURRENCY_ROUND_UNIT'\n",
+                  rounding_str);
+      GNUNET_free (rounding_str);
+      global_ret = 1;
       return;
     }
-    else
-    {
-      currency_rounding_fractional_digits = (uint8_t) num;
-    }
   }
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_time (cfg,
diff --git a/src/exchange/taler-exchange-aggregator.c 
b/src/exchange/taler-exchange-aggregator.c
index 9032cd5e..338e979e 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -224,7 +224,7 @@ static char *exchange_currency_string;
 /**
  * How many fractional digits does the currency use?
  */
-static uint8_t currency_rounding_fractional_digits;
+static struct TALER_Amount currency_round_unit;
 
 /**
  * What is the base URL of this exchange?
@@ -615,29 +615,31 @@ exchange_serve_process_config ()
   }
 
   {
-    unsigned long long num;
+    char *rounding_str;
     if (GNUNET_OK !=
-        GNUNET_CONFIGURATION_get_value_number (cfg,
+        GNUNET_CONFIGURATION_get_value_string (cfg,
                                                "taler",
-                                               
"CURRENCY_ROUNDING_FRACTIONAL_DIGITS",
-                                               &num))
+                                               "CURRENCY_ROUND_UNIT",
+                                               &rounding_str))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "No [taler]/CURRENCY_ROUNDING_FRACTIONAL_DIGITS specified, 
defaulting to 2 digits.\n");
-      currency_rounding_fractional_digits = 2;
+                  "No [taler]/CURRENCY_ROUND_UNIT specified, defaulting to 
'0.01'.\n");
+      TALER_amount_get_zero (exchange_currency_string, &currency_round_unit);
+      currency_round_unit.fraction = TALER_AMOUNT_FRAC_BASE / 100;
     }
-    else if (num > TALER_AMOUNT_FRAC_LEN)
+    else if (GNUNET_OK !=
+             TALER_string_to_amount (rounding_str,
+                                     &currency_round_unit))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Value of CURRENCY_ROUNDING_FRACTIONAL_DIGITS too big.\n");
+                  "Invalid amount `%s' specified in `TALER' under 
`CURRENCY_ROUND_UNIT'\n",
+                  rounding_str);
+      GNUNET_free (rounding_str);
       return GNUNET_SYSERR;
     }
-    else
-    {
-      currency_rounding_fractional_digits = (uint8_t) num;
-    }
   }
 
+
   if (NULL ==
       (db_plugin = TALER_EXCHANGEDB_plugin_load (cfg)))
   {
@@ -1120,7 +1122,7 @@ expired_reserve_cb (void *cls,
   /* round down to enable transfer */
   if (GNUNET_SYSERR ==
       TALER_amount_round_down (&amount_without_fee,
-                               currency_rounding_fractional_digits))
+                               &currency_round_unit))
   {
     GNUNET_break (0);
     global_ret = GNUNET_SYSERR;
@@ -1456,7 +1458,7 @@ run_aggregation (void *cls)
                                &au->wire_fee)) ||
        (GNUNET_SYSERR ==
         TALER_amount_round_down (&au->final_amount,
-                                 currency_rounding_fractional_digits)) ||
+                                 &currency_round_unit)) ||
        ( (0 == au->final_amount.value) &&
          (0 == au->final_amount.fraction) ) )
   {
diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h
index 7118e2ec..df1cf06f 100644
--- a/src/include/taler_amount_lib.h
+++ b/src/include/taler_amount_lib.h
@@ -311,15 +311,18 @@ TALER_amount2s (const struct TALER_Amount *amount);
 
 /**
  * Round the amount to something that can be transferred on the wire.
+ * The rounding mode is specified via the smallest transferable unit,
+ * which must only have a fractional part.
  *
  * @param[in,out] amount amount to round down
- * @param max_fractional_digits number of fractional digits to round down to
+ * @param[in] round_unit unit that should be rounded down to,
+ *            the value part of this amount must be zero
  * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary,
  *         #GNUNET_SYSERR if the amount or currency was invalid
  */
 int
 TALER_amount_round_down (struct TALER_Amount *amount,
-                         uint8_t max_fractional_digits);
+                         const struct TALER_Amount *round_unit);
 
 
 #if 0                           /* keep Emacsens' auto-indent happy */
diff --git a/src/util/amount.c b/src/util/amount.c
index 48f5d989..1f00b1d6 100644
--- a/src/util/amount.c
+++ b/src/util/amount.c
@@ -674,23 +674,27 @@ TALER_amount_divide (struct TALER_Amount *result,
 
 /**
  * Round the amount to something that can be transferred on the wire.
+ * The rounding mode is specified via the smallest transferable unit,
+ * which must only have a fractional part.
  *
  * @param[in,out] amount amount to round down
- * @param max_fractional_digits number of fractional digits to round down to
+ * @param[in] round_unit unit that should be rounded down to,
+ *            the value part of this amount must be zero
  * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary,
  *         #GNUNET_SYSERR if the amount or currency was invalid
  */
 int
 TALER_amount_round_down (struct TALER_Amount *amount,
-                         uint8_t max_fractional_digits)
+                         const struct TALER_Amount *round_unit)
 {
   uint32_t delta;
-  uint32_t divisor = 1;
 
-  for (unsigned int i = 0; i < max_fractional_digits; i++)
-    divisor *= 10;
+  GNUNET_break (0 == round_unit->value);
 
-  delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / divisor);
+  if (0 == round_unit->fraction)
+    return GNUNET_OK;
+
+  delta = amount->fraction % round_unit->fraction;
   if (0 == delta)
     return GNUNET_NO;
   amount->fraction -= delta;
diff --git a/src/util/test_amount.c b/src/util/test_amount.c
index 4eeccd7e..3bf8e6fb 100644
--- a/src/util/test_amount.c
+++ b/src/util/test_amount.c
@@ -31,6 +31,7 @@ main (int argc,
   struct TALER_Amount a1;
   struct TALER_Amount a2;
   struct TALER_Amount a3;
+  struct TALER_Amount r;
   char *c;
 
   GNUNET_log_setup ("test-amout",
@@ -236,6 +237,10 @@ main (int argc,
 
   /* test rounding #1 */
 
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:0.01",
+                                         &r));
+
   GNUNET_assert (GNUNET_OK ==
                  TALER_string_to_amount ("EUR:4.001",
                                          &a1));
@@ -243,19 +248,23 @@ main (int argc,
                  TALER_string_to_amount ("EUR:4",
                                          &a2));
 
-  GNUNET_assert (GNUNET_OK == TALER_amount_round_down (&a1, 2));
-  GNUNET_assert (GNUNET_NO == TALER_amount_round_down (&a1, 2));
+  GNUNET_assert (GNUNET_OK == TALER_amount_round_down (&a1, &r));
+  GNUNET_assert (GNUNET_NO == TALER_amount_round_down (&a1, &r));
   GNUNET_assert (0 == TALER_amount_cmp (&a1, &a2));
 
   /* test rounding #2 */
 
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:0.001",
+                                         &r));
+
   GNUNET_assert (GNUNET_OK ==
                  TALER_string_to_amount ("EUR:4.001",
                                          &a1));
   GNUNET_assert (GNUNET_OK ==
                  TALER_string_to_amount ("EUR:4.001",
                                          &a2));
-  GNUNET_assert (GNUNET_NO == TALER_amount_round_down (&a1, 3));
+  GNUNET_assert (GNUNET_NO == TALER_amount_round_down (&a1, &r));
   GNUNET_assert (0 == TALER_amount_cmp (&a1, &a2));
 
   return 0;

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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