From 54fc83ee6b910d482948c6ec8185df7aab1b0cb1 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 11 Jan 2019 21:27:34 +0100 Subject: fix cyclic dependency by combining exchange-lib and auditor-lib directories --- src/exchange-lib/testing_api_cmd_refresh.c | 1317 ---------------------------- 1 file changed, 1317 deletions(-) delete mode 100644 src/exchange-lib/testing_api_cmd_refresh.c (limited to 'src/exchange-lib/testing_api_cmd_refresh.c') diff --git a/src/exchange-lib/testing_api_cmd_refresh.c b/src/exchange-lib/testing_api_cmd_refresh.c deleted file mode 100644 index 55900cf27..000000000 --- a/src/exchange-lib/testing_api_cmd_refresh.c +++ /dev/null @@ -1,1317 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2018 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 - the Free Software Foundation; either version 3, or (at your - option) any later version. - - TALER is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with TALER; see the file COPYING. If not, see - -*/ - -/** - * @file exchange-lib/testing_api_cmd_refresh.c - * @brief commands for testing all "refresh" features. - * @author Marcello Stanisci - */ - -#include "platform.h" -#include "taler_json_lib.h" -#include -#include "exchange_api_handle.h" -#include "taler_testing_lib.h" -#include "taler_signatures.h" -#include "backoff.h" - -/** - * Data for a coin to be melted. - */ -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; -}; - - -/** - * State for a "refresh melt" command. - */ -struct RefreshMeltState -{ - - /** - * Information about coins to be melted. - */ - struct MeltDetails melted_coin; - - /** - * "Crypto data" used in the refresh operation. - */ - char *refresh_data; - - /** - * Reference to a previous melt command. - */ - const char *melt_reference; - - /** - * Melt handle while operation is running. - */ - struct TALER_EXCHANGE_RefreshMeltHandle *rmh; - - /** - * Interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Array of the denomination public keys - * corresponding to the @e fresh_amounts. - */ - struct TALER_EXCHANGE_DenomPublicKey *fresh_pks; - - /** - * Task scheduled to try later. - */ - struct GNUNET_SCHEDULER_Task *retry_task; - - /** - * How long do we wait until we retry? - */ - struct GNUNET_TIME_Relative backoff; - - /** - * Number of bytes in @e refresh_data. - */ - size_t refresh_data_length; - - /** - * Expected HTTP response code. - */ - unsigned int expected_response_code; - - /** - * if set to #GNUNET_YES, then two /refresh/melt operations - * will be performed. This is needed to trigger the logic - * that manages those already-made requests. Note: it - * is not possible to just copy-and-paste a test refresh melt - * CMD to have the same effect, because every data preparation - * generates new planchets that (in turn) make the whole "hash" - * different from any previous one, therefore NOT allowing the - * exchange to pick any previous /rerfesh/melt operation from - * the database. - */ - unsigned int double_melt; - - /** - * Should we retry on (transient) failures? - */ - int do_retry; - - /** - * Set by the melt callback as it comes from the exchange. - */ - uint16_t noreveal_index; -}; - - -/** - * State for a "refresh reveal" CMD. - */ -struct RefreshRevealState -{ - /** - * Link to a "refresh melt" command. - */ - const char *melt_reference; - - /** - * Reveal handle while operation is running. - */ - struct TALER_EXCHANGE_RefreshRevealHandle *rrh; - - /** - * 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. - */ - struct FreshCoin *fresh_coins; - - /** - * Interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Task scheduled to try later. - */ - struct GNUNET_SCHEDULER_Task *retry_task; - - /** - * How long do we wait until we retry? - */ - struct GNUNET_TIME_Relative backoff; - - /** - * Number of fresh coins withdrawn, set by the - * reveal callback as it comes from the exchange, - * it is the length of the @e fresh_coins array. - */ - unsigned int num_fresh_coins; - - /** - * Expected HTTP response code. - */ - unsigned int expected_response_code; - - /** - * Should we retry on (transient) failures? - */ - int do_retry; - -}; - - -/** - * State for a "refresh link" CMD. - */ -struct RefreshLinkState -{ - /** - * Link to a "refresh reveal" command. - */ - const char *reveal_reference; - - /** - * Handle to the ongoing operation. - */ - struct TALER_EXCHANGE_RefreshLinkHandle *rlh; - - /** - * Interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Task scheduled to try later. - */ - struct GNUNET_SCHEDULER_Task *retry_task; - - /** - * How long do we wait until we retry? - */ - struct GNUNET_TIME_Relative backoff; - - /** - * Expected HTTP response code. - */ - unsigned int expected_response_code; - - /** - * Should we retry on (transient) failures? - */ - int do_retry; - -}; - - -/** - * 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); - - -/** - * Task scheduled to re-try #refresh_reveal_run. - * - * @param cls a `struct RefreshRevealState` - */ -static void -do_reveal_retry (void *cls) -{ - struct RefreshRevealState *rrs = cls; - - rrs->retry_task = NULL; - refresh_reveal_run (rrs, - NULL, - rrs->is); -} - - -/** - * "refresh reveal" request callback; it checks that the response - * code is expected and copies into its command's state the data - * coming from the exchange, namely the fresh coins. - * - * @param cls closure. - * @param http_status HTTP response code. - * @param ec taler-specific error code. - * @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 full_response raw exchange response. - */ -static void -reveal_cb (void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - unsigned int num_coins, - const struct TALER_CoinSpendPrivateKeyP *coin_privs, - const struct TALER_DenominationSignature *sigs, - const json_t *full_response) -{ - struct RefreshRevealState *rrs = cls; - const struct TALER_TESTING_Command *melt_cmd; - - rrs->rrh = NULL; - if (rrs->expected_response_code != http_status) - { - if (GNUNET_YES == rrs->do_retry) - { - if ( (0 == http_status) || - (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) || - (MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "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, - &do_reveal_retry, - rrs); - return; - } - } - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d to command %s in %s:%u\n", - http_status, - (int) ec, - rrs->is->commands[rrs->is->ip].label, - __FILE__, - __LINE__); - json_dumpf (full_response, stderr, 0); - TALER_TESTING_interpreter_fail (rrs->is); - return; - } - melt_cmd = TALER_TESTING_interpreter_lookup_command - (rrs->is, rrs->melt_reference); - if (NULL == melt_cmd) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rrs->is); - return; - } - rrs->num_fresh_coins = num_coins; - switch (http_status) - { - case MHD_HTTP_OK: - rrs->fresh_coins = GNUNET_new_array - (num_coins, struct FreshCoin); - - const struct TALER_EXCHANGE_DenomPublicKey *fresh_pks; - - if (GNUNET_OK != - TALER_TESTING_get_trait_denom_pub (melt_cmd, - 0, - &fresh_pks)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rrs->is); - return; - } - - for (unsigned int i=0; ifresh_coins[i]; - - fc->pk = &fresh_pks[i]; - fc->coin_priv = coin_privs[i]; - fc->sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup - (sigs[i].rsa_signature); - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unknown HTTP status %d\n", - http_status); - } - TALER_TESTING_interpreter_next (rrs->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) -{ - struct RefreshRevealState *rrs = cls; - struct RefreshMeltState *rms; - const struct TALER_TESTING_Command *melt_cmd; - - rrs->is = is; - melt_cmd = TALER_TESTING_interpreter_lookup_command - (is, rrs->melt_reference); - - if (NULL == melt_cmd) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rrs->is); - return; - } - rms = melt_cmd->cls; - rrs->rrh = TALER_EXCHANGE_refresh_reveal - (is->exchange, - rms->refresh_data_length, - rms->refresh_data, - rms->noreveal_index, - &reveal_cb, rrs); - - if (NULL == rrs->rrh) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } -} - - -/** - * Free the state from a "refresh reveal" CMD, and possibly - * cancel a pending operation thereof. - * - * @param cls closure. - * @param cmd the command which is being cleaned up. - */ -static void -refresh_reveal_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct RefreshRevealState *rrs = cls; - - if (NULL != rrs->rrh) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Command %u (%s) did not complete\n", - rrs->is->ip, - cmd->label); - - TALER_EXCHANGE_refresh_reveal_cancel (rrs->rrh); - rrs->rrh = NULL; - } - if (NULL != rrs->retry_task) - { - GNUNET_SCHEDULER_cancel (rrs->retry_task); - rrs->retry_task = NULL; - } - - for (unsigned int j=0; j < rrs->num_fresh_coins; j++) - GNUNET_CRYPTO_rsa_signature_free (rrs->fresh_coins[j].sig.rsa_signature); - - GNUNET_free_non_null (rrs->fresh_coins); - rrs->fresh_coins = NULL; - rrs->num_fresh_coins = 0; - GNUNET_free (rrs); -} - - -/** - * Run the command. - * - * @param cls closure. - * @param cmd the command to execute. - * @param is the interpreter state. - */ -static void -refresh_link_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is); - - -/** - * Task scheduled to re-try #refresh_link_run. - * - * @param cls a `struct RefreshLinkState` - */ -static void -do_link_retry (void *cls) -{ - struct RefreshLinkState *rls = cls; - - rls->retry_task = NULL; - refresh_link_run (rls, - NULL, - rls->is); -} - - -/** - * "refresh link" operation callback, checks that HTTP response - * code is expected _and_ that all the linked coins were actually - * withdrawn by the "refresh reveal" CMD. - * - * @param cls closure. - * @param http_status HTTP response code. - * @param ec taler-specific error code - * @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 full_response raw response from the exchange. - */ -static void -link_cb (void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - unsigned int num_coins, - const struct TALER_CoinSpendPrivateKeyP *coin_privs, - const struct TALER_DenominationSignature *sigs, - const struct TALER_DenominationPublicKey *pubs, - const json_t *full_response) -{ - - struct RefreshLinkState *rls = cls; - 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; - - rls->rlh = NULL; - if (rls->expected_response_code != http_status) - { - if (GNUNET_YES == rls->do_retry) - { - if ( (0 == http_status) || - (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) || - (MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Retrying refresh link 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) - rls->backoff = GNUNET_TIME_UNIT_ZERO; - else - rls->backoff = EXCHANGE_LIB_BACKOFF (rls->backoff); - 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", - http_status, - (int) ec, - link_cmd->label, - __FILE__, - __LINE__); - json_dumpf (full_response, stderr, 0); - TALER_TESTING_interpreter_fail (rls->is); - return; - } - reveal_cmd = TALER_TESTING_interpreter_lookup_command - (rls->is, rls->reveal_reference); - - if (NULL == reveal_cmd) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rls->is); - return; - } - - switch (http_status) - { - 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)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rls->is); - return; - } - if (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, - *num_fresh_coins, - __FILE__, - __LINE__); - TALER_TESTING_interpreter_fail (rls->is); - return; - } - /* check that the coins match */ - for (unsigned int i=0;iis); - return; - } - - for (unsigned int i=0;ikey.rsa_public_key, - pubs[j].rsa_public_key)) ) - { - found++; - break; - } - } - if (found != num_coins) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Only %u/%u coins match expectations\n", - found, num_coins); - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rls->is); - return; - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unknown HTTP response code %u.\n", - http_status); - } - TALER_TESTING_interpreter_next (rls->is); -} - - -/** - * Run the command. - * - * @param cls closure. - * @param cmd the command to execute. - * @param is the interpreter state. - */ -static void -refresh_link_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct RefreshLinkState *rls = cls; - struct RefreshRevealState *rrs; - struct RefreshMeltState *rms; - const struct TALER_TESTING_Command *reveal_cmd; - const struct TALER_TESTING_Command *melt_cmd; - const struct TALER_TESTING_Command *coin_cmd; - rls->is = is; - - reveal_cmd = TALER_TESTING_interpreter_lookup_command - (rls->is, rls->reveal_reference); - - if (NULL == reveal_cmd) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rls->is); - return; - } - rrs = reveal_cmd->cls; - melt_cmd = TALER_TESTING_interpreter_lookup_command - (rls->is, rrs->melt_reference); - - if (NULL == melt_cmd) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rls->is); - return; - } - - /* 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); - if (NULL == coin_cmd) - { - 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)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rls->is); - return; - } - - /* finally, use private key from withdraw sign command */ - rls->rlh = TALER_EXCHANGE_refresh_link - (is->exchange, coin_priv, &link_cb, rls); - - if (NULL == rls->rlh) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rls->is); - return; - } -} - - -/** - * Free the state of the "refresh link" CMD, and possibly - * cancel a operation thereof. - * - * @param cls closure - * @param cmd the command which is being cleaned up. - */ -static void -refresh_link_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct RefreshLinkState *rls = cls; - - if (NULL != rls->rlh) - { - - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Command %u (%s) did not complete\n", - rls->is->ip, - cmd->label); - TALER_EXCHANGE_refresh_link_cancel (rls->rlh); - rls->rlh = NULL; - } - if (NULL != rls->retry_task) - { - GNUNET_SCHEDULER_cancel (rls->retry_task); - rls->retry_task = NULL; - } - GNUNET_free (rls); -} - - -/** - * Run the command. - * - * @param cls closure. - * @param cmd the command to execute. - * @param is the interpreter state. - */ -static void -refresh_melt_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is); - - -/** - * Task scheduled to re-try #refresh_melt_run. - * - * @param cls a `struct RefreshMeltState` - */ -static void -do_melt_retry (void *cls) -{ - struct RefreshMeltState *rms = cls; - - rms->retry_task = NULL; - refresh_melt_run (rms, - NULL, - rms->is); -} - - -/** - * Callback for a "refresh melt" operation; checks if the HTTP - * response code is okay and re-run the melt operation if the - * CMD was set to do so. - * - * @param cls closure. - * @param http_status HTTP response code. - * @param ec taler-specific error code. - * @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 full_response raw response body from the exchange. - */ -static void -melt_cb (void *cls, - unsigned int http_status, - enum TALER_ErrorCode ec, - uint32_t noreveal_index, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const json_t *full_response) -{ - struct RefreshMeltState *rms = cls; - - rms->rmh = NULL; - if (rms->expected_response_code != http_status) - { - if (GNUNET_YES == rms->do_retry) - { - if ( (0 == http_status) || - (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) || - (MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Retrying refresh melt 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) - rms->backoff = GNUNET_TIME_UNIT_ZERO; - else - rms->backoff = EXCHANGE_LIB_BACKOFF (rms->backoff); - 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", - http_status, - (int) ec, - rms->is->commands[rms->is->ip].label, - __FILE__, - __LINE__); - json_dumpf (full_response, stderr, 0); - TALER_TESTING_interpreter_fail (rms->is); - return; - } - rms->noreveal_index = noreveal_index; - - if (GNUNET_YES == rms->double_melt) - { - TALER_LOG_DEBUG ("Doubling the melt (%s)\n", - rms->is->commands[rms->is->ip].label); - rms->rmh = TALER_EXCHANGE_refresh_melt - (rms->is->exchange, rms->refresh_data_length, - rms->refresh_data, &melt_cb, rms); - rms->double_melt = GNUNET_NO; - return; - } - TALER_TESTING_interpreter_next (rms->is); -} - - -/** - * Run the command. - * - * @param cls closure. - * @param cmd the command to execute. - * @param is the interpreter state. - */ -static void -refresh_melt_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct RefreshMeltState *rms = cls; - unsigned int num_fresh_coins; - const struct TALER_TESTING_Command *coin_command; - /* FIXME: this should be dynamic */ - const char *melt_fresh_amounts[] = { - "EUR:1", "EUR:1", "EUR:1", "EUR:0.1", - NULL}; - const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk; - - rms->is = is; - rms->noreveal_index = UINT16_MAX; - for (num_fresh_coins=0; - NULL != melt_fresh_amounts[num_fresh_coins]; - num_fresh_coins++) ; - - rms->fresh_pks = GNUNET_new_array - (num_fresh_coins, - struct TALER_EXCHANGE_DenomPublicKey); - { - const struct TALER_CoinSpendPrivateKeyP *melt_priv; - struct TALER_Amount melt_amount; - struct TALER_Amount fresh_amount; - const struct TALER_DenominationSignature *melt_sig; - const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub; - - const struct MeltDetails *md = &rms->melted_coin; - if (NULL == (coin_command - = TALER_TESTING_interpreter_lookup_command - (is, md->coin_reference))) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rms->is); - return; - } - - if (GNUNET_OK != TALER_TESTING_get_trait_coin_priv - (coin_command, 0, &melt_priv)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rms->is); - return; - } - - 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)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rms->is); - return; - } - 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; - } - - for (unsigned int i=0;iis); - return; - } - fresh_pk = TALER_TESTING_find_pk - (TALER_EXCHANGE_get_keys (is->exchange), &fresh_amount); - if (NULL == fresh_pk) - { - GNUNET_break (0); - /* Subroutine logs specific error */ - TALER_TESTING_interpreter_fail (rms->is); - return; - } - - rms->fresh_pks[i] = *fresh_pk; - } - rms->refresh_data = TALER_EXCHANGE_refresh_prepare - (melt_priv, &melt_amount, melt_sig, melt_denom_pub, - GNUNET_YES, num_fresh_coins, rms->fresh_pks, - &rms->refresh_data_length); - - if (NULL == rms->refresh_data) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rms->is); - return; - } - rms->rmh = TALER_EXCHANGE_refresh_melt - (is->exchange, rms->refresh_data_length, - rms->refresh_data, &melt_cb, rms); - - if (NULL == rms->rmh) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (rms->is); - return; - } - } -} - - -/** - * Free the "refresh melt" CMD state, and possibly cancel a - * pending operation thereof. - * - * @param cls closure, typically a #struct RefreshMeltState. - * @param cmd the command which is being cleaned up. - */ -static void -refresh_melt_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct RefreshMeltState *rms = cls; - - 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_EXCHANGE_refresh_melt_cancel (rms->rmh); - rms->rmh = NULL; - } - if (NULL != rms->retry_task) - { - GNUNET_SCHEDULER_cancel (rms->retry_task); - rms->retry_task = NULL; - } - GNUNET_free_non_null (rms->fresh_pks); - rms->fresh_pks = NULL; - GNUNET_free_non_null (rms->refresh_data); - rms->refresh_data = NULL; - rms->refresh_data_length = 0; - GNUNET_free (rms); -} - - -/** - * Offer internal data to the "refresh melt" CMD. - * - * @param cls closure. - * @param ret[out] result (could be anything). - * @param trait name of the trait. - * @param index index number of the object to offer. - * - * @return #GNUNET_OK on success. - */ -static int -refresh_melt_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - struct RefreshMeltState *rms = cls; - - struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_denom_pub (0, rms->fresh_pks), - TALER_TESTING_trait_end () - }; - - return TALER_TESTING_get_trait (traits, - ret, - trait, - index); -} - - -/** - * 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. - * - * @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) -{ - struct RefreshMeltState *rms; - struct MeltDetails md; - - md.coin_reference = coin_reference; - md.amount = amount; - - rms = GNUNET_new (struct RefreshMeltState); - rms->melted_coin = md; - rms->expected_response_code = expected_response_code; - - struct TALER_TESTING_Command cmd = { - .label = label, - .cls = rms, - .run = &refresh_melt_run, - .cleanup = &refresh_melt_cleanup, - .traits = &refresh_melt_traits - }; - - return cmd; -} - - -/** - * 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 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 - * - * @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) -{ - struct RefreshMeltState *rms; - struct MeltDetails md; - - md.coin_reference = coin_reference; - md.amount = amount; - - rms = GNUNET_new (struct RefreshMeltState); - rms->melted_coin = md; - rms->expected_response_code = expected_response_code; - rms->double_melt = GNUNET_YES; - - struct TALER_TESTING_Command cmd = { - .label = label, - .cls = rms, - .run = &refresh_melt_run, - .cleanup = &refresh_melt_cleanup, - .traits = &refresh_melt_traits - }; - - return cmd; -} - - -/** - * Modify a "refresh melt" command to enable retries. - * - * @param cmd command - * @return modified command. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_refresh_melt_with_retry (struct TALER_TESTING_Command cmd) -{ - struct RefreshMeltState *rms; - - GNUNET_assert (&refresh_melt_run == cmd.run); - rms = cmd.cls; - rms->do_retry = GNUNET_YES; - return cmd; -} - - -/** - * Offer internal data from a "refresh reveal" CMD. - * - * @param cls closure. - * @param ret[out] result (could be anything). - * @param trait name of the trait. - * @param index index number of the object to offer. - * - * @return #GNUNET_OK on success. - */ -static int -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 * 3) + 3) - struct TALER_TESTING_Trait traits[NUM_TRAITS]; - - /* Making coin privs traits */ - for (unsigned int i=0; ifresh_coins[i].coin_priv); - - /* Making denom pubs traits */ - for (unsigned int i=0; ifresh_coins[i].pk); - - /* Making denom sigs traits */ - for (unsigned int i=0; ifresh_coins[i].sig); - - /* number of fresh coins */ - traits[(num_coins * 3)] = TALER_TESTING_make_trait_uint - (0, &rrs->num_fresh_coins); - - /* whole array of fresh coins */ - traits[(num_coins * 3) + 1] - = TALER_TESTING_make_trait_fresh_coins (0, rrs->fresh_coins), - - /* end of traits */ - traits[(num_coins * 3) + 2] = TALER_TESTING_trait_end (); - - return TALER_TESTING_get_trait (traits, - ret, - trait, - index); -} - - -/** - * Create a "refresh reveal" command. - * - * @param label command label. - * @param exchange connection to the exchange. - * @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, - unsigned int expected_response_code) -{ - struct RefreshRevealState *rrs; - - rrs = GNUNET_new (struct RefreshRevealState); - rrs->melt_reference = melt_reference; - rrs->expected_response_code = expected_response_code; - - struct TALER_TESTING_Command cmd = { - .cls = rrs, - .label = label, - .run = &refresh_reveal_run, - .cleanup = &refresh_reveal_cleanup, - .traits = &refresh_reveal_traits - }; - - return cmd; -} - - -/** - * 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) -{ - struct RefreshRevealState *rrs; - - GNUNET_assert (&refresh_reveal_run == cmd.run); - rrs = cmd.cls; - rrs->do_retry = GNUNET_YES; - return 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, - unsigned int expected_response_code) -{ - struct RefreshLinkState *rrs; - - rrs = GNUNET_new (struct RefreshLinkState); - rrs->reveal_reference = reveal_reference; - rrs->expected_response_code = expected_response_code; - - struct TALER_TESTING_Command cmd = { - .cls = rrs, - .label = label, - .run = &refresh_link_run, - .cleanup = &refresh_link_cleanup - }; - - return cmd; -} - - -/** - * 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) -{ - struct RefreshLinkState *rls; - - GNUNET_assert (&refresh_link_run == cmd.run); - rls = cmd.cls; - rls->do_retry = GNUNET_YES; - return cmd; -} -- cgit v1.2.3