getting revocation/payback test with refreshed coins to pass
This commit is contained in:
parent
80ff186648
commit
9e3f4bdd79
@ -305,6 +305,7 @@ payback_transaction (void *cls,
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_get_zero (pc->value.currency,
|
||||
&spent));
|
||||
|
@ -556,7 +556,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
GNUNET_break_op (0);
|
||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||
TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE,
|
||||
"new_denoms");
|
||||
"new_denoms_h");
|
||||
|
||||
}
|
||||
if (json_array_size (new_denoms_h_json) !=
|
||||
@ -640,7 +640,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
TEH_KS_release (key_state);
|
||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||
TALER_EC_REFRESH_REVEAL_FRESH_DENOMINATION_KEY_NOT_FOUND,
|
||||
"new_denoms");
|
||||
"new_denoms_h");
|
||||
}
|
||||
GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key);
|
||||
}
|
||||
@ -674,7 +674,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
/* lookup old_coin_pub in database */
|
||||
{
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
(qs = TEH_plugin->get_melt (TEH_plugin->cls,
|
||||
NULL,
|
||||
@ -725,7 +725,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
ldp.purpose.size = htonl (sizeof (ldp));
|
||||
ldp.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK);
|
||||
ldp.h_denom_pub = dki_h[i];
|
||||
ldp.old_coin_pub = refresh_melt.session.coin.coin_pub;
|
||||
ldp.old_coin_pub = refresh_melt.session.coin.coin_pub;
|
||||
ldp.transfer_pub = rctx->gamma_tp;
|
||||
GNUNET_CRYPTO_hash (rcds[i].coin_ev,
|
||||
rcds[i].coin_ev_size,
|
||||
@ -744,7 +744,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rctx->num_fresh_coins = num_fresh_coins;
|
||||
rctx->rcds = rcds;
|
||||
rctx->dkis = dkis;
|
||||
|
@ -286,7 +286,7 @@ withdraw_transaction (void *cls,
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
*mhd_ret = reply_reserve_withdraw_insufficient_funds (connection,
|
||||
rh);
|
||||
rh);
|
||||
TEH_plugin->free_reserve_history (TEH_plugin->cls,
|
||||
rh);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
@ -319,8 +319,8 @@ withdraw_transaction (void *cls,
|
||||
wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope;
|
||||
wc->collectable.reserve_sig = wc->signature;
|
||||
qs = TEH_plugin->insert_withdraw_info (TEH_plugin->cls,
|
||||
session,
|
||||
&wc->collectable);
|
||||
session,
|
||||
&wc->collectable);
|
||||
if (0 > qs)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
|
@ -2593,8 +2593,8 @@ postgres_insert_withdraw_info (void *cls,
|
||||
now = GNUNET_TIME_absolute_get ();
|
||||
(void) GNUNET_TIME_round_abs (&now);
|
||||
qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
|
||||
"insert_withdraw_info",
|
||||
params);
|
||||
"insert_withdraw_info",
|
||||
params);
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
@ -2627,6 +2627,9 @@ postgres_insert_withdraw_info (void *cls,
|
||||
TALER_B2S (&collectable->reserve_pub));
|
||||
return GNUNET_DB_STATUS_SOFT_ERROR;
|
||||
}
|
||||
/* FIXME: idle_reserve_expiration_time is not a good value here,
|
||||
we should base this on the LEGAL expiration time of coins
|
||||
as we need reserve data for payback! */
|
||||
expiry = GNUNET_TIME_absolute_add (now,
|
||||
pg->idle_reserve_expiration_time);
|
||||
reserve.expiry = GNUNET_TIME_absolute_max (expiry,
|
||||
@ -7721,11 +7724,12 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_time (cfg,
|
||||
"exchangedb",
|
||||
"IDLE_RESERVE_EXPIRATION_TIME",
|
||||
&pg->idle_reserve_expiration_time))
|
||||
"exchangedb",
|
||||
"IDLE_RESERVE_EXPIRATION_TIME",
|
||||
&pg->idle_reserve_expiration_time))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"exchangedb",
|
||||
|
@ -511,6 +511,7 @@ TALER_EXCHANGE_get_signing_key_details (const struct TALER_EXCHANGE_Keys *keys,
|
||||
const char *
|
||||
TALER_EXCHANGE_get_base_url (const struct TALER_EXCHANGE_Handle *exchange);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the denomination key details from the exchange.
|
||||
*
|
||||
|
@ -131,6 +131,7 @@ TALER_TESTING_cert_cb
|
||||
const struct TALER_EXCHANGE_Keys *keys,
|
||||
enum TALER_EXCHANGE_VersionCompatibility compat);
|
||||
|
||||
|
||||
/**
|
||||
* Wait for the exchange to have started. Waits for at
|
||||
* most 10s, after that returns 77 to indicate an error.
|
||||
@ -1108,19 +1109,18 @@ TALER_TESTING_cmd_deposit_with_retry
|
||||
* 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.
|
||||
*
|
||||
* @param ... NULL-terminated list of amounts to be melted
|
||||
* @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);
|
||||
unsigned int expected_response_code,
|
||||
...);
|
||||
|
||||
|
||||
/**
|
||||
@ -1129,19 +1129,18 @@ TALER_TESTING_cmd_refresh_melt
|
||||
* request, see #5312.
|
||||
*
|
||||
* @param label command label
|
||||
* @param amount FIXME not used.
|
||||
* @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_refresh_melt_double
|
||||
(const char *label,
|
||||
const char *amount,
|
||||
const char *coin_reference,
|
||||
unsigned int expected_response_code);
|
||||
unsigned int expected_response_code,
|
||||
...);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -192,8 +192,8 @@ TESTS = \
|
||||
$(check_PROGRAMS)
|
||||
|
||||
# expected to fail for now: test incomplete, feature not implemented!
|
||||
XFAIL_TESTS = \
|
||||
test_exchange_api_revocation
|
||||
#XFAIL_TESTS = \
|
||||
# test_exchange_api_revocation
|
||||
|
||||
test_exchange_api_SOURCES = \
|
||||
test_exchange_api.c
|
||||
|
@ -1518,11 +1518,11 @@ handle_refresh_reveal_finished (void *cls,
|
||||
*/
|
||||
struct TALER_EXCHANGE_RefreshRevealHandle *
|
||||
TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
|
||||
size_t refresh_data_length,
|
||||
const char *refresh_data,
|
||||
uint32_t noreveal_index,
|
||||
TALER_EXCHANGE_RefreshRevealCallback reveal_cb,
|
||||
void *reveal_cb_cls)
|
||||
size_t refresh_data_length,
|
||||
const char *refresh_data,
|
||||
uint32_t noreveal_index,
|
||||
TALER_EXCHANGE_RefreshRevealCallback reveal_cb,
|
||||
void *reveal_cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_RefreshRevealHandle *rrh;
|
||||
json_t *transfer_privs;
|
||||
@ -1535,15 +1535,6 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct MeltData *md;
|
||||
struct TALER_TransferPublicKeyP transfer_pub;
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
md = deserialize_melt_data (refresh_data,
|
||||
refresh_data_length);
|
||||
if (NULL == md)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
if (noreveal_index >= TALER_CNC_KAPPA)
|
||||
{
|
||||
/* We check this here, as it would be really bad to below just
|
||||
@ -1553,6 +1544,19 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
md = deserialize_melt_data (refresh_data,
|
||||
refresh_data_length);
|
||||
if (NULL == md)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* now transfer_pub */
|
||||
GNUNET_CRYPTO_ecdhe_key_get_public (&md->melted_coin.transfer_priv[noreveal_index].ecdhe_priv,
|
||||
|
@ -231,9 +231,9 @@ run (void *cls,
|
||||
* Melt the rest of the coin's value (EUR:4.00 = 3x EUR:1.03 + 7x
|
||||
* EUR:0.13) */
|
||||
TALER_TESTING_cmd_refresh_melt_double ("refresh-melt-1",
|
||||
"EUR:4",
|
||||
"refresh-withdraw-coin-1",
|
||||
MHD_HTTP_OK),
|
||||
MHD_HTTP_OK,
|
||||
NULL),
|
||||
/**
|
||||
* Complete (successful) melt operation, and withdraw the coins
|
||||
*/
|
||||
|
@ -309,8 +309,10 @@ run (void *cls,
|
||||
* Melt the rest of the coin's value
|
||||
* (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
|
||||
TALER_TESTING_cmd_refresh_melt_double
|
||||
("refresh-melt-1", "EUR:4",
|
||||
"refresh-withdraw-coin-1", MHD_HTTP_OK),
|
||||
("refresh-melt-1",
|
||||
"refresh-withdraw-coin-1",
|
||||
MHD_HTTP_OK,
|
||||
NULL),
|
||||
/**
|
||||
* Complete (successful) melt operation, and
|
||||
* withdraw the coins
|
||||
@ -360,8 +362,10 @@ run (void *cls,
|
||||
/* Test running a failing melt operation (same operation
|
||||
* again must fail) */
|
||||
TALER_TESTING_cmd_refresh_melt
|
||||
("refresh-melt-failing", "EUR:4",
|
||||
"refresh-withdraw-coin-1", MHD_HTTP_FORBIDDEN),
|
||||
("refresh-melt-failing",
|
||||
"refresh-withdraw-coin-1",
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
NULL),
|
||||
|
||||
/* FIXME: also test with coin that was already melted
|
||||
* (signature differs from coin that was deposited...) */
|
||||
|
@ -142,11 +142,13 @@ run (void *cls,
|
||||
\"value\":\"EUR:1\"}]}",
|
||||
GNUNET_TIME_UNIT_ZERO, "EUR:1", MHD_HTTP_OK),
|
||||
/**
|
||||
* Melt the rest of the coin's value
|
||||
* (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
|
||||
TALER_TESTING_cmd_refresh_melt_double
|
||||
("refresh-melt-1", "EUR:4",
|
||||
"withdraw-coin-1", MHD_HTTP_OK),
|
||||
* Melt SOME of the rest of the coin's value
|
||||
* (EUR:3.17 = 3x EUR:1.03 + 7x EUR:0.13) */
|
||||
TALER_TESTING_cmd_refresh_melt
|
||||
("refresh-melt-1",
|
||||
"withdraw-coin-1",
|
||||
MHD_HTTP_OK,
|
||||
NULL),
|
||||
/**
|
||||
* Complete (successful) melt operation, and withdraw the coins
|
||||
*/
|
||||
@ -174,45 +176,49 @@ run (void *cls,
|
||||
"refresh-reveal-1#2",
|
||||
"EUR:1",
|
||||
"refresh-melt-1"),
|
||||
/* Melt original coin AGAIN (FIXME: this command
|
||||
is simply WRONG as it neither matches
|
||||
the EUR:3 that were paid back NOR is melt_double
|
||||
precisely right here!) -- it always tries to MELT EUR:4, which is too much! */
|
||||
TALER_TESTING_cmd_refresh_melt_double
|
||||
("refresh-melt-2", "EUR:3",
|
||||
"withdraw-coin-1", MHD_HTTP_OK),
|
||||
/* Now we have EUR:3.83 EUR back after 3x EUR:1 in paybacks */
|
||||
/* Melt original coin AGAIN, but only create one 0.1 EUR coin;
|
||||
This costs EUR:0.03 in refresh and EUR:01 in withdraw fees,
|
||||
leaving EUR:3.69. */
|
||||
TALER_TESTING_cmd_refresh_melt
|
||||
("refresh-melt-2",
|
||||
"withdraw-coin-1",
|
||||
MHD_HTTP_OK,
|
||||
"EUR:0.1",
|
||||
NULL),
|
||||
/**
|
||||
* Complete (successful) melt operation, and withdraw the coins
|
||||
*/
|
||||
TALER_TESTING_cmd_refresh_reveal
|
||||
("refresh-reveal-2",
|
||||
"refresh-melt-2", MHD_HTTP_OK),
|
||||
/* Make refreshed coin invalid */
|
||||
/* Revokes refreshed EUR:0.1 coin */
|
||||
TALER_TESTING_cmd_revoke ("revoke-2",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-2",
|
||||
CONFIG_FILE),
|
||||
/* Make also original coin invalid */
|
||||
/* Revoke also original coin denomination */
|
||||
TALER_TESTING_cmd_revoke ("revoke-3",
|
||||
MHD_HTTP_OK,
|
||||
"withdraw-coin-1",
|
||||
CONFIG_FILE),
|
||||
/* Refund coin to original coin */
|
||||
/* Refund coin EUR:0.1 to original coin, creating zombie! */
|
||||
TALER_TESTING_cmd_payback ("payback-2",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-melt-2",
|
||||
"EUR:1",
|
||||
"refresh-reveal-2",
|
||||
"EUR:0.1",
|
||||
"refresh-melt-2"),
|
||||
/* Refund original coin to reserve */
|
||||
/* Due to payback, original coin is now at EUR:3.79 */
|
||||
/* Refund original (now zombie) coin to reserve */
|
||||
TALER_TESTING_cmd_payback ("payback-3",
|
||||
MHD_HTTP_OK,
|
||||
"withdraw-coin-1",
|
||||
"EUR:1",
|
||||
"EUR:3.79",
|
||||
NULL),
|
||||
/* Check the money is back with the reserve */
|
||||
TALER_TESTING_cmd_status ("payback-reserve-status-1",
|
||||
"create-reserve-1",
|
||||
"EUR:1.0",
|
||||
"EUR:3.79",
|
||||
MHD_HTTP_OK),
|
||||
TALER_TESTING_cmd_end ()
|
||||
};
|
||||
|
@ -187,9 +187,9 @@ run (void *cls,
|
||||
* (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
|
||||
TALER_TESTING_cmd_refresh_melt
|
||||
("refresh-melt",
|
||||
"EUR:4",
|
||||
"refresh-withdraw-coin",
|
||||
MHD_HTTP_OK),
|
||||
MHD_HTTP_OK,
|
||||
NULL),
|
||||
|
||||
/* Trigger 409 Conflict. */
|
||||
TALER_TESTING_cmd_flip_upload
|
||||
|
@ -37,16 +37,6 @@
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@ -57,9 +47,10 @@ struct RefreshMeltState
|
||||
{
|
||||
|
||||
/**
|
||||
* Information about coins to be melted.
|
||||
* Reference to reserve_withdraw operations for coin to
|
||||
* be used for the /refresh/melt operation.
|
||||
*/
|
||||
struct MeltDetails melted_coin;
|
||||
const char *coin_reference;
|
||||
|
||||
/**
|
||||
* "Crypto data" used in the refresh operation.
|
||||
@ -107,6 +98,11 @@ struct RefreshMeltState
|
||||
*/
|
||||
size_t refresh_data_length;
|
||||
|
||||
/**
|
||||
* Amounts to be generated during melt.
|
||||
*/
|
||||
const char **melt_fresh_amounts;
|
||||
|
||||
/**
|
||||
* Number of fresh coins generated by the melt.
|
||||
*/
|
||||
@ -314,12 +310,12 @@ reveal_cb (void *cls,
|
||||
"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,
|
||||
/* 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;
|
||||
@ -691,12 +687,9 @@ refresh_link_run (void *cls,
|
||||
|
||||
/* 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);
|
||||
(rls->is, rms->coin_reference);
|
||||
if (NULL == coin_cmd)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -879,11 +872,14 @@ refresh_melt_run (void *cls,
|
||||
{
|
||||
struct RefreshMeltState *rms = cls;
|
||||
unsigned int num_fresh_coins;
|
||||
/* FIXME: this should be dynamic */
|
||||
const char *melt_fresh_amounts[] = {
|
||||
const char *default_melt_fresh_amounts[] = {
|
||||
"EUR:1", "EUR:1", "EUR:1", "EUR:0.1",
|
||||
NULL};
|
||||
NULL
|
||||
};
|
||||
const char **melt_fresh_amounts;
|
||||
|
||||
if (NULL == (melt_fresh_amounts = rms->melt_fresh_amounts))
|
||||
melt_fresh_amounts = default_melt_fresh_amounts;
|
||||
rms->is = is;
|
||||
rms->noreveal_index = UINT16_MAX;
|
||||
for (num_fresh_coins=0;
|
||||
@ -899,11 +895,10 @@ refresh_melt_run (void *cls,
|
||||
const struct TALER_DenominationSignature *melt_sig;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
|
||||
const struct TALER_TESTING_Command *coin_command;
|
||||
const struct MeltDetails *md = &rms->melted_coin;
|
||||
|
||||
if (NULL == (coin_command
|
||||
= TALER_TESTING_interpreter_lookup_command
|
||||
(is, md->coin_reference)))
|
||||
(is, rms->coin_reference)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (rms->is);
|
||||
@ -918,18 +913,6 @@ refresh_melt_run (void *cls,
|
||||
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,
|
||||
@ -946,6 +929,9 @@ refresh_melt_run (void *cls,
|
||||
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;
|
||||
for (unsigned int i=0;i<num_fresh_coins;i++)
|
||||
{
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk;
|
||||
@ -969,7 +955,14 @@ refresh_melt_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (rms->is);
|
||||
return;
|
||||
}
|
||||
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_add (&melt_amount,
|
||||
&melt_amount,
|
||||
&fresh_amount));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_add (&melt_amount,
|
||||
&melt_amount,
|
||||
&fresh_pk->fee_withdraw));
|
||||
rms->fresh_pks[i] = *fresh_pk;
|
||||
}
|
||||
rms->refresh_data = TALER_EXCHANGE_refresh_prepare
|
||||
@ -1028,6 +1021,7 @@ refresh_melt_cleanup (void *cls,
|
||||
GNUNET_free_non_null (rms->refresh_data);
|
||||
rms->refresh_data = NULL;
|
||||
rms->refresh_data_length = 0;
|
||||
GNUNET_free_non_null (rms->melt_fresh_amounts);
|
||||
GNUNET_free (rms);
|
||||
}
|
||||
|
||||
@ -1069,32 +1063,83 @@ refresh_melt_traits (void *cls,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse list of amounts for melt operation.
|
||||
*
|
||||
* @param rms[in,out] where to store the list
|
||||
* @param ap NULL-termianted list of amounts to be melted (one per fresh coin)
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
static int
|
||||
parse_amounts (struct RefreshMeltState *rms,
|
||||
va_list ap)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned int off;
|
||||
const char *amount;
|
||||
|
||||
len = 0;
|
||||
off = 0;
|
||||
while (NULL != (amount = va_arg (ap, const char *)))
|
||||
{
|
||||
if (len == off)
|
||||
{
|
||||
struct TALER_Amount a;
|
||||
|
||||
GNUNET_array_grow (rms->melt_fresh_amounts,
|
||||
len,
|
||||
off + 16);
|
||||
if (GNUNET_OK !=
|
||||
TALER_string_to_amount (amount, &a))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to parse amount `%s' at index %u\n",
|
||||
amount, off);
|
||||
GNUNET_free (rms->melt_fresh_amounts);
|
||||
rms->melt_fresh_amounts = NULL;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
rms->melt_fresh_amounts[off++] = amount;
|
||||
}
|
||||
}
|
||||
if (0 == off)
|
||||
return GNUNET_OK; /* no amounts given == use defaults! */
|
||||
/* ensure NULL-termination */
|
||||
GNUNET_array_grow (rms->melt_fresh_amounts,
|
||||
len,
|
||||
off + 1);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param ... NULL-terminated list of amounts to be melted
|
||||
* @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)
|
||||
unsigned int expected_response_code,
|
||||
...)
|
||||
{
|
||||
struct RefreshMeltState *rms;
|
||||
struct MeltDetails md;
|
||||
va_list ap;
|
||||
|
||||
md.coin_reference = coin_reference;
|
||||
md.amount = amount;
|
||||
rms = GNUNET_new (struct RefreshMeltState);
|
||||
rms->melted_coin = md;
|
||||
rms->coin_reference = coin_reference;
|
||||
rms->expected_response_code = expected_response_code;
|
||||
va_start (ap, expected_response_code);
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
parse_amounts (rms, ap));
|
||||
va_end (ap);
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
.label = label,
|
||||
@ -1116,28 +1161,30 @@ TALER_TESTING_cmd_refresh_melt
|
||||
*
|
||||
* @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
|
||||
* @param ... NULL-terminated list of amounts to be melted
|
||||
* @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)
|
||||
unsigned int expected_response_code,
|
||||
...)
|
||||
{
|
||||
struct RefreshMeltState *rms;
|
||||
struct MeltDetails md;
|
||||
va_list ap;
|
||||
|
||||
md.coin_reference = coin_reference;
|
||||
md.amount = amount;
|
||||
rms = GNUNET_new (struct RefreshMeltState);
|
||||
rms->melted_coin = md;
|
||||
rms->coin_reference = coin_reference;
|
||||
rms->expected_response_code = expected_response_code;
|
||||
rms->double_melt = GNUNET_YES;
|
||||
va_start (ap, expected_response_code);
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
parse_amounts (rms, ap));
|
||||
va_end (ap);
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
.label = label,
|
||||
|
Loading…
Reference in New Issue
Block a user