From 2f6c57f35150481d214fb393073bc0d2fc3e2e92 Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Mon, 6 Jun 2016 16:53:42 +0200 Subject: spending logic in benchmark --- src/benchmark/taler-exchange-benchmark.c | 140 +++++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 9 deletions(-) diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index b2aa1eea7..4202e72e4 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -98,6 +98,11 @@ struct Coin { */ struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh; + /** + * Deposit handle (while operation is running). + */ + struct TALER_EXCHANGE_DepositHandle *dh; + }; /** @@ -147,6 +152,16 @@ static unsigned int *spent_coins; */ static unsigned int spent_coins_size = 0; +/** + * Transaction id counter + */ +static unsigned int transaction_id = 0; + +/** + * This key (usually provided by merchants) is needed when depositing coins, + * even though there is no merchant acting in the benchmark + */ +static struct TALER_MerchantPrivateKeyP merchant_priv; /** * URI under which the exchange is reachable during the benchmark. @@ -162,7 +177,7 @@ static unsigned int spent_coins_size = 0; * Large enough value to allow having 12 coins per reserve without parsing * /keys in the first place */ -#define RESERVE_AMOUNT "PUDOS:1000" +#define RESERVE_AMOUNT "KUDOS:1000" /** * Probability a coin can be spent @@ -194,6 +209,33 @@ fail (char *msg) GNUNET_SCHEDULER_shutdown (); } +/** + * Function called with the result of a /deposit operation. + * + * @param cls closure with the interpreter state + * @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 obj the received JSON reply, should be kept as proof (and, in case of errors, + * be forwarded to the customer) + */ +static void +deposit_cb (void *cls, + unsigned int http_status, + const json_t *obj) +{ + unsigned int coin_index = (unsigned int) cls; + + + if (MHD_HTTP_OK != http_status) + { + fail ("At least one coin has not been deposited, status: %d\n"); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Coin #%d correctly spent!\n", coin_index); + GNUNET_array_append (spent_coins, spent_coins_size, coin_index); + spent_coins_size++; +} + /** * Function called upon completion of our /reserve/withdraw request. * @@ -219,13 +261,84 @@ reserve_withdraw_cb (void *cls, GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature); if (GNUNET_OK == eval_probability (SPEND_PROBABILITY)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Spending %d-th coin\n", coin_index); - /* FIXME: the following operation must be done once the coins has *actually* - * been spent - */ - GNUNET_array_append (spent_coins, spent_coins_size, coin_index); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "picked! = %d\n", spent_coins[spent_coins_size-1]); - spent_coins_size++; + struct TALER_Amount amount; + struct GNUNET_TIME_Absolute wire_deadline; + struct GNUNET_TIME_Absolute timestamp; + struct GNUNET_TIME_Absolute refund_deadline; + struct GNUNET_HashCode h_contract; + json_t *merchant_details; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_DepositRequestPS dr; + struct TALER_MerchantPublicKeyP merchant_pub; + struct TALER_CoinSpendSignatureP coin_sig; + + GNUNET_CRYPTO_eddsa_key_get_public (&coins[coin_index].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); + GNUNET_TIME_round_abs (×tamp); + GNUNET_TIME_round_abs (&wire_deadline); + GNUNET_TIME_round_abs (&refund_deadline); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Spending %d-th coin\n", coin_index); + TALER_amount_subtract (&amount, + &coins[coin_index].pk->value, + &coins[coin_index].pk->fee_deposit); + merchant_details = json_loads ("{ \"type\":\"test\", \"bank_uri\":\"https://bank.test.taler.net/\", \"account_number\":63}", + JSON_REJECT_DUPLICATES, + NULL); + + memset (&dr, 0, sizeof (dr)); + dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS)); + dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); + dr.h_contract = h_contract; + TALER_JSON_hash (merchant_details, + &dr.h_wire); + + dr.timestamp = GNUNET_TIME_absolute_hton (timestamp); + dr.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline); + dr.transaction_id = GNUNET_htonll (transaction_id); + + TALER_amount_hton (&dr.amount_with_fee, + &amount); + TALER_amount_hton (&dr.deposit_fee, + &coins[coin_index].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, + &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 *) coin_index); + if (NULL == coins[coin_index].dh) + { + json_decref (merchant_details); + fail ("An error occurred while calling deposit API\n"); + } + json_decref (merchant_details); + transaction_id++; + } } @@ -293,11 +406,14 @@ benchmark_run (void *cls) struct GNUNET_TIME_Absolute execution_date; struct TALER_Amount reserve_amount; + priv = GNUNET_CRYPTO_eddsa_key_create (); + merchant_priv.eddsa_priv = *priv; + GNUNET_free (priv); + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &blinding_key, sizeof (blinding_key)); TALER_string_to_amount (RESERVE_AMOUNT, &reserve_amount); - /* FIXME bank_uri to be tuned to exchange's tastes */ sender_details = json_loads ("{ \"type\":\"test\", \"bank_uri\":\"https://bank.test.taler.net/\", \"account_number\":62}", JSON_REJECT_DUPLICATES, NULL); @@ -424,6 +540,12 @@ do_shutdown (void *cls) coins[i].wsh = NULL; } + if (NULL != coins[i].dh) + { + TALER_EXCHANGE_deposit_cancel(coins[i].dh); + coins[i].dh = NULL; + + } } GNUNET_free_non_null (reserves); -- cgit v1.2.3