gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: round amounts based on config, d


From: gnunet
Subject: [taler-exchange] branch master updated: round amounts based on config, do unit test for rounding
Date: Wed, 15 Jan 2020 15:17:29 +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 da5b3ba8 round amounts based on config, do unit test for rounding
da5b3ba8 is described below

commit da5b3ba8aeb9d47e4f99cd22847c9b539ff8ee2b
Author: Florian Dold <address@hidden>
AuthorDate: Wed Jan 15 15:17:02 2020 +0100

    round amounts based on config, do unit test for rounding
---
 src/auditor/taler-auditor.c              | 32 ++++++++++++++++++++++++++++-
 src/exchange/taler-exchange-aggregator.c | 35 ++++++++++++++++++++++++++++++--
 src/include/taler_amount_lib.h           |  7 ++++---
 src/util/amount.c                        | 13 ++++++++----
 src/util/test_amount.c                   | 23 +++++++++++++++++++++
 5 files changed, 100 insertions(+), 10 deletions(-)

diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index d4fb84d1..d2bc3404 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -85,6 +85,11 @@ static struct TALER_EXCHANGEDB_Plugin *edb;
  */
 static char *currency;
 
+/**
+ * How many fractional digits does the currency use?
+ */
+static uint8_t currency_rounding_fractional_digits;
+
 /**
  * Our configuration.
  */
@@ -2895,7 +2900,8 @@ check_wire_out_cb
   }
 
   /* Round down to amount supported by wire method */
-  GNUNET_break (TALER_amount_round (&final_amount));
+  GNUNET_break (TALER_amount_round_down (&final_amount,
+                                         currency_rounding_fractional_digits));
 
   /* Calculate the exchange's gain as the fees plus rounding differences! */
   if (GNUNET_OK !=
@@ -5204,6 +5210,30 @@ run (void *cls,
     global_ret = 1;
     return;
   }
+  {
+    unsigned long long num;
+    if (GNUNET_OK !=
+        GNUNET_CONFIGURATION_get_value_number (cfg,
+                                               "taler",
+                                               
"CURRENCY_ROUNDING_FRACTIONAL_DIGITS",
+                                               &num))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "No [taler]/CURRENCY_ROUNDING_FRACTIONAL_DIGITS specified, 
defaulting to 2 digits.\n");
+      currency_rounding_fractional_digits = 2;
+    }
+    else if (num > TALER_AMOUNT_FRAC_LEN)
+    {
+      global_ret = 1;
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Value of CURRENCY_ROUNDING_FRACTIONAL_DIGITS too big.\n");
+      return;
+    }
+    else
+    {
+      currency_rounding_fractional_digits = (uint8_t) num;
+    }
+  }
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_time (cfg,
                                            "exchangedb",
diff --git a/src/exchange/taler-exchange-aggregator.c 
b/src/exchange/taler-exchange-aggregator.c
index fe3ef39c..f1abbe2b 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -226,6 +226,11 @@ static struct CloseTransferContext *ctc;
  */
 static char *exchange_currency_string;
 
+/**
+ * How many fractional digits does the currency use?
+ */
+static uint8_t currency_rounding_fractional_digits;
+
 /**
  * What is the base URL of this exchange?
  */
@@ -614,6 +619,30 @@ exchange_serve_process_config ()
     return GNUNET_SYSERR;
   }
 
+  {
+    unsigned long long num;
+    if (GNUNET_OK !=
+        GNUNET_CONFIGURATION_get_value_number (cfg,
+                                               "taler",
+                                               
"CURRENCY_ROUNDING_FRACTIONAL_DIGITS",
+                                               &num))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "No [taler]/CURRENCY_ROUNDING_FRACTIONAL_DIGITS specified, 
defaulting to 2 digits.\n");
+      currency_rounding_fractional_digits = 2;
+    }
+    else if (num > TALER_AMOUNT_FRAC_LEN)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Value of CURRENCY_ROUNDING_FRACTIONAL_DIGITS too big.\n");
+      return GNUNET_SYSERR;
+    }
+    else
+    {
+      currency_rounding_fractional_digits = (uint8_t) num;
+    }
+  }
+
   if (NULL ==
       (db_plugin = TALER_EXCHANGEDB_plugin_load (cfg)))
   {
@@ -1116,7 +1145,8 @@ expired_reserve_cb (void *cls,
   }
   /* round down to enable transfer */
   if (GNUNET_SYSERR ==
-      TALER_amount_round (&amount_without_fee))
+      TALER_amount_round_down (&amount_without_fee,
+                               currency_rounding_fractional_digits))
   {
     GNUNET_break (0);
     global_ret = GNUNET_SYSERR;
@@ -1447,7 +1477,8 @@ run_aggregation (void *cls)
                                &au->total_amount,
                                &au->wire_fee)) ||
        (GNUNET_SYSERR ==
-        TALER_amount_round (&au->final_amount)) ||
+        TALER_amount_round_down (&au->final_amount,
+                                 currency_rounding_fractional_digits)) ||
        ( (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 37f42bd9..7118e2ec 100644
--- a/src/include/taler_amount_lib.h
+++ b/src/include/taler_amount_lib.h
@@ -310,15 +310,16 @@ TALER_amount2s (const struct TALER_Amount *amount);
 
 
 /**
- * Round the amount to something that can be
- * transferred on the wire.
+ * Round the amount to something that can be transferred on the wire.
  *
  * @param[in,out] amount amount to round down
+ * @param max_fractional_digits number of fractional digits to round down to
  * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary,
  *         #GNUNET_SYSERR if the amount or currency was invalid
  */
 int
-TALER_amount_round (struct TALER_Amount *amount);
+TALER_amount_round_down (struct TALER_Amount *amount,
+                         uint8_t max_fractional_digits);
 
 
 #if 0                           /* keep Emacsens' auto-indent happy */
diff --git a/src/util/amount.c b/src/util/amount.c
index edb9dc06..48f5d989 100644
--- a/src/util/amount.c
+++ b/src/util/amount.c
@@ -673,19 +673,24 @@ TALER_amount_divide (struct TALER_Amount *result,
 
 
 /**
- * Round the amount to something that can be
- * transferred on the wire.
+ * Round the amount to something that can be transferred on the wire.
  *
  * @param[in,out] amount amount to round down
+ * @param max_fractional_digits number of fractional digits to round down to
  * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary,
  *         #GNUNET_SYSERR if the amount or currency was invalid
  */
 int
-TALER_amount_round (struct TALER_Amount *amount)
+TALER_amount_round_down (struct TALER_Amount *amount,
+                         uint8_t max_fractional_digits)
 {
   uint32_t delta;
+  uint32_t divisor = 1;
 
-  delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / 100);
+  for (unsigned int i = 0; i < max_fractional_digits; i++)
+    divisor *= 10;
+
+  delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / divisor);
   if (0 == delta)
     return GNUNET_NO;
   amount->fraction -= delta;
diff --git a/src/util/test_amount.c b/src/util/test_amount.c
index d9110eaf..4eeccd7e 100644
--- a/src/util/test_amount.c
+++ b/src/util/test_amount.c
@@ -234,6 +234,29 @@ main (int argc,
   GNUNET_assert (0 == a2.value);
   GNUNET_assert (1 == a2.fraction);
 
+  /* test rounding #1 */
+
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:4.001",
+                                         &a1));
+  GNUNET_assert (GNUNET_OK ==
+                 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 (0 == TALER_amount_cmp (&a1, &a2));
+
+  /* test rounding #2 */
+
+  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 (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]