gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-exchange] branch master updated: getting revocation/


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: getting revocation/payback test with refreshed coins to pass
Date: Wed, 24 Jul 2019 11:57:06 +0200

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 9e3f4bdd getting revocation/payback test with refreshed coins to pass
9e3f4bdd is described below

commit 9e3f4bdd791f87df25cfd2b818c7ef385b78b35d
Author: Christian Grothoff <address@hidden>
AuthorDate: Wed Jul 24 11:57:03 2019 +0200

    getting revocation/payback test with refreshed coins to pass
---
 src/exchange/taler-exchange-httpd_payback.c        |   1 +
 src/exchange/taler-exchange-httpd_refresh_reveal.c |  10 +-
 .../taler-exchange-httpd_reserve_withdraw.c        |   6 +-
 src/exchangedb/plugin_exchangedb_postgres.c        |  14 +-
 src/include/taler_exchange_service.h               |   1 +
 src/include/taler_testing_lib.h                    |  15 +-
 src/lib/Makefile.am                                |   4 +-
 src/lib/exchange_api_refresh.c                     |  32 +++--
 src/lib/test_auditor_api.c                         |   4 +-
 src/lib/test_exchange_api.c                        |  12 +-
 src/lib/test_exchange_api_revocation.c             |  46 +++---
 src/lib/test_exchange_api_twisted.c                |   4 +-
 src/lib/testing_api_cmd_refresh.c                  | 157 +++++++++++++--------
 13 files changed, 186 insertions(+), 120 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_payback.c 
b/src/exchange/taler-exchange-httpd_payback.c
index 8cfc1aec..50c0ffdb 100644
--- a/src/exchange/taler-exchange-httpd_payback.c
+++ b/src/exchange/taler-exchange-httpd_payback.c
@@ -305,6 +305,7 @@ payback_transaction (void *cls,
     }
     return qs;
   }
+
   GNUNET_assert (GNUNET_OK ==
                  TALER_amount_get_zero (pc->value.currency,
                                         &spent));
diff --git a/src/exchange/taler-exchange-httpd_refresh_reveal.c 
b/src/exchange/taler-exchange-httpd_refresh_reveal.c
index d34c85a9..47287b15 100644
--- a/src/exchange/taler-exchange-httpd_refresh_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refresh_reveal.c
@@ -556,7 +556,7 @@ handle_refresh_reveal_json (struct MHD_Connection 
*connection,
     GNUNET_break_op (0);
     return TEH_RESPONSE_reply_arg_invalid (connection,
                                            
TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE,
-                                           "new_denoms");
+                                           "new_denoms_h");
 
   }
   if (json_array_size (new_denoms_h_json) !=
@@ -640,7 +640,7 @@ handle_refresh_reveal_json (struct MHD_Connection 
*connection,
         TEH_KS_release (key_state);
         return TEH_RESPONSE_reply_arg_invalid (connection,
                                                
TALER_EC_REFRESH_REVEAL_FRESH_DENOMINATION_KEY_NOT_FOUND,
-                                               "new_denoms");
+                                               "new_denoms_h");
       }
       GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key);
     }
@@ -674,7 +674,7 @@ handle_refresh_reveal_json (struct MHD_Connection 
*connection,
     /* lookup old_coin_pub in database */
     {
       enum GNUNET_DB_QueryStatus qs;
-    
+
       if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           (qs = TEH_plugin->get_melt (TEH_plugin->cls,
                                       NULL,
@@ -725,7 +725,7 @@ handle_refresh_reveal_json (struct MHD_Connection 
*connection,
         ldp.purpose.size = htonl (sizeof (ldp));
         ldp.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK);
         ldp.h_denom_pub = dki_h[i];
-        ldp.old_coin_pub = refresh_melt.session.coin.coin_pub; 
+        ldp.old_coin_pub = refresh_melt.session.coin.coin_pub;
         ldp.transfer_pub = rctx->gamma_tp;
         GNUNET_CRYPTO_hash (rcds[i].coin_ev,
                             rcds[i].coin_ev_size,
@@ -744,7 +744,7 @@ handle_refresh_reveal_json (struct MHD_Connection 
*connection,
         }
       }
     }
-    
+
     rctx->num_fresh_coins = num_fresh_coins;
     rctx->rcds = rcds;
     rctx->dkis = dkis;
diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c 
b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
index 32d53980..65bca25e 100644
--- a/src/exchange/taler-exchange-httpd_reserve_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
@@ -286,7 +286,7 @@ withdraw_transaction (void *cls,
       return GNUNET_DB_STATUS_HARD_ERROR;
     }
     *mhd_ret = reply_reserve_withdraw_insufficient_funds (connection,
-                                                         rh);
+                                                          rh);
     TEH_plugin->free_reserve_history (TEH_plugin->cls,
                                       rh);
     return GNUNET_DB_STATUS_HARD_ERROR;
@@ -319,8 +319,8 @@ withdraw_transaction (void *cls,
   wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope;
   wc->collectable.reserve_sig = wc->signature;
   qs = TEH_plugin->insert_withdraw_info (TEH_plugin->cls,
-                                        session,
-                                        &wc->collectable);
+                                         session,
+                                         &wc->collectable);
   if (0 > qs)
   {
     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index c95ed261..72e77fa6 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -2593,8 +2593,8 @@ postgres_insert_withdraw_info (void *cls,
   now = GNUNET_TIME_absolute_get ();
   (void) GNUNET_TIME_round_abs (&now);
   qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                          "insert_withdraw_info",
-                                          params);
+                                           "insert_withdraw_info",
+                                           params);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
   {
     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -2627,6 +2627,9 @@ postgres_insert_withdraw_info (void *cls,
                 TALER_B2S (&collectable->reserve_pub));
     return GNUNET_DB_STATUS_SOFT_ERROR;
   }
+  /* FIXME: idle_reserve_expiration_time is not a good value here,
+     we should base this on the LEGAL expiration time of coins
+     as we need reserve data for payback! */
   expiry = GNUNET_TIME_absolute_add (now,
                                      pg->idle_reserve_expiration_time);
   reserve.expiry = GNUNET_TIME_absolute_max (expiry,
@@ -7721,11 +7724,12 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
       return NULL;
     }
   }
+
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_time (cfg,
-                                          "exchangedb",
-                                          "IDLE_RESERVE_EXPIRATION_TIME",
-                                          &pg->idle_reserve_expiration_time))
+                                           "exchangedb",
+                                           "IDLE_RESERVE_EXPIRATION_TIME",
+                                           &pg->idle_reserve_expiration_time))
   {
     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                                "exchangedb",
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 7bcfee9e..4ced8ad9 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -511,6 +511,7 @@ TALER_EXCHANGE_get_signing_key_details (const struct 
TALER_EXCHANGE_Keys *keys,
 const char *
 TALER_EXCHANGE_get_base_url (const struct TALER_EXCHANGE_Handle *exchange);
 
+
 /**
  * Obtain the denomination key details from the exchange.
  *
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index c08cfdc5..41cc8b50 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -131,6 +131,7 @@ TALER_TESTING_cert_cb
    const struct TALER_EXCHANGE_Keys *keys,
    enum TALER_EXCHANGE_VersionCompatibility compat);
 
+
 /**
  * Wait for the exchange to have started. Waits for at
  * most 10s, after that returns 77 to indicate an error.
@@ -1108,19 +1109,18 @@ TALER_TESTING_cmd_deposit_with_retry
  * Create a "refresh melt" command.
  *
  * @param label command label.
- * @param amount amount to be melted.
  * @param coin_reference reference to a command
  *        that will provide a coin to refresh.
  * @param expected_response_code expected HTTP code.
- *
+ * @param ... NULL-terminated list of amounts to be melted
  * @return the command.
  */
 struct TALER_TESTING_Command
 TALER_TESTING_cmd_refresh_melt
   (const char *label,
-   const char *amount,
    const char *coin_reference,
-   unsigned int expected_response_code);
+   unsigned int expected_response_code,
+   ...);
 
 
 /**
@@ -1129,19 +1129,18 @@ TALER_TESTING_cmd_refresh_melt
  * request, see #5312.
  *
  * @param label command label
- * @param amount FIXME not used.
  * @param coin_reference reference to a command that will provide
  *        a coin to refresh
  * @param expected_response_code expected HTTP code
- *
+ * @param ... NULL-terminated list of amounts to be melted
  * @return the command.
  */
 struct TALER_TESTING_Command
 TALER_TESTING_cmd_refresh_melt_double
   (const char *label,
-   const char *amount,
    const char *coin_reference,
-   unsigned int expected_response_code);
+   unsigned int expected_response_code,
+   ...);
 
 
 /**
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 71301e58..fddc961f 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -192,8 +192,8 @@ TESTS = \
   $(check_PROGRAMS)
 
 # expected to fail for now: test incomplete, feature not implemented!
-XFAIL_TESTS = \
-  test_exchange_api_revocation
+#XFAIL_TESTS = \
+#  test_exchange_api_revocation
 
 test_exchange_api_SOURCES = \
   test_exchange_api.c
diff --git a/src/lib/exchange_api_refresh.c b/src/lib/exchange_api_refresh.c
index c12fd32d..617eab39 100644
--- a/src/lib/exchange_api_refresh.c
+++ b/src/lib/exchange_api_refresh.c
@@ -1518,11 +1518,11 @@ handle_refresh_reveal_finished (void *cls,
  */
 struct TALER_EXCHANGE_RefreshRevealHandle *
 TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
-                              size_t refresh_data_length,
-                              const char *refresh_data,
-                              uint32_t noreveal_index,
-                              TALER_EXCHANGE_RefreshRevealCallback reveal_cb,
-                              void *reveal_cb_cls)
+                               size_t refresh_data_length,
+                               const char *refresh_data,
+                               uint32_t noreveal_index,
+                               TALER_EXCHANGE_RefreshRevealCallback reveal_cb,
+                               void *reveal_cb_cls)
 {
   struct TALER_EXCHANGE_RefreshRevealHandle *rrh;
   json_t *transfer_privs;
@@ -1535,15 +1535,6 @@ TALER_EXCHANGE_refresh_reveal (struct 
TALER_EXCHANGE_Handle *exchange,
   struct MeltData *md;
   struct TALER_TransferPublicKeyP transfer_pub;
 
-  GNUNET_assert (GNUNET_YES ==
-                TEAH_handle_is_ready (exchange));
-  md = deserialize_melt_data (refresh_data,
-                              refresh_data_length);
-  if (NULL == md)
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
   if (noreveal_index >= TALER_CNC_KAPPA)
   {
     /* We check this here, as it would be really bad to below just
@@ -1553,6 +1544,19 @@ TALER_EXCHANGE_refresh_reveal (struct 
TALER_EXCHANGE_Handle *exchange,
     GNUNET_break (0);
     return NULL;
   }
+  if (GNUNET_YES !=
+      TEAH_handle_is_ready (exchange))
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  md = deserialize_melt_data (refresh_data,
+                              refresh_data_length);
+  if (NULL == md)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
 
   /* now transfer_pub */
   GNUNET_CRYPTO_ecdhe_key_get_public 
(&md->melted_coin.transfer_priv[noreveal_index].ecdhe_priv,
diff --git a/src/lib/test_auditor_api.c b/src/lib/test_auditor_api.c
index 6595ea76..df69eac9 100644
--- a/src/lib/test_auditor_api.c
+++ b/src/lib/test_auditor_api.c
@@ -231,9 +231,9 @@ run (void *cls,
      * Melt the rest of the coin's value (EUR:4.00 = 3x EUR:1.03 + 7x
      * EUR:0.13) */
     TALER_TESTING_cmd_refresh_melt_double ("refresh-melt-1",
-                                           "EUR:4",
                                            "refresh-withdraw-coin-1",
-                                           MHD_HTTP_OK),
+                                           MHD_HTTP_OK,
+                                           NULL),
     /**
      * Complete (successful) melt operation, and withdraw the coins
      */
diff --git a/src/lib/test_exchange_api.c b/src/lib/test_exchange_api.c
index dc868d1d..33a2df9d 100644
--- a/src/lib/test_exchange_api.c
+++ b/src/lib/test_exchange_api.c
@@ -309,8 +309,10 @@ run (void *cls,
      * Melt the rest of the coin's value
      * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
     TALER_TESTING_cmd_refresh_melt_double
-      ("refresh-melt-1", "EUR:4",
-       "refresh-withdraw-coin-1", MHD_HTTP_OK),
+      ("refresh-melt-1",
+       "refresh-withdraw-coin-1",
+       MHD_HTTP_OK,
+       NULL),
     /**
      * Complete (successful) melt operation, and
      * withdraw the coins
@@ -360,8 +362,10 @@ run (void *cls,
     /* Test running a failing melt operation (same operation
      * again must fail) */
     TALER_TESTING_cmd_refresh_melt
-      ("refresh-melt-failing", "EUR:4",
-       "refresh-withdraw-coin-1", MHD_HTTP_FORBIDDEN),
+      ("refresh-melt-failing",
+       "refresh-withdraw-coin-1",
+       MHD_HTTP_FORBIDDEN,
+       NULL),
 
     /* FIXME: also test with coin that was already melted
      * (signature differs from coin that was deposited...) */
diff --git a/src/lib/test_exchange_api_revocation.c 
b/src/lib/test_exchange_api_revocation.c
index bd1d91c6..14bb4553 100644
--- a/src/lib/test_exchange_api_revocation.c
+++ b/src/lib/test_exchange_api_revocation.c
@@ -142,11 +142,13 @@ run (void *cls,
                      \"value\":\"EUR:1\"}]}",
        GNUNET_TIME_UNIT_ZERO, "EUR:1", MHD_HTTP_OK),
     /**
-     * Melt the rest of the coin's value
-     * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
-    TALER_TESTING_cmd_refresh_melt_double
-      ("refresh-melt-1", "EUR:4",
-       "withdraw-coin-1", MHD_HTTP_OK),
+     * Melt SOME of the rest of the coin's value
+     * (EUR:3.17 = 3x EUR:1.03 + 7x EUR:0.13) */
+    TALER_TESTING_cmd_refresh_melt
+      ("refresh-melt-1",
+       "withdraw-coin-1",
+       MHD_HTTP_OK,
+       NULL),
     /**
      * Complete (successful) melt operation, and withdraw the coins
      */
@@ -174,45 +176,49 @@ run (void *cls,
                                "refresh-reveal-1#2",
                                "EUR:1",
                                "refresh-melt-1"),
-    /* Melt original coin AGAIN (FIXME: this command
-       is simply WRONG as it neither matches
-       the EUR:3 that were paid back NOR is melt_double
-       precisely right here!) -- it always tries to MELT EUR:4, which is too 
much! */
-    TALER_TESTING_cmd_refresh_melt_double
-      ("refresh-melt-2", "EUR:3",
-       "withdraw-coin-1", MHD_HTTP_OK),
+    /* Now we have EUR:3.83 EUR back after 3x EUR:1 in paybacks */
+    /* Melt original coin AGAIN, but only create one 0.1 EUR coin;
+       This costs EUR:0.03 in refresh and EUR:01 in withdraw fees,
+       leaving EUR:3.69. */
+    TALER_TESTING_cmd_refresh_melt
+      ("refresh-melt-2",
+       "withdraw-coin-1",
+       MHD_HTTP_OK,
+       "EUR:0.1",
+       NULL),
     /**
      * Complete (successful) melt operation, and withdraw the coins
      */
     TALER_TESTING_cmd_refresh_reveal
       ("refresh-reveal-2",
        "refresh-melt-2", MHD_HTTP_OK),
-    /* Make refreshed coin invalid */
+    /* Revokes refreshed EUR:0.1 coin  */
     TALER_TESTING_cmd_revoke ("revoke-2",
                               MHD_HTTP_OK,
                               "refresh-reveal-2",
                               CONFIG_FILE),
-    /* Make also original coin invalid */
+    /* Revoke also original coin denomination */
     TALER_TESTING_cmd_revoke ("revoke-3",
                               MHD_HTTP_OK,
                               "withdraw-coin-1",
                               CONFIG_FILE),
-    /* Refund coin to original coin */
+    /* Refund coin EUR:0.1 to original coin, creating zombie! */
     TALER_TESTING_cmd_payback ("payback-2",
                                MHD_HTTP_OK,
-                               "refresh-melt-2",
-                               "EUR:1",
+                               "refresh-reveal-2",
+                               "EUR:0.1",
                                "refresh-melt-2"),
-    /* Refund original coin to reserve */
+    /* Due to payback, original coin is now at EUR:3.79 */
+    /* Refund original (now zombie) coin to reserve */
     TALER_TESTING_cmd_payback ("payback-3",
                                MHD_HTTP_OK,
                                "withdraw-coin-1",
-                               "EUR:1",
+                               "EUR:3.79",
                                NULL),
     /* Check the money is back with the reserve */
     TALER_TESTING_cmd_status ("payback-reserve-status-1",
                               "create-reserve-1",
-                              "EUR:1.0",
+                              "EUR:3.79",
                               MHD_HTTP_OK),
     TALER_TESTING_cmd_end ()
   };
diff --git a/src/lib/test_exchange_api_twisted.c 
b/src/lib/test_exchange_api_twisted.c
index 7ba9cbaa..48a4ed36 100644
--- a/src/lib/test_exchange_api_twisted.c
+++ b/src/lib/test_exchange_api_twisted.c
@@ -187,9 +187,9 @@ run (void *cls,
      * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
     TALER_TESTING_cmd_refresh_melt
       ("refresh-melt",
-       "EUR:4",
        "refresh-withdraw-coin",
-       MHD_HTTP_OK),
+       MHD_HTTP_OK,
+       NULL),
 
     /* Trigger 409 Conflict.  */
     TALER_TESTING_cmd_flip_upload
diff --git a/src/lib/testing_api_cmd_refresh.c 
b/src/lib/testing_api_cmd_refresh.c
index bc67af7f..b2754edd 100644
--- a/src/lib/testing_api_cmd_refresh.c
+++ b/src/lib/testing_api_cmd_refresh.c
@@ -37,16 +37,6 @@
 struct MeltDetails
 {
 
-  /**
-   * Amount to melt (including fee).
-   */
-  const char *amount;
-
-  /**
-   * Reference to reserve_withdraw operations for coin to
-   * be used for the /refresh/melt operation.
-   */
-  const char *coin_reference;
 };
 
 
@@ -57,9 +47,10 @@ struct RefreshMeltState
 {
 
   /**
-   * Information about coins to be melted.
+   * Reference to reserve_withdraw operations for coin to
+   * be used for the /refresh/melt operation.
    */
-  struct MeltDetails melted_coin;
+  const char *coin_reference;
 
   /**
    * "Crypto data" used in the refresh operation.
@@ -108,6 +99,11 @@ struct RefreshMeltState
   size_t refresh_data_length;
 
   /**
+   * Amounts to be generated during melt.
+   */
+  const char **melt_fresh_amounts;
+
+  /**
    * Number of fresh coins generated by the melt.
    */
   unsigned int num_fresh_coins;
@@ -314,12 +310,12 @@ reveal_cb (void *cls,
                     "Retrying refresh reveal failed with %u/%d\n",
                     http_status,
                     (int) ec);
-       /* on DB conflicts, do not use backoff */
-       if (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec)
-         rrs->backoff = GNUNET_TIME_UNIT_ZERO;
-       else
-         rrs->backoff = EXCHANGE_LIB_BACKOFF (rrs->backoff);
-       rrs->retry_task = GNUNET_SCHEDULER_add_delayed (rrs->backoff,
+        /* on DB conflicts, do not use backoff */
+        if (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec)
+          rrs->backoff = GNUNET_TIME_UNIT_ZERO;
+        else
+          rrs->backoff = EXCHANGE_LIB_BACKOFF (rrs->backoff);
+        rrs->retry_task = GNUNET_SCHEDULER_add_delayed (rrs->backoff,
                                                         &do_reveal_retry,
                                                         rrs);
         return;
@@ -691,12 +687,9 @@ refresh_link_run (void *cls,
 
   /* find reserve_withdraw command */
   {
-    const struct MeltDetails *md;
-
     rms = melt_cmd->cls;
-    md = &rms->melted_coin;
     coin_cmd = TALER_TESTING_interpreter_lookup_command
-      (rls->is, md->coin_reference);
+      (rls->is, rms->coin_reference);
     if (NULL == coin_cmd)
     {
       GNUNET_break (0);
@@ -879,11 +872,14 @@ refresh_melt_run (void *cls,
 {
   struct RefreshMeltState *rms = cls;
   unsigned int num_fresh_coins;
-  /* FIXME:  this should be dynamic */
-  const char *melt_fresh_amounts[] = {
+  const char *default_melt_fresh_amounts[] = {
     "EUR:1", "EUR:1", "EUR:1", "EUR:0.1",
-    NULL};
+    NULL
+  };
+  const char **melt_fresh_amounts;
 
+  if (NULL == (melt_fresh_amounts = rms->melt_fresh_amounts))
+    melt_fresh_amounts = default_melt_fresh_amounts;
   rms->is = is;
   rms->noreveal_index = UINT16_MAX;
   for (num_fresh_coins=0;
@@ -899,11 +895,10 @@ refresh_melt_run (void *cls,
     const struct TALER_DenominationSignature *melt_sig;
     const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
     const struct TALER_TESTING_Command *coin_command;
-    const struct MeltDetails *md = &rms->melted_coin;
 
     if (NULL == (coin_command
       = TALER_TESTING_interpreter_lookup_command
-        (is, md->coin_reference)))
+        (is, rms->coin_reference)))
     {
       GNUNET_break (0);
       TALER_TESTING_interpreter_fail (rms->is);
@@ -919,18 +914,6 @@ refresh_melt_run (void *cls,
     }
 
     if (GNUNET_OK !=
-        TALER_string_to_amount (md->amount,
-                                &melt_amount))
-    {
-      GNUNET_break (0);
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Failed to parse amount `%s' at %u\n",
-                  md->amount,
-                  is->ip);
-      TALER_TESTING_interpreter_fail (rms->is);
-      return;
-    }
-    if (GNUNET_OK !=
         TALER_TESTING_get_trait_denom_sig (coin_command,
                                            0,
                                            &melt_sig))
@@ -946,6 +929,9 @@ refresh_melt_run (void *cls,
       TALER_TESTING_interpreter_fail (rms->is);
       return;
     }
+    /* Melt amount starts with the melt fee of the old coin; we'll add the
+       values and withdraw fees of the fresh coins next */
+    melt_amount = melt_denom_pub->fee_refresh;
     for (unsigned int i=0;i<num_fresh_coins;i++)
     {
       const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk;
@@ -969,7 +955,14 @@ refresh_melt_run (void *cls,
         TALER_TESTING_interpreter_fail (rms->is);
         return;
       }
-
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_amount_add (&melt_amount,
+                                       &melt_amount,
+                                       &fresh_amount));
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_amount_add (&melt_amount,
+                                       &melt_amount,
+                                       &fresh_pk->fee_withdraw));
       rms->fresh_pks[i] = *fresh_pk;
     }
     rms->refresh_data = TALER_EXCHANGE_refresh_prepare
@@ -1028,6 +1021,7 @@ refresh_melt_cleanup (void *cls,
   GNUNET_free_non_null (rms->refresh_data);
   rms->refresh_data = NULL;
   rms->refresh_data_length = 0;
+  GNUNET_free_non_null (rms->melt_fresh_amounts);
   GNUNET_free (rms);
 }
 
@@ -1070,31 +1064,82 @@ refresh_melt_traits (void *cls,
 
 
 /**
+ * Parse list of amounts for melt operation.
+ *
+ * @param rms[in,out] where to store the list
+ * @param ap NULL-termianted list of amounts to be melted (one per fresh coin)
+ * @return #GNUNET_OK on success
+ */
+static int
+parse_amounts (struct RefreshMeltState *rms,
+               va_list ap)
+{
+  unsigned int len;
+  unsigned int off;
+  const char *amount;
+
+  len = 0;
+  off = 0;
+  while (NULL != (amount = va_arg (ap, const char *)))
+  {
+    if (len == off)
+    {
+      struct TALER_Amount a;
+
+      GNUNET_array_grow (rms->melt_fresh_amounts,
+                         len,
+                         off + 16);
+      if (GNUNET_OK !=
+          TALER_string_to_amount (amount, &a))
+      {
+        GNUNET_break (0);
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "Failed to parse amount `%s' at index %u\n",
+                    amount, off);
+        GNUNET_free (rms->melt_fresh_amounts);
+        rms->melt_fresh_amounts = NULL;
+        return GNUNET_SYSERR;
+      }
+      rms->melt_fresh_amounts[off++] = amount;
+    }
+  }
+  if (0 == off)
+    return GNUNET_OK; /* no amounts given == use defaults! */
+  /* ensure NULL-termination */
+  GNUNET_array_grow (rms->melt_fresh_amounts,
+                     len,
+                     off + 1);
+  return GNUNET_OK;
+}
+
+
+/**
  * Create a "refresh melt" command.
  *
  * @param label command label.
- * @param amount amount to be melted.
  * @param coin_reference reference to a command
  *        that will provide a coin to refresh.
  * @param expected_response_code expected HTTP code.
- *
+ * @param ... NULL-terminated list of amounts to be melted
  * @return the command.
  */
 struct TALER_TESTING_Command
 TALER_TESTING_cmd_refresh_melt
   (const char *label,
-   const char *amount,
    const char *coin_reference,
-   unsigned int expected_response_code)
+   unsigned int expected_response_code,
+   ...)
 {
   struct RefreshMeltState *rms;
-  struct MeltDetails md;
+  va_list ap;
 
-  md.coin_reference = coin_reference;
-  md.amount = amount;
   rms = GNUNET_new (struct RefreshMeltState);
-  rms->melted_coin = md;
+  rms->coin_reference = coin_reference;
   rms->expected_response_code = expected_response_code;
+  va_start (ap, expected_response_code);
+  GNUNET_assert (GNUNET_OK ==
+                 parse_amounts (rms, ap));
+  va_end (ap);
   {
     struct TALER_TESTING_Command cmd = {
       .label = label,
@@ -1116,28 +1161,30 @@ TALER_TESTING_cmd_refresh_melt
  *
  * @param label command label
  * @param exchange connection to the exchange
- * @param amount amount to be melted.
  * @param coin_reference reference to a command that will provide
  *        a coin to refresh
  * @param expected_response_code expected HTTP code
+ * @param ... NULL-terminated list of amounts to be melted
  * @return the command.
  */
 struct TALER_TESTING_Command
 TALER_TESTING_cmd_refresh_melt_double
   (const char *label,
-   const char *amount,
    const char *coin_reference,
-   unsigned int expected_response_code)
+   unsigned int expected_response_code,
+   ...)
 {
   struct RefreshMeltState *rms;
-  struct MeltDetails md;
+  va_list ap;
 
-  md.coin_reference = coin_reference;
-  md.amount = amount;
   rms = GNUNET_new (struct RefreshMeltState);
-  rms->melted_coin = md;
+  rms->coin_reference = coin_reference;
   rms->expected_response_code = expected_response_code;
   rms->double_melt = GNUNET_YES;
+  va_start (ap, expected_response_code);
+  GNUNET_assert (GNUNET_OK ==
+                 parse_amounts (rms, ap));
+  va_end (ap);
   {
     struct TALER_TESTING_Command cmd = {
       .label = label,

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



reply via email to

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