summaryrefslogtreecommitdiff
path: root/src/testing/testing_api_cmd_refresh.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing/testing_api_cmd_refresh.c')
-rw-r--r--src/testing/testing_api_cmd_refresh.c727
1 files changed, 398 insertions, 329 deletions
diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c
index fcf8540c0..111e9118f 100644
--- a/src/testing/testing_api_cmd_refresh.c
+++ b/src/testing/testing_api_cmd_refresh.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2018-2020 Taler Systems SA
+ Copyright (C) 2018-2022 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@@ -70,10 +70,17 @@ struct TALER_TESTING_FreshCoinData
*/
struct TALER_CoinSpendPrivateKeyP coin_priv;
+ /*
+ * Fresh age commitment for the coin with proof and its hash, NULL if not
+ * applicable.
+ */
+ struct TALER_AgeCommitmentProof *age_commitment_proof;
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
/**
* The blinding key (needed for recoup operations).
*/
- struct TALER_DenominationBlindingKeyP blinding_key;
+ union GNUNET_CRYPTO_BlindingSecretP blinding_key;
};
@@ -91,9 +98,14 @@ struct RefreshMeltState
const char *coin_reference;
/**
- * "Crypto data" used in the refresh operation.
+ * Data used in the refresh operation.
+ */
+ struct TALER_EXCHANGE_RefreshData refresh_data;
+
+ /**
+ * Our command.
*/
- char *refresh_data;
+ const struct TALER_TESTING_Command *cmd;
/**
* Reference to a previous melt command.
@@ -106,6 +118,12 @@ struct RefreshMeltState
struct TALER_EXCHANGE_MeltHandle *rmh;
/**
+ * Expected entry in the coin history created by this
+ * operation.
+ */
+ struct TALER_EXCHANGE_CoinHistoryEntry che;
+
+ /**
* Interpreter state.
*/
struct TALER_TESTING_Interpreter *is;
@@ -117,11 +135,27 @@ struct RefreshMeltState
struct TALER_EXCHANGE_DenomPublicKey *fresh_pks;
/**
+ * Array of @e num_fresh_coins of results from
+ * the melt operation.
+ */
+ struct TALER_EXCHANGE_MeltBlindingDetail *mbds;
+
+ /**
+ * Entropy seed for the refresh-melt operation.
+ */
+ struct TALER_RefreshMasterSecretP rms;
+
+ /**
* Private key of the dirty coin being melted.
*/
const struct TALER_CoinSpendPrivateKeyP *melt_priv;
/**
+ * Public key of the dirty coin being melted.
+ */
+ struct TALER_CoinSpendPublicKeyP melt_pub;
+
+ /**
* Task scheduled to try later.
*/
struct GNUNET_SCHEDULER_Task *retry_task;
@@ -137,11 +171,6 @@ struct RefreshMeltState
struct GNUNET_TIME_Relative total_backoff;
/**
- * Number of bytes in @e refresh_data.
- */
- size_t refresh_data_length;
-
- /**
* Amounts to be generated during melt.
*/
const char **melt_fresh_amounts;
@@ -167,7 +196,7 @@ struct RefreshMeltState
* exchange to pick any previous /rerfesh/melt operation from
* the database.
*/
- unsigned int double_melt;
+ bool double_melt;
/**
* How often should we retry on (transient) failures?
@@ -197,6 +226,11 @@ struct RefreshRevealState
struct TALER_EXCHANGE_RefreshesRevealHandle *rrh;
/**
+ * Our command.
+ */
+ const struct TALER_TESTING_Command *cmd;
+
+ /**
* Convenience struct to keep in one place all the
* data related to one fresh coin, set by the reveal callback
* as it comes from the exchange.
@@ -204,6 +238,12 @@ struct RefreshRevealState
struct TALER_TESTING_FreshCoinData *fresh_coins;
/**
+ * Array of @e num_fresh_coins planchet secrets derived
+ * from the transfer secret per fresh coin.
+ */
+ struct TALER_PlanchetMasterSecretP *psa;
+
+ /**
* Interpreter state.
*/
struct TALER_TESTING_Interpreter *is;
@@ -254,6 +294,11 @@ struct RefreshLinkState
const char *reveal_reference;
/**
+ * Our command.
+ */
+ const struct TALER_TESTING_Command *cmd;
+
+ /**
* Handle to the ongoing operation.
*/
struct TALER_EXCHANGE_LinkHandle *rlh;
@@ -315,8 +360,7 @@ do_reveal_retry (void *cls)
struct RefreshRevealState *rrs = cls;
rrs->retry_task = NULL;
- rrs->is->commands[rrs->is->ip].last_req_time
- = GNUNET_TIME_absolute_get ();
+ TALER_TESTING_touch_cmd (rrs->is);
refresh_reveal_run (rrs,
NULL,
rrs->is);
@@ -329,23 +373,14 @@ do_reveal_retry (void *cls)
* coming from the exchange, namely the fresh coins.
*
* @param cls closure, a `struct RefreshRevealState`
- * @param hr HTTP response details
- * @param num_coins number of fresh coins created, length of the
- * @a sigs and @a coin_privs arrays, 0 if the operation
- * failed.
- * @param coin_privs array of @a num_coins private keys for the
- * coins that were created, NULL on error.
- * @param sigs array of signature over @a num_coins coins,
- * NULL on error.
+ * @param rr HTTP response details
*/
static void
reveal_cb (void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- unsigned int num_coins,
- const struct TALER_PlanchetSecretsP *coin_privs,
- const struct TALER_DenominationSignature *sigs)
+ const struct TALER_EXCHANGE_RevealResult *rr)
{
struct RefreshRevealState *rrs = cls;
+ const struct TALER_EXCHANGE_HttpResponse *hr = &rr->hr;
const struct TALER_TESTING_Command *melt_cmd;
rrs->rrh = NULL;
@@ -370,24 +405,16 @@ reveal_cb (void *cls,
MAX_BACKOFF);
rrs->total_backoff = GNUNET_TIME_relative_add (rrs->total_backoff,
rrs->backoff);
- rrs->is->commands[rrs->is->ip].num_tries++;
+ TALER_TESTING_inc_tries (rrs->is);
rrs->retry_task = GNUNET_SCHEDULER_add_delayed (rrs->backoff,
&do_reveal_retry,
rrs);
return;
}
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d to command %s in %s:%u\n",
- hr->http_status,
- (int) hr->ec,
- rrs->is->commands[rrs->is->ip].label,
- __FILE__,
- __LINE__);
- json_dumpf (hr->reply,
- stderr,
- 0);
- TALER_TESTING_interpreter_fail (rrs->is);
+ TALER_TESTING_unexpected_status (rrs->is,
+ hr->http_status,
+ rrs->expected_response_code);
return;
}
melt_cmd = TALER_TESTING_interpreter_lookup_command (rrs->is,
@@ -398,16 +425,22 @@ reveal_cb (void *cls,
TALER_TESTING_interpreter_fail (rrs->is);
return;
}
- rrs->num_fresh_coins = num_coins;
switch (hr->http_status)
{
case MHD_HTTP_OK:
- rrs->fresh_coins = GNUNET_new_array (num_coins,
+ rrs->num_fresh_coins = rr->details.ok.num_coins;
+ rrs->psa = GNUNET_new_array (rrs->num_fresh_coins,
+ struct TALER_PlanchetMasterSecretP);
+ rrs->fresh_coins = GNUNET_new_array (rrs->num_fresh_coins,
struct TALER_TESTING_FreshCoinData);
- for (unsigned int i = 0; i<num_coins; i++)
+ for (unsigned int i = 0; i<rrs->num_fresh_coins; i++)
{
+ const struct TALER_EXCHANGE_RevealedCoinInfo *coin
+ = &rr->details.ok.coins[i];
struct TALER_TESTING_FreshCoinData *fc = &rrs->fresh_coins[i];
+ rrs->psa[i] = coin->ps;
+ fc->blinding_key = coin->bks;
if (GNUNET_OK !=
TALER_TESTING_get_trait_denom_pub (melt_cmd,
i,
@@ -417,18 +450,25 @@ reveal_cb (void *cls,
TALER_TESTING_interpreter_fail (rrs->is);
return;
}
- fc->coin_priv = coin_privs[i].coin_priv;
- fc->blinding_key = coin_privs[i].blinding_key;
- fc->sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup
- (sigs[i].rsa_signature);
+ fc->coin_priv = coin->coin_priv;
+
+ if (NULL != coin->age_commitment_proof)
+ {
+ fc->age_commitment_proof =
+ TALER_age_commitment_proof_duplicate (coin->age_commitment_proof);
+ fc->h_age_commitment = coin->h_age_commitment;
+ }
+
+ TALER_denom_sig_copy (&fc->sig,
+ &coin->sig);
}
if (0 != rrs->total_backoff.rel_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Total reveal backoff for %s was %s\n",
- rrs->is->commands[rrs->is->ip].label,
+ rrs->cmd->label,
GNUNET_STRINGS_relative_time_to_string (rrs->total_backoff,
- GNUNET_YES));
+ true));
}
break;
default:
@@ -449,6 +489,19 @@ reveal_cb (void *cls,
* @param is the interpreter state.
*/
static void
+melt_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is);
+
+
+/**
+ * Run the command.
+ *
+ * @param cls closure.
+ * @param cmd the command to execute.
+ * @param is the interpreter state.
+ */
+static void
refresh_reveal_run (void *cls,
const struct TALER_TESTING_Command *cmd,
struct TALER_TESTING_Interpreter *is)
@@ -457,6 +510,7 @@ refresh_reveal_run (void *cls,
struct RefreshMeltState *rms;
const struct TALER_TESTING_Command *melt_cmd;
+ rrs->cmd = cmd;
rrs->is = is;
melt_cmd = TALER_TESTING_interpreter_lookup_command (is,
rrs->melt_reference);
@@ -466,14 +520,24 @@ refresh_reveal_run (void *cls,
TALER_TESTING_interpreter_fail (rrs->is);
return;
}
+ GNUNET_assert (melt_cmd->run == &melt_run);
rms = melt_cmd->cls;
- rrs->rrh = TALER_EXCHANGE_refreshes_reveal (is->exchange,
- rms->refresh_data_length,
- rms->refresh_data,
- rms->noreveal_index,
- &reveal_cb,
- rrs);
-
+ {
+ struct TALER_ExchangeWithdrawValues alg_values[rms->num_fresh_coins];
+
+ for (unsigned int i = 0; i<rms->num_fresh_coins; i++)
+ alg_values[i] = rms->mbds[i].alg_value;
+ rrs->rrh = TALER_EXCHANGE_refreshes_reveal (
+ TALER_TESTING_interpreter_get_context (is),
+ TALER_TESTING_get_exchange_url (is),
+ &rms->rms,
+ &rms->refresh_data,
+ rms->num_fresh_coins,
+ alg_values,
+ rms->noreveal_index,
+ &reveal_cb,
+ rrs);
+ }
if (NULL == rrs->rrh)
{
GNUNET_break (0);
@@ -496,12 +560,11 @@ refresh_reveal_cleanup (void *cls,
{
struct RefreshRevealState *rrs = cls;
+ (void) cmd;
if (NULL != rrs->rrh)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Command %u (%s) did not complete\n",
- rrs->is->ip,
- cmd->label);
+ TALER_TESTING_command_incomplete (rrs->is,
+ cmd->label);
TALER_EXCHANGE_refreshes_reveal_cancel (rrs->rrh);
rrs->rrh = NULL;
}
@@ -512,10 +575,14 @@ refresh_reveal_cleanup (void *cls,
}
for (unsigned int j = 0; j < rrs->num_fresh_coins; j++)
- GNUNET_CRYPTO_rsa_signature_free (rrs->fresh_coins[j].sig.rsa_signature);
+ {
+ TALER_denom_sig_free (&rrs->fresh_coins[j].sig);
+ TALER_age_commitment_proof_free (rrs->fresh_coins[j].age_commitment_proof);
+ GNUNET_free (rrs->fresh_coins[j].age_commitment_proof);
+ }
GNUNET_free (rrs->fresh_coins);
- rrs->fresh_coins = NULL;
+ GNUNET_free (rrs->psa);
rrs->num_fresh_coins = 0;
GNUNET_free (rrs);
}
@@ -545,8 +612,7 @@ do_link_retry (void *cls)
struct RefreshLinkState *rls = cls;
rls->retry_task = NULL;
- rls->is->commands[rls->is->ip].last_req_time
- = GNUNET_TIME_absolute_get ();
+ TALER_TESTING_touch_cmd (rls->is);
refresh_link_run (rls,
NULL,
rls->is);
@@ -559,29 +625,15 @@ do_link_retry (void *cls)
* withdrawn by the "refresh reveal" CMD.
*
* @param cls closure.
- * @param hr HTTP response details
- * @param num_coins number of fresh coins created, length of the
- * @a sigs and @a coin_privs arrays, 0 if the operation
- * failed.
- * @param coin_privs array of @a num_coins private keys for the
- * coins that were created, NULL on error.
- * @param sigs array of signature over @a num_coins coins, NULL on
- * error.
- * @param pubs array of public keys for the @a sigs,
- * NULL on error.
+ * @param lr HTTP response details
*/
static void
link_cb (void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- unsigned int num_coins,
- const struct TALER_CoinSpendPrivateKeyP *coin_privs,
- const struct TALER_DenominationSignature *sigs,
- const struct TALER_DenominationPublicKey *pubs)
+ const struct TALER_EXCHANGE_LinkResult *lr)
{
-
struct RefreshLinkState *rls = cls;
+ const struct TALER_EXCHANGE_HttpResponse *hr = &lr->hr;
const struct TALER_TESTING_Command *reveal_cmd;
- struct TALER_TESTING_Command *link_cmd = &rls->is->commands[rls->is->ip];
unsigned int found;
const unsigned int *num_fresh_coins;
@@ -607,24 +659,16 @@ link_cb (void *cls,
MAX_BACKOFF);
rls->total_backoff = GNUNET_TIME_relative_add (rls->total_backoff,
rls->backoff);
- rls->is->commands[rls->is->ip].num_tries++;
+ TALER_TESTING_inc_tries (rls->is);
rls->retry_task = GNUNET_SCHEDULER_add_delayed (rls->backoff,
&do_link_retry,
rls);
return;
}
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d to command %s in %s:%u\n",
- hr->http_status,
- (int) hr->ec,
- link_cmd->label,
- __FILE__,
- __LINE__);
- json_dumpf (hr->reply,
- stderr,
- 0);
- TALER_TESTING_interpreter_fail (rls->is);
+ TALER_TESTING_unexpected_status (rls->is,
+ hr->http_status,
+ rls->expected_response_code);
return;
}
reveal_cmd = TALER_TESTING_interpreter_lookup_command (rls->is,
@@ -641,19 +685,18 @@ link_cb (void *cls,
case MHD_HTTP_OK:
/* check that number of coins returned matches */
if (GNUNET_OK !=
- TALER_TESTING_get_trait_uint (reveal_cmd,
- 0,
- &num_fresh_coins))
+ TALER_TESTING_get_trait_array_length (reveal_cmd,
+ &num_fresh_coins))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (rls->is);
return;
}
- if (num_coins != *num_fresh_coins)
+ if (lr->details.ok.num_coins != *num_fresh_coins)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected number of fresh coins: %d vs %d in %s:%u\n",
- num_coins,
+ lr->details.ok.num_coins,
*num_fresh_coins,
__FILE__,
__LINE__);
@@ -661,22 +704,21 @@ link_cb (void *cls,
return;
}
/* check that the coins match */
- for (unsigned int i = 0; i<num_coins; i++)
- for (unsigned int j = i + 1; j<num_coins; j++)
+ for (unsigned int i = 0; i<lr->details.ok.num_coins; i++)
+ for (unsigned int j = i + 1; j<lr->details.ok.num_coins; j++)
if (0 ==
- GNUNET_memcmp (&coin_privs[i],
- &coin_privs[j]))
+ GNUNET_memcmp (&lr->details.ok.coins[i].coin_priv,
+ &lr->details.ok.coins[j].coin_priv))
GNUNET_break (0);
/* Note: coins might be legitimately permutated in here... */
found = 0;
/* Will point to the pointer inside the cmd state. */
{
- const struct TALER_TESTING_FreshCoinData *fc = NULL;
+ const struct TALER_TESTING_FreshCoinData **fc = NULL;
if (GNUNET_OK !=
TALER_TESTING_get_trait_fresh_coins (reveal_cmd,
- 0,
&fc))
{
GNUNET_break (0);
@@ -684,29 +726,38 @@ link_cb (void *cls,
return;
}
- for (unsigned int i = 0; i<num_coins; i++)
- for (unsigned int j = 0; j<num_coins; j++)
+ for (unsigned int i = 0; i<lr->details.ok.num_coins; i++)
+ {
+ const struct TALER_EXCHANGE_LinkedCoinInfo *lci_i
+ = &lr->details.ok.coins[i];
+
+ for (unsigned int j = 0; j<lr->details.ok.num_coins; j++)
{
+ const struct TALER_TESTING_FreshCoinData *fcj
+ = &(*fc)[j];
+
if ( (0 ==
- GNUNET_memcmp (&coin_privs[i],
- &fc[j].coin_priv)) &&
+ GNUNET_memcmp (&fcj->coin_priv,
+ &lci_i->coin_priv)) &&
(0 ==
- GNUNET_CRYPTO_rsa_signature_cmp (fc[i].sig.rsa_signature,
- sigs[j].rsa_signature)) &&
+ TALER_denom_sig_cmp (&fcj->sig,
+ &lci_i->sig)) &&
(0 ==
- GNUNET_CRYPTO_rsa_public_key_cmp (fc[i].pk->key.rsa_public_key,
- pubs[j].rsa_public_key)) )
+ TALER_denom_pub_cmp (&fcj->pk->key,
+ &lci_i->pub)) )
{
found++;
break;
}
- }
+ } /* for j*/
+ } /* for i */
}
- if (found != num_coins)
+ if (found != lr->details.ok.num_coins)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Only %u/%u coins match expectations\n",
- found, num_coins);
+ found,
+ lr->details.ok.num_coins);
GNUNET_break (0);
TALER_TESTING_interpreter_fail (rls->is);
return;
@@ -715,9 +766,9 @@ link_cb (void *cls,
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Total link backoff for %s was %s\n",
- rls->is->commands[rls->is->ip].label,
+ rls->cmd->label,
GNUNET_STRINGS_relative_time_to_string (rls->total_backoff,
- GNUNET_YES));
+ true));
}
break;
default:
@@ -748,8 +799,16 @@ refresh_link_run (void *cls,
const struct TALER_TESTING_Command *reveal_cmd;
const struct TALER_TESTING_Command *melt_cmd;
const struct TALER_TESTING_Command *coin_cmd;
+ const char *exchange_url;
+ rls->cmd = cmd;
rls->is = is;
+ exchange_url = TALER_TESTING_get_exchange_url (is);
+ if (NULL == exchange_url)
+ {
+ GNUNET_break (0);
+ return;
+ }
reveal_cmd = TALER_TESTING_interpreter_lookup_command (rls->is,
rls->reveal_reference);
if (NULL == reveal_cmd)
@@ -769,21 +828,22 @@ refresh_link_run (void *cls,
}
/* find reserve_withdraw command */
+ GNUNET_assert (melt_cmd->run == &melt_run);
+ rms = melt_cmd->cls;
+ coin_cmd = TALER_TESTING_interpreter_lookup_command (rls->is,
+ rms->coin_reference);
+ if (NULL == coin_cmd)
{
- rms = melt_cmd->cls;
- coin_cmd = TALER_TESTING_interpreter_lookup_command (rls->is,
- rms->coin_reference);
- if (NULL == coin_cmd)
- {
- GNUNET_break (0);
- TALER_TESTING_interpreter_fail (rls->is);
- return;
- }
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (rls->is);
+ return;
}
const struct TALER_CoinSpendPrivateKeyP *coin_priv;
- if (GNUNET_OK != TALER_TESTING_get_trait_coin_priv
- (coin_cmd, 0, &coin_priv))
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_coin_priv (coin_cmd,
+ 0,
+ &coin_priv))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (rls->is);
@@ -791,10 +851,13 @@ refresh_link_run (void *cls,
}
/* finally, use private key from withdraw sign command */
- rls->rlh = TALER_EXCHANGE_link (is->exchange,
- coin_priv,
- &link_cb,
- rls);
+ rls->rlh = TALER_EXCHANGE_link (
+ TALER_TESTING_interpreter_get_context (is),
+ exchange_url,
+ coin_priv,
+ rms->refresh_data.melt_age_commitment_proof,
+ &link_cb,
+ rls);
if (NULL == rls->rlh)
{
@@ -820,11 +883,8 @@ refresh_link_cleanup (void *cls,
if (NULL != rls->rlh)
{
-
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Command %u (%s) did not complete\n",
- rls->is->ip,
- cmd->label);
+ TALER_TESTING_command_incomplete (rls->is,
+ cmd->label);
TALER_EXCHANGE_link_cancel (rls->rlh);
rls->rlh = NULL;
}
@@ -838,19 +898,6 @@ refresh_link_cleanup (void *cls,
/**
- * Run the command.
- *
- * @param cls closure.
- * @param cmd the command to execute.
- * @param is the interpreter state.
- */
-static void
-melt_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is);
-
-
-/**
* Task scheduled to re-try #melt_run.
*
* @param cls a `struct RefreshMeltState`
@@ -861,8 +908,7 @@ do_melt_retry (void *cls)
struct RefreshMeltState *rms = cls;
rms->retry_task = NULL;
- rms->is->commands[rms->is->ip].last_req_time
- = GNUNET_TIME_absolute_get ();
+ TALER_TESTING_touch_cmd (rms->is);
melt_run (rms,
NULL,
rms->is);
@@ -875,18 +921,14 @@ do_melt_retry (void *cls)
* CMD was set to do so.
*
* @param cls closure.
- * @param hr HTTP response details
- * @param noreveal_index choice by the exchange in the
- * cut-and-choose protocol, UINT16_MAX on error.
- * @param exchange_pub public key the exchange used for signing.
+ * @param mr melt response details
*/
static void
melt_cb (void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- uint32_t noreveal_index,
- const struct TALER_ExchangePublicKeyP *exchange_pub)
+ const struct TALER_EXCHANGE_MeltResponse *mr)
{
struct RefreshMeltState *rms = cls;
+ const struct TALER_EXCHANGE_HttpResponse *hr = &mr->hr;
rms->rmh = NULL;
if (rms->expected_response_code != hr->http_status)
@@ -910,45 +952,57 @@ melt_cb (void *cls,
MAX_BACKOFF);
rms->total_backoff = GNUNET_TIME_relative_add (rms->total_backoff,
rms->backoff);
- rms->is->commands[rms->is->ip].num_tries++;
+ TALER_TESTING_inc_tries (rms->is);
rms->retry_task = GNUNET_SCHEDULER_add_delayed (rms->backoff,
&do_melt_retry,
rms);
return;
}
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d to command %s in %s:%u\n",
- hr->http_status,
- (int) hr->ec,
- rms->is->commands[rms->is->ip].label,
- __FILE__,
- __LINE__);
- json_dumpf (hr->reply,
- stderr,
- 0);
- TALER_TESTING_interpreter_fail (rms->is);
+ TALER_TESTING_unexpected_status_with_body (rms->is,
+ hr->http_status,
+ rms->expected_response_code,
+ hr->reply);
return;
}
- rms->noreveal_index = noreveal_index;
+ if (MHD_HTTP_OK == hr->http_status)
+ {
+ rms->noreveal_index = mr->details.ok.noreveal_index;
+ if (mr->details.ok.num_mbds != rms->num_fresh_coins)
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (rms->is);
+ return;
+ }
+ GNUNET_free (rms->mbds);
+ rms->mbds = GNUNET_new_array (
+ mr->details.ok.num_mbds,
+ struct TALER_EXCHANGE_MeltBlindingDetail);
+ for (unsigned int i = 0; i<mr->details.ok.num_mbds; i++)
+ TALER_denom_ewv_copy (&rms->mbds[i].alg_value,
+ &mr->details.ok.mbds[i].alg_value);
+ }
if (0 != rms->total_backoff.rel_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Total melt backoff for %s was %s\n",
- rms->is->commands[rms->is->ip].label,
+ rms->cmd->label,
GNUNET_STRINGS_relative_time_to_string (rms->total_backoff,
- GNUNET_YES));
+ true));
}
- if (GNUNET_YES == rms->double_melt)
+ if (rms->double_melt)
{
TALER_LOG_DEBUG ("Doubling the melt (%s)\n",
- rms->is->commands[rms->is->ip].label);
- rms->rmh = TALER_EXCHANGE_melt (rms->is->exchange,
- rms->refresh_data_length,
- rms->refresh_data,
- &melt_cb,
- rms);
- rms->double_melt = GNUNET_NO;
+ rms->cmd->label);
+ rms->rmh = TALER_EXCHANGE_melt (
+ TALER_TESTING_interpreter_get_context (rms->is),
+ TALER_TESTING_get_exchange_url (rms->is),
+ TALER_TESTING_get_keys (rms->is),
+ &rms->rms,
+ &rms->refresh_data,
+ &melt_cb,
+ rms);
+ rms->double_melt = false;
return;
}
TALER_TESTING_interpreter_next (rms->is);
@@ -975,36 +1029,53 @@ melt_run (void *cls,
};
const char **melt_fresh_amounts;
+ rms->cmd = cmd;
if (NULL == (melt_fresh_amounts = rms->melt_fresh_amounts))
melt_fresh_amounts = default_melt_fresh_amounts;
rms->is = is;
rms->noreveal_index = UINT16_MAX;
+ TALER_refresh_master_setup_random (&rms->rms);
for (num_fresh_coins = 0;
NULL != melt_fresh_amounts[num_fresh_coins];
num_fresh_coins++)
;
rms->num_fresh_coins = num_fresh_coins;
- rms->fresh_pks = GNUNET_new_array
- (num_fresh_coins,
- struct TALER_EXCHANGE_DenomPublicKey);
+ rms->fresh_pks = GNUNET_new_array (
+ num_fresh_coins,
+ struct TALER_EXCHANGE_DenomPublicKey);
{
struct TALER_Amount melt_amount;
struct TALER_Amount fresh_amount;
+ const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
+ const struct TALER_AgeCommitmentHash *h_age_commitment = NULL;
const struct TALER_DenominationSignature *melt_sig;
const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
const struct TALER_TESTING_Command *coin_command;
+ bool age_restricted_denom;
if (NULL == (coin_command
- = TALER_TESTING_interpreter_lookup_command
- (is, rms->coin_reference)))
+ = TALER_TESTING_interpreter_lookup_command (
+ is,
+ rms->coin_reference)))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (rms->is);
return;
}
- if (GNUNET_OK != TALER_TESTING_get_trait_coin_priv
- (coin_command, 0, &rms->melt_priv))
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_coin_priv (coin_command,
+ 0,
+ &rms->melt_priv))
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (rms->is);
+ return;
+ }
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_age_commitment_proof (coin_command,
+ 0,
+ &age_commitment_proof))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (rms->is);
@@ -1012,6 +1083,15 @@ melt_run (void *cls,
}
if (GNUNET_OK !=
+ TALER_TESTING_get_trait_h_age_commitment (coin_command,
+ 0,
+ &h_age_commitment))
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (rms->is);
+ return;
+ }
+ if (GNUNET_OK !=
TALER_TESTING_get_trait_denom_sig (coin_command,
0,
&melt_sig))
@@ -1020,32 +1100,42 @@ melt_run (void *cls,
TALER_TESTING_interpreter_fail (rms->is);
return;
}
- if (GNUNET_OK != TALER_TESTING_get_trait_denom_pub
- (coin_command, 0, &melt_denom_pub))
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_denom_pub (coin_command,
+ 0,
+ &melt_denom_pub))
{
GNUNET_break (0);
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;
+ melt_amount = melt_denom_pub->fees.refresh;
+ age_restricted_denom = melt_denom_pub->key.age_mask.bits != 0;
+ GNUNET_assert (age_restricted_denom == (NULL != age_commitment_proof));
+ GNUNET_assert ((NULL == age_commitment_proof) ||
+ (0 < age_commitment_proof->commitment.num));
for (unsigned int i = 0; i<num_fresh_coins; i++)
{
const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk;
- if (GNUNET_OK != TALER_string_to_amount
- (melt_fresh_amounts[i], &fresh_amount))
+ if (GNUNET_OK !=
+ TALER_string_to_amount (melt_fresh_amounts[i],
+ &fresh_amount))
{
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to parse amount `%s' at index %u\n",
- melt_fresh_amounts[i], i);
+ melt_fresh_amounts[i],
+ i);
TALER_TESTING_interpreter_fail (rms->is);
return;
}
- fresh_pk = TALER_TESTING_find_pk
- (TALER_EXCHANGE_get_keys (is->exchange), &fresh_amount);
+ fresh_pk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (rms->is),
+ &fresh_amount,
+ age_restricted_denom);
if (NULL == fresh_pk)
{
GNUNET_break (0);
@@ -1060,32 +1150,49 @@ melt_run (void *cls,
GNUNET_assert (0 <=
TALER_amount_add (&melt_amount,
&melt_amount,
- &fresh_pk->fee_withdraw));
+ &fresh_pk->fees.withdraw));
rms->fresh_pks[i] = *fresh_pk;
/* Make a deep copy of the RSA key */
- rms->fresh_pks[i].key.rsa_public_key
- = GNUNET_CRYPTO_rsa_public_key_dup (fresh_pk->key.rsa_public_key);
- }
- rms->refresh_data
- = TALER_EXCHANGE_refresh_prepare (rms->melt_priv,
- &melt_amount,
- melt_sig,
- melt_denom_pub,
- num_fresh_coins,
- rms->fresh_pks,
- &rms->refresh_data_length);
-
- if (NULL == rms->refresh_data)
+ TALER_denom_pub_copy (&rms->fresh_pks[i].key,
+ &fresh_pk->key);
+ } /* end for */
+
+ rms->refresh_data.melt_priv = *rms->melt_priv;
+ GNUNET_CRYPTO_eddsa_key_get_public (&rms->melt_priv->eddsa_priv,
+ &rms->melt_pub.eddsa_pub);
+ rms->refresh_data.melt_amount = melt_amount;
+ rms->refresh_data.melt_sig = *melt_sig;
+ rms->refresh_data.melt_pk = *melt_denom_pub;
+
+ if (NULL != age_commitment_proof)
{
- GNUNET_break (0);
- TALER_TESTING_interpreter_fail (rms->is);
- return;
+ GNUNET_assert (NULL != h_age_commitment);
+ rms->refresh_data.melt_age_commitment_proof = age_commitment_proof;
+ rms->refresh_data.melt_h_age_commitment = h_age_commitment;
}
- rms->rmh = TALER_EXCHANGE_melt (is->exchange,
- rms->refresh_data_length,
- rms->refresh_data,
- &melt_cb,
- rms);
+ rms->refresh_data.fresh_pks = rms->fresh_pks;
+ rms->refresh_data.fresh_pks_len = num_fresh_coins;
+
+ GNUNET_assert (age_restricted_denom ==
+ (NULL != age_commitment_proof));
+ GNUNET_assert ((NULL == age_commitment_proof) ||
+ (0 < age_commitment_proof->commitment.num));
+
+ rms->che.type = TALER_EXCHANGE_CTT_MELT;
+ rms->che.amount = melt_amount;
+ if (NULL != age_commitment_proof)
+ rms->che.details.melt.h_age_commitment = *h_age_commitment;
+ else
+ rms->che.details.melt.no_hac = true;
+
+ rms->rmh = TALER_EXCHANGE_melt (
+ TALER_TESTING_interpreter_get_context (is),
+ TALER_TESTING_get_exchange_url (is),
+ TALER_TESTING_get_keys (is),
+ &rms->rms,
+ &rms->refresh_data,
+ &melt_cb,
+ rms);
if (NULL == rms->rmh)
{
@@ -1110,11 +1217,11 @@ melt_cleanup (void *cls,
{
struct RefreshMeltState *rms = cls;
+ (void) cmd;
if (NULL != rms->rmh)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Command %u (%s) did not complete\n",
- rms->is->ip, rms->is->commands[rms->is->ip].label);
+ TALER_TESTING_command_incomplete (rms->is,
+ cmd->label);
TALER_EXCHANGE_melt_cancel (rms->rmh);
rms->rmh = NULL;
}
@@ -1126,13 +1233,15 @@ melt_cleanup (void *cls,
if (NULL != rms->fresh_pks)
{
for (unsigned int i = 0; i < rms->num_fresh_coins; i++)
- GNUNET_CRYPTO_rsa_public_key_free (rms->fresh_pks[i].key.rsa_public_key);
+ TALER_denom_pub_free (&rms->fresh_pks[i].key);
+ GNUNET_free (rms->fresh_pks);
+ }
+ if (NULL != rms->mbds)
+ {
+ for (unsigned int i = 0; i < rms->num_fresh_coins; i++)
+ TALER_denom_ewv_free (&rms->mbds[i].alg_value);
+ GNUNET_free (rms->mbds);
}
- GNUNET_free (rms->fresh_pks);
- rms->fresh_pks = NULL;
- GNUNET_free (rms->refresh_data);
- rms->refresh_data = NULL;
- rms->refresh_data_length = 0;
GNUNET_free (rms->melt_fresh_amounts);
GNUNET_free (rms);
}
@@ -1147,7 +1256,7 @@ melt_cleanup (void *cls,
* @param index index number of the object to offer.
* @return #GNUNET_OK on success.
*/
-static int
+static enum GNUNET_GenericReturnValue
melt_traits (void *cls,
const void **ret,
const char *trait,
@@ -1162,8 +1271,25 @@ melt_traits (void *cls,
}
{
struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_denom_pub (index, &rms->fresh_pks[index]),
- TALER_TESTING_make_trait_coin_priv (0, rms->melt_priv),
+ TALER_TESTING_make_trait_denom_pub (index,
+ &rms->fresh_pks[index]),
+ TALER_TESTING_make_trait_coin_priv (0,
+ rms->melt_priv),
+ TALER_TESTING_make_trait_coin_pub (0,
+ &rms->melt_pub),
+ TALER_TESTING_make_trait_coin_history (0,
+ &rms->che),
+ TALER_TESTING_make_trait_age_commitment_proof (
+ index,
+ rms->refresh_data.melt_age_commitment_proof),
+ TALER_TESTING_make_trait_h_age_commitment (
+ index,
+ rms->refresh_data.melt_h_age_commitment),
+ TALER_TESTING_make_trait_refresh_secret (&rms->rms),
+ (NULL != rms->mbds)
+ ? TALER_TESTING_make_trait_exchange_wd_value (index,
+ &rms->mbds[index].alg_value)
+ : TALER_TESTING_trait_end (),
TALER_TESTING_trait_end ()
};
@@ -1182,7 +1308,7 @@ melt_traits (void *cls,
* @param ap NULL-termianted list of amounts to be melted (one per fresh coin)
* @return #GNUNET_OK on success
*/
-static int
+static enum GNUNET_GenericReturnValue
parse_amounts (struct RefreshMeltState *rms,
va_list ap)
{
@@ -1225,16 +1351,6 @@ parse_amounts (struct RefreshMeltState *rms,
}
-/**
- * Create a "refresh melt" command.
- *
- * @param label command label.
- * @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_melt (const char *label,
const char *coin_reference,
@@ -1247,7 +1363,8 @@ TALER_TESTING_cmd_melt (const char *label,
rms = GNUNET_new (struct RefreshMeltState);
rms->coin_reference = coin_reference;
rms->expected_response_code = expected_response_code;
- va_start (ap, expected_response_code);
+ va_start (ap,
+ expected_response_code);
GNUNET_assert (GNUNET_OK ==
parse_amounts (rms, ap));
va_end (ap);
@@ -1265,18 +1382,6 @@ TALER_TESTING_cmd_melt (const char *label,
}
-/**
- * Create a "refresh melt" CMD that does TWO /refresh/melt
- * requests. This was needed to test the replay of a valid melt
- * request, see #5312.
- *
- * @param label command label
- * @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_melt_double (const char *label,
const char *coin_reference,
@@ -1289,8 +1394,9 @@ TALER_TESTING_cmd_melt_double (const char *label,
rms = GNUNET_new (struct RefreshMeltState);
rms->coin_reference = coin_reference;
rms->expected_response_code = expected_response_code;
- rms->double_melt = GNUNET_YES;
- va_start (ap, expected_response_code);
+ rms->double_melt = true;
+ va_start (ap,
+ expected_response_code);
GNUNET_assert (GNUNET_OK ==
parse_amounts (rms, ap));
va_end (ap);
@@ -1308,12 +1414,6 @@ TALER_TESTING_cmd_melt_double (const char *label,
}
-/**
- * Modify a "refresh melt" command to enable retries.
- *
- * @param cmd command
- * @return modified command.
- */
struct TALER_TESTING_Command
TALER_TESTING_cmd_melt_with_retry (struct TALER_TESTING_Command cmd)
{
@@ -1335,65 +1435,54 @@ TALER_TESTING_cmd_melt_with_retry (struct TALER_TESTING_Command cmd)
* @param index index number of the object to offer.
* @return #GNUNET_OK on success.
*/
-static int
+static enum GNUNET_GenericReturnValue
refresh_reveal_traits (void *cls,
const void **ret,
const char *trait,
unsigned int index)
{
struct RefreshRevealState *rrs = cls;
- unsigned int num_coins = rrs->num_fresh_coins;
-#define NUM_TRAITS ((num_coins * 4) + 3)
- struct TALER_TESTING_Trait traits[NUM_TRAITS];
-
- /* Making coin privs traits */
- for (unsigned int i = 0; i<num_coins; i++)
- traits[i] = TALER_TESTING_make_trait_coin_priv
- (i, &rrs->fresh_coins[i].coin_priv);
-
- /* Making denom pubs traits */
- for (unsigned int i = 0; i<num_coins; i++)
- traits[num_coins + i]
- = TALER_TESTING_make_trait_denom_pub
- (i, rrs->fresh_coins[i].pk);
-
- /* Making denom sigs traits */
- for (unsigned int i = 0; i<num_coins; i++)
- traits[(num_coins * 2) + i]
- = TALER_TESTING_make_trait_denom_sig
- (i, &rrs->fresh_coins[i].sig);
- /* blinding key traits */
- for (unsigned int i = 0; i<num_coins; i++)
- traits[(num_coins * 3) + i]
- = TALER_TESTING_make_trait_blinding_key (i,
- &rrs->fresh_coins[i].blinding_key),
-
- /* number of fresh coins */
- traits[(num_coins * 4)] = TALER_TESTING_make_trait_uint
- (0, &rrs->num_fresh_coins);
-
- /* whole array of fresh coins */
- traits[(num_coins * 4) + 1]
- = TALER_TESTING_make_trait_fresh_coins (0, rrs->fresh_coins),
-
- /* end of traits */
- traits[(num_coins * 4) + 2] = TALER_TESTING_trait_end ();
-
- return TALER_TESTING_get_trait (traits,
- ret,
- trait,
- index);
+
+ if (index >= rrs->num_fresh_coins)
+ return GNUNET_SYSERR;
+
+ {
+ struct TALER_TESTING_Trait traits[] = {
+ TALER_TESTING_make_trait_coin_priv (
+ index,
+ &rrs->fresh_coins[index].coin_priv),
+ TALER_TESTING_make_trait_age_commitment_proof (
+ index,
+ rrs->fresh_coins[index].age_commitment_proof),
+ TALER_TESTING_make_trait_h_age_commitment (
+ index,
+ &rrs->fresh_coins[index].h_age_commitment),
+ TALER_TESTING_make_trait_denom_pub (
+ index,
+ rrs->fresh_coins[index].pk),
+ TALER_TESTING_make_trait_denom_sig (
+ index,
+ &rrs->fresh_coins[index].sig),
+ TALER_TESTING_make_trait_blinding_key (
+ index,
+ &rrs->fresh_coins[index].blinding_key),
+ TALER_TESTING_make_trait_array_length (
+ &rrs->num_fresh_coins),
+ TALER_TESTING_make_trait_fresh_coins (
+ (const struct TALER_TESTING_FreshCoinData **) &rrs->fresh_coins),
+ TALER_TESTING_make_trait_planchet_secrets (index,
+ &rrs->psa[index]),
+ TALER_TESTING_trait_end ()
+ };
+
+ return TALER_TESTING_get_trait (traits,
+ ret,
+ trait,
+ index);
+ }
}
-/**
- * Create a "refresh reveal" command.
- *
- * @param label command label.
- * @param melt_reference reference to a "refresh melt" command.
- * @param expected_response_code expected HTTP response code.
- * @return the command.
- */
struct TALER_TESTING_Command
TALER_TESTING_cmd_refresh_reveal (const char *label,
const char *melt_reference,
@@ -1418,12 +1507,6 @@ TALER_TESTING_cmd_refresh_reveal (const char *label,
}
-/**
- * Modify a "refresh reveal" command to enable retries.
- *
- * @param cmd command
- * @return modified command.
- */
struct TALER_TESTING_Command
TALER_TESTING_cmd_refresh_reveal_with_retry (struct TALER_TESTING_Command cmd)
{
@@ -1436,14 +1519,6 @@ TALER_TESTING_cmd_refresh_reveal_with_retry (struct TALER_TESTING_Command cmd)
}
-/**
- * Create a "refresh link" command.
- *
- * @param label command label.
- * @param reveal_reference reference to a "refresh reveal" CMD.
- * @param expected_response_code expected HTTP response code
- * @return the "refresh link" command
- */
struct TALER_TESTING_Command
TALER_TESTING_cmd_refresh_link (const char *label,
const char *reveal_reference,
@@ -1467,12 +1542,6 @@ TALER_TESTING_cmd_refresh_link (const char *label,
}
-/**
- * Modify a "refresh link" command to enable retries.
- *
- * @param cmd command
- * @return modified command.
- */
struct TALER_TESTING_Command
TALER_TESTING_cmd_refresh_link_with_retry (struct TALER_TESTING_Command cmd)
{