spending logic in benchmark

This commit is contained in:
Marcello Stanisci 2016-06-06 16:53:42 +02:00
parent 0fef44159a
commit 2f6c57f351

View File

@ -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 (&timestamp);
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);