From b31c62039dd342455b678b921ab16156e625af51 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 15 Jun 2016 16:04:29 +0200 Subject: avoid passing int's as void*'s in benchmark logic --- src/benchmark/taler-exchange-benchmark.c | 265 ++++++++++++++++++------------- src/exchange-lib/exchange_api_refund.c | 3 +- 2 files changed, 157 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index 9b410ab5f..4d6531347 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -17,6 +17,7 @@ * @file src/benchmark/taler-exchange-benchmark.c * @brief exchange's benchmark * @author Marcello Stanisci + * @author Christian Grothoff */ #include "platform.h" #include "taler_util.h" @@ -116,6 +117,11 @@ struct Reserve */ struct TALER_EXCHANGE_AdminAddIncomingHandle *aih; + /** + * Index of this reserve in the #reserves array. + */ + unsigned int reserve_index; + }; @@ -189,6 +195,11 @@ struct Coin */ unsigned int reserve_index; + /** + * Index of this coin in the #coins array. + */ + unsigned int coin_index; + /** * If the coin has to be refreshed, this value indicates * how much is left on this coin @@ -237,6 +248,11 @@ static struct Coin *coins; */ static unsigned int transaction_id; +/** + * Transfer UUID counter, used in /admin/add/incoming + */ +static unsigned int transfer_uuid; + /** * This key (usually provided by merchants) is needed when depositing coins, * even though there is no merchant acting in the benchmark @@ -248,6 +264,12 @@ static struct TALER_MerchantPrivateKeyP merchant_priv; */ static char *exchange_uri; +/** + * URI under which the administrative exchange is reachable during the + * benchmark. + */ +static char *exchange_admin_uri; + /** * How many coins (AKA withdraw operations) per reserve should be withdrawn */ @@ -389,10 +411,11 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys, return NULL; } + /** * Function called with the result of the /refresh/reveal operation. * - * @param cls closure with the interpreter state + * @param cls closure with the `struct RefreshRevealCls *` * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed @@ -409,10 +432,12 @@ reveal_cb (void *cls, const json_t *full_response) { struct RefreshRevealCls *rrcls = cls; + struct Coin *coin; unsigned int i; const struct TALER_EXCHANGE_Keys *keys; - coins[rrcls->coin_index].rrh = NULL; + coin = &coins[rrcls->coin_index]; + coin->rrh = NULL; if (MHD_HTTP_OK != http_status) { GNUNET_free (rrcls); @@ -425,7 +450,7 @@ reveal_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Coin #%d revealed!\n", rrcls->coin_index); - coins[rrcls->coin_index].left.value = 0; + coin->left.value = 0; } keys = TALER_EXCHANGE_get_keys (exchange); @@ -440,12 +465,14 @@ reveal_cb (void *cls, "# of coins after refresh: %d\n", revealed_str, ncoins); - GNUNET_free (revealed_str); - fresh_coin.reserve_index = coins[rrcls->coin_index].reserve_index; + + fresh_coin.reserve_index = coin->reserve_index; fresh_coin.pk = find_pk (keys, &rrcls->denoms[i]); fresh_coin.sig = sigs[i]; - GNUNET_array_append (coins, ncoins, fresh_coin); + GNUNET_array_append (coins, + ncoins, + fresh_coin); } GNUNET_free (rrcls); } @@ -454,7 +481,7 @@ reveal_cb (void *cls, /** * Function called with the result of the /refresh/melt operation. * - * @param cls closure with the interpreter state + * @param cls closure with the `struct RefreshRevealCls *` * @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped. * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param noreveal_index choice by the exchange in the cut-and-choose protocol, @@ -471,8 +498,10 @@ melt_cb (void *cls, { /* free'd in `reveal_cb` */ struct RefreshRevealCls *rrcls = cls; + struct Coin *coin; - coins[rrcls->coin_index].rmh = NULL; + coin = &coins[rrcls->coin_index]; + coin->rmh = NULL; if (MHD_HTTP_OK != http_status) { json_dumpf (full_response, stderr, 0); @@ -480,7 +509,7 @@ melt_cb (void *cls, return; } - coins[rrcls->coin_index].rrh + coin->rrh = TALER_EXCHANGE_refresh_reveal (exchange, rrcls->blob_size, rrcls->blob, @@ -494,7 +523,7 @@ melt_cb (void *cls, * Function called upon completion of our /reserve/withdraw request. * This is merely the function which spends withdrawn coins * - * @param cls closure with the interpreter state + * @param cls closure with the `struct Coin` we are withdrawing * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param sig signature over the coin, NULL on error @@ -510,7 +539,7 @@ reserve_withdraw_cb (void *cls, /** * Function called with the result of a /deposit operation. * - * @param cls closure with the interpreter state + * @param cls closure with the `struct Coin` that we are processing * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param exchange_pub public key used by the exchange for signing @@ -523,9 +552,9 @@ deposit_cb (void *cls, const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *obj) { - unsigned int coin_index = (unsigned int) (long) cls; + struct Coin *coin = cls; - coins[coin_index].dh = NULL; + coin->dh = NULL; if (MHD_HTTP_OK != http_status) { json_dumpf (obj, stderr, 0); @@ -534,8 +563,8 @@ deposit_cb (void *cls, } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Coin #%d correctly spent!\n", - coin_index); - if (GNUNET_YES == coins[coin_index].refresh) + coin->coin_index); + if (GNUNET_YES == coin->refresh) { struct RefreshRevealCls *rrcls; char *blob; @@ -550,15 +579,15 @@ deposit_cb (void *cls, unsigned long long acc_value; TALER_amount_get_zero (currency, &curr); - curr.value = COIN_VALUE >> 1; acc_value = 0; - keys = TALER_EXCHANGE_get_keys (exchange); - for (; curr.value > 0; curr.value = curr.value >> 1) + for (curr.value = COIN_VALUE >> 1; curr.value > 0; curr.value = curr.value >> 1) { - if (acc_value + curr.value <= coins[coin_index].left.value) + if (acc_value + curr.value <= coin->left.value) { - GNUNET_array_append (denoms, ndenoms, curr); + GNUNET_array_append (denoms, + ndenoms, + curr); GNUNET_assert (NULL != (curr_dpk = find_pk (keys, &curr))); GNUNET_array_append (dpks, ndenoms2, *curr_dpk); acc_value += curr.value; @@ -567,10 +596,10 @@ deposit_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "# of coins to get in melt: %d\n", ndenoms2); - blob = TALER_EXCHANGE_refresh_prepare (&coins[coin_index].coin_priv, - &coins[coin_index].left, - &coins[coin_index].sig, - coins[coin_index].pk, + blob = TALER_EXCHANGE_refresh_prepare (&coin->coin_priv, + &coin->left, + &coin->sig, + coin->pk, GNUNET_YES, ndenoms2, dpks, @@ -588,14 +617,14 @@ deposit_cb (void *cls, rrcls = GNUNET_new (struct RefreshRevealCls); rrcls->blob = blob; rrcls->blob_size = blob_size; - rrcls->coin_index = coin_index; + rrcls->coin_index = coin->coin_index; rrcls->denoms = denoms; - coins[coin_index].rmh = TALER_EXCHANGE_refresh_melt (exchange, - blob_size, - blob, - &melt_cb, - rrcls); - if (NULL == coins[coin_index].rmh) + coin->rmh = TALER_EXCHANGE_refresh_melt (exchange, + blob_size, + blob, + &melt_cb, + rrcls); + if (NULL == coin->rmh) { fail ("Impossible to issue a melt request to the exchange"); return; @@ -604,17 +633,18 @@ deposit_cb (void *cls, else { /* re-withdraw */ struct GNUNET_CRYPTO_EddsaPrivateKey *coin_priv; + coin_priv = GNUNET_CRYPTO_eddsa_key_create (); - coins[coin_index].coin_priv.eddsa_priv = *coin_priv; + coin->coin_priv.eddsa_priv = *coin_priv; GNUNET_free (coin_priv); - coins[coin_index].wsh = + coin->wsh = TALER_EXCHANGE_reserve_withdraw (exchange, - coins[coin_index].pk, - &reserves[coins[coin_index].reserve_index].reserve_priv, - &coins[coin_index].coin_priv, + coin->pk, + &reserves[coin->reserve_index].reserve_priv, + &coin->coin_priv, &blinding_key, - reserve_withdraw_cb, - (void *) (long) coin_index); + &reserve_withdraw_cb, + coin); } } @@ -624,7 +654,7 @@ deposit_cb (void *cls, * This is merely the function which spends withdrawn coins. For each * spent coin, ti either refresh it or re-withdraw it. * - * @param cls closure with the interpreter state + * @param cls closure with our `struct Coin` * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param sig signature over the coin, NULL on error @@ -636,10 +666,9 @@ reserve_withdraw_cb (void *cls, const struct TALER_DenominationSignature *sig, const json_t *full_response) { + struct Coin *coin = cls; - unsigned int coin_index = (unsigned int) (long) cls; - - coins[coin_index].wsh = NULL; + coin->wsh = NULL; if (MHD_HTTP_OK != http_status) { json_dumpf (full_response, stderr, 0); @@ -648,8 +677,8 @@ reserve_withdraw_cb (void *cls, } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%d-th coin withdrawn\n", - coin_index); - coins[coin_index].sig.rsa_signature = + coin->coin_index); + coin->sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature); if (GNUNET_OK == eval_probability (SPEND_PROBABILITY)) { @@ -663,44 +692,49 @@ reserve_withdraw_cb (void *cls, struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_CoinSpendSignatureP coin_sig; - GNUNET_CRYPTO_eddsa_key_get_public (&coins[coin_index].coin_priv.eddsa_priv, + GNUNET_CRYPTO_eddsa_key_get_public (&coin->coin_priv.eddsa_priv, &coin_pub.eddsa_pub); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &h_contract, sizeof (h_contract)); timestamp = GNUNET_TIME_absolute_get (); - wire_deadline = GNUNET_TIME_absolute_add (timestamp, GNUNET_TIME_UNIT_WEEKS); - refund_deadline = GNUNET_TIME_absolute_add (timestamp, GNUNET_TIME_UNIT_DAYS); + wire_deadline = GNUNET_TIME_absolute_add (timestamp, + GNUNET_TIME_UNIT_WEEKS); + refund_deadline = GNUNET_TIME_absolute_add (timestamp, + GNUNET_TIME_UNIT_DAYS); GNUNET_TIME_round_abs (×tamp); GNUNET_TIME_round_abs (&wire_deadline); GNUNET_TIME_round_abs (&refund_deadline); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Spending %d-th coin\n", coin_index); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Spending %d-th coin\n", + coin->coin_index); - if (GNUNET_YES == eval_probability (REFRESH_PROBABILITY) - && GNUNET_NO == refreshed_once) + if ( (GNUNET_YES == eval_probability (REFRESH_PROBABILITY)) && + (GNUNET_NO == refreshed_once) ) { /** * Always spending 1 out of 8 KUDOS. To be improved by randomly * picking the spent amount */ struct TALER_Amount one; + TALER_amount_get_zero (currency, &one); one.value = 1; TALER_amount_subtract (&amount, &one, - &coins[coin_index].pk->fee_deposit); - TALER_amount_subtract (&coins[coin_index].left, - &coins[coin_index].pk->value, + &coin->pk->fee_deposit); + TALER_amount_subtract (&coin->left, + &coin->pk->value, &one); - coins[coin_index].refresh = GNUNET_YES; + coin->refresh = GNUNET_YES; refreshed_once = GNUNET_YES; } else { TALER_amount_subtract (&amount, - &coins[coin_index].pk->value, - &coins[coin_index].pk->fee_deposit); + &coin->pk->value, + &coin->pk->fee_deposit); } memset (&dr, 0, sizeof (dr)); dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS)); @@ -716,33 +750,33 @@ reserve_withdraw_cb (void *cls, TALER_amount_hton (&dr.amount_with_fee, &amount); TALER_amount_hton (&dr.deposit_fee, - &coins[coin_index].pk->fee_deposit); + &coin->pk->fee_deposit); GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv.eddsa_priv, &merchant_pub.eddsa_pub); dr.merchant = merchant_pub; dr.coin_pub = coin_pub; GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_eddsa_sign (&coins[coin_index].coin_priv.eddsa_priv, + GNUNET_CRYPTO_eddsa_sign (&coin->coin_priv.eddsa_priv, &dr.purpose, &coin_sig.eddsa_signature)); - coins[coin_index].dh = TALER_EXCHANGE_deposit (exchange, - &amount, - wire_deadline, - merchant_details, - &h_contract, - &coin_pub, - &coins[coin_index].sig, - &coins[coin_index].pk->key, - timestamp, - transaction_id, - &merchant_pub, - refund_deadline, - &coin_sig, - &deposit_cb, - (void *) (long) coin_index); - if (NULL == coins[coin_index].dh) + coin->dh = TALER_EXCHANGE_deposit (exchange, + &amount, + wire_deadline, + merchant_details, + &h_contract, + &coin_pub, + &coin->sig, + &coin->pk->key, + timestamp, + transaction_id, + &merchant_pub, + refund_deadline, + &coin_sig, + &deposit_cb, + coin); + if (NULL == coin->dh) { json_decref (merchant_details); fail ("An error occurred while calling deposit API"); @@ -757,7 +791,7 @@ reserve_withdraw_cb (void *cls, * Function called upon completion of our /admin/add/incoming request. * Its duty is withdrawing coins on the freshly created reserve. * - * @param cls closure with the interpreter state + * @param cls closure with the `struct Reserve *` * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param full_response full response from the exchange (for logging, in case of errors) @@ -767,18 +801,17 @@ add_incoming_cb (void *cls, unsigned int http_status, const json_t *full_response) { - unsigned int reserve_index = (unsigned int) (long) cls; + struct Reserve *r = cls; struct GNUNET_CRYPTO_EddsaPrivateKey *coin_priv; unsigned int i; unsigned int coin_index; struct TALER_Amount amount; const struct TALER_EXCHANGE_Keys *keys; - keys = TALER_EXCHANGE_get_keys (exchange); + r->aih = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "/admin/add/incoming callback called on %d-th reserve\n", - reserve_index); - reserves[reserve_index].aih = NULL; + r->reserve_index); if (MHD_HTTP_OK != http_status) { json_dumpf (full_response, stderr, 0); @@ -786,24 +819,30 @@ add_incoming_cb (void *cls, return; } + keys = TALER_EXCHANGE_get_keys (exchange); for (i=0; i < COINS_PER_RESERVE; i++) { + struct Coin *coin; + + coin_index = r->reserve_index * COINS_PER_RESERVE + i; + coin = &coins[coin_index]; + coin->coin_index = coin_index; coin_priv = GNUNET_CRYPTO_eddsa_key_create (); - coin_index = reserve_index * COINS_PER_RESERVE + i; - coins[coin_index].coin_priv.eddsa_priv = *coin_priv; - coins[coin_index].reserve_index = reserve_index; - TALER_amount_get_zero (currency, &amount); - amount.value = COIN_VALUE; - GNUNET_assert (NULL != (coins[coin_index].pk = find_pk (keys, &amount))); + coin->coin_priv.eddsa_priv = *coin_priv; GNUNET_free (coin_priv); - coins[coin_index].wsh = + coin->reserve_index = r->reserve_index; + TALER_amount_get_zero (currency, + &amount); + amount.value = COIN_VALUE; + GNUNET_assert (NULL != (coin->pk = find_pk (keys, &amount))); + coin->wsh = TALER_EXCHANGE_reserve_withdraw (exchange, - coins[coin_index].pk, - &reserves[reserve_index].reserve_priv, - &coins[coin_index].coin_priv, + coin->pk, + &r->reserve_priv, + &coin->coin_priv, &blinding_key, - reserve_withdraw_cb, - (void *) (long) coin_index); + &reserve_withdraw_cb, + coin); } } @@ -819,7 +858,6 @@ benchmark_run (void *cls) unsigned int i; struct GNUNET_CRYPTO_EddsaPrivateKey *priv; json_t *transfer_details; - char *uuid; struct TALER_ReservePublicKeyP reserve_pub; struct GNUNET_TIME_Absolute execution_date; struct TALER_Amount reserve_amount; @@ -849,26 +887,27 @@ benchmark_run (void *cls) for (i=0;i < nreserves;i++) { + struct Reserve *r = &reserves[i]; + priv = GNUNET_CRYPTO_eddsa_key_create (); - reserves[i].reserve_priv.eddsa_priv = *priv; + r->reserve_priv.eddsa_priv = *priv; GNUNET_free (priv); - // FIXME: avoid use of JSON parser - GNUNET_asprintf (&uuid, "{ \"uuid\":%d}", i); - transfer_details = json_loads (uuid, JSON_REJECT_DUPLICATES, NULL); - GNUNET_free (uuid); - GNUNET_CRYPTO_eddsa_key_get_public (&reserves[i].reserve_priv.eddsa_priv, + r->reserve_index = i; + transfer_details = json_pack ("{s:I}", + "uuid", (json_int_t) transfer_uuid++); + GNUNET_assert (NULL != transfer_details); + GNUNET_CRYPTO_eddsa_key_get_public (&r->reserve_priv.eddsa_priv, &reserve_pub.eddsa_pub); - - reserves[i].aih = TALER_EXCHANGE_admin_add_incoming (exchange, - "http://localhost:18080/", - &reserve_pub, - &reserve_amount, - execution_date, - bank_details, - transfer_details, - &add_incoming_cb, - (void *) (long) i); - GNUNET_assert (NULL != reserves[i].aih); + r->aih = TALER_EXCHANGE_admin_add_incoming (exchange, + exchange_admin_uri, + &reserve_pub, + &reserve_amount, + execution_date, + bank_details, + transfer_details, + &add_incoming_cb, + r); + GNUNET_assert (NULL != r->aih); json_decref (transfer_details); } json_decref (bank_details); @@ -1187,7 +1226,11 @@ main (int argc, &GNUNET_GETOPT_set_uint, &pool_size}, {'e', "exchange-uri", "URI", "URI of the exchange", GNUNET_YES, - &GNUNET_GETOPT_set_string, &exchange_uri} + &GNUNET_GETOPT_set_string, &exchange_uri}, + {'E', "exchange-admin-uri", "URI", + "URI of the administrative interface of the exchange", GNUNET_YES, + &GNUNET_GETOPT_set_string, &exchange_admin_uri}, + GNUNET_GETOPT_OPTION_END }; GNUNET_log_setup ("taler-exchange-benchmark", @@ -1198,6 +1241,8 @@ main (int argc, options, argc, argv)); if (NULL == exchange_uri) exchange_uri = GNUNET_strdup ("http://localhost:8081/"); + if (NULL == exchange_admin_uri) + exchange_admin_uri = GNUNET_strdup ("http://localhost:18080/"); if (run_exchange) { char *wget; diff --git a/src/exchange-lib/exchange_api_refund.c b/src/exchange-lib/exchange_api_refund.c index fff03acf9..26b960703 100644 --- a/src/exchange-lib/exchange_api_refund.c +++ b/src/exchange-lib/exchange_api_refund.c @@ -283,7 +283,8 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, "merchant_pub", GNUNET_JSON_from_data_auto (&rr.merchant), "merchant_sig", GNUNET_JSON_from_data_auto (&merchant_sig) ); - + GNUNET_assert (NULL != refund_obj); + rh = GNUNET_new (struct TALER_EXCHANGE_RefundHandle); rh->exchange = exchange; rh->cb = cb; -- cgit v1.2.3