implement retries for a few more commands
This commit is contained in:
parent
1ee55ea838
commit
96c2fb8e10
@ -398,7 +398,9 @@ run (void *cls,
|
||||
create_reserve_label,
|
||||
AMOUNT_5,
|
||||
MHD_HTTP_OK));
|
||||
unit[1] = TALER_TESTING_cmd_deposit
|
||||
unit[1] =
|
||||
TALER_TESTING_cmd_deposit_with_retry
|
||||
(TALER_TESTING_cmd_deposit
|
||||
("deposit",
|
||||
is->exchange,
|
||||
withdraw_label,
|
||||
@ -409,7 +411,7 @@ run (void *cls,
|
||||
order_enc,
|
||||
GNUNET_TIME_UNIT_ZERO,
|
||||
AMOUNT_1,
|
||||
MHD_HTTP_OK);
|
||||
MHD_HTTP_OK));
|
||||
|
||||
if (eval_probability (REFRESH_PROBABILITY))
|
||||
{
|
||||
@ -424,22 +426,28 @@ run (void *cls,
|
||||
"refresh-reveal-%u-%u",
|
||||
i,
|
||||
j);
|
||||
unit[2] = TALER_TESTING_cmd_refresh_melt
|
||||
unit[2] =
|
||||
TALER_TESTING_cmd_refresh_melt_with_retry
|
||||
(TALER_TESTING_cmd_refresh_melt
|
||||
(melt_label,
|
||||
is->exchange,
|
||||
AMOUNT_4,
|
||||
withdraw_label,
|
||||
MHD_HTTP_OK);
|
||||
unit[3] = TALER_TESTING_cmd_refresh_reveal
|
||||
MHD_HTTP_OK));
|
||||
unit[3] =
|
||||
TALER_TESTING_cmd_refresh_reveal_with_retry
|
||||
(TALER_TESTING_cmd_refresh_reveal
|
||||
(reveal_label,
|
||||
is->exchange,
|
||||
melt_label,
|
||||
MHD_HTTP_OK);
|
||||
unit[4] = TALER_TESTING_cmd_refresh_link
|
||||
MHD_HTTP_OK));
|
||||
unit[4] =
|
||||
TALER_TESTING_cmd_refresh_link_with_retry
|
||||
(TALER_TESTING_cmd_refresh_link
|
||||
("refresh-link",
|
||||
is->exchange,
|
||||
reveal_label,
|
||||
MHD_HTTP_OK);
|
||||
MHD_HTTP_OK));
|
||||
unit[5] = TALER_TESTING_cmd_end ();
|
||||
}
|
||||
else
|
||||
|
@ -81,11 +81,6 @@ struct DepositState
|
||||
*/
|
||||
struct TALER_EXCHANGE_DepositHandle *dh;
|
||||
|
||||
/**
|
||||
* Expected HTTP response code.
|
||||
*/
|
||||
unsigned int expected_response_code;
|
||||
|
||||
/**
|
||||
* Interpreter state.
|
||||
*/
|
||||
@ -95,8 +90,60 @@ struct DepositState
|
||||
* Exchange connection.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* 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
|
||||
deposit_run (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd,
|
||||
struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
/**
|
||||
* Task scheduled to re-try #deposit_run.
|
||||
*
|
||||
* @param cls a `struct DepositState`
|
||||
*/
|
||||
static void
|
||||
do_retry (void *cls)
|
||||
{
|
||||
struct DepositState *ds = cls;
|
||||
|
||||
ds->retry_task = NULL;
|
||||
deposit_run (ds,
|
||||
NULL,
|
||||
ds->is);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback to analyze the /deposit response, just used to
|
||||
* check if the response code is acceptable.
|
||||
@ -120,6 +167,27 @@ deposit_cb (void *cls,
|
||||
ds->dh = NULL;
|
||||
if (ds->expected_response_code != http_status)
|
||||
{
|
||||
if (GNUNET_YES == ds->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 deposit 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)
|
||||
ds->backoff = GNUNET_TIME_UNIT_ZERO;
|
||||
else
|
||||
ds->backoff = GNUNET_TIME_STD_BACKOFF (ds->backoff);
|
||||
ds->retry_task = GNUNET_SCHEDULER_add_delayed (ds->backoff,
|
||||
&do_retry,
|
||||
ds);
|
||||
return;
|
||||
}
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u to command %s in %s:%u\n",
|
||||
http_status,
|
||||
@ -324,7 +392,11 @@ deposit_cleanup (void *cls,
|
||||
TALER_EXCHANGE_deposit_cancel (ds->dh);
|
||||
ds->dh = NULL;
|
||||
}
|
||||
|
||||
if (NULL != ds->retry_task)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (ds->retry_task);
|
||||
ds->retry_task = NULL;
|
||||
}
|
||||
json_decref (ds->wire_details);
|
||||
GNUNET_free (ds);
|
||||
}
|
||||
@ -441,3 +513,25 @@ TALER_TESTING_cmd_deposit
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Modify a deposit command to enable retries when we get transient
|
||||
* errors from the exchange.
|
||||
*
|
||||
* @param cmd a deposit command
|
||||
* @return the command with retries enabled
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_deposit_with_retry (struct TALER_TESTING_Command cmd)
|
||||
{
|
||||
struct DepositState *ds;
|
||||
|
||||
GNUNET_assert (&deposit_run == cmd.run);
|
||||
ds = cmd.cls;
|
||||
ds->do_retry = GNUNET_YES;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
/* end of testing_api_cmd_deposit.c */
|
||||
|
@ -55,19 +55,6 @@ struct MeltDetails
|
||||
struct RefreshMeltState
|
||||
{
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Information about coins to be melted.
|
||||
*/
|
||||
@ -78,11 +65,6 @@ struct RefreshMeltState
|
||||
*/
|
||||
char *refresh_data;
|
||||
|
||||
/**
|
||||
* Number of bytes in @e refresh_data.
|
||||
*/
|
||||
size_t refresh_data_length;
|
||||
|
||||
/**
|
||||
* Reference to a previous melt command.
|
||||
*/
|
||||
@ -103,16 +85,49 @@ struct RefreshMeltState
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Array of the denomination public keys
|
||||
* corresponding to the @e fresh_amounts.
|
||||
* 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.
|
||||
*/
|
||||
struct TALER_EXCHANGE_DenomPublicKey *fresh_pks;
|
||||
unsigned int double_melt;
|
||||
|
||||
/**
|
||||
* Should we retry on (transient) failures?
|
||||
*/
|
||||
int do_retry;
|
||||
|
||||
/**
|
||||
* Set by the melt callback as it comes from the exchange.
|
||||
@ -136,13 +151,6 @@ struct RefreshRevealState
|
||||
*/
|
||||
struct TALER_EXCHANGE_RefreshRevealHandle *rrh;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Convenience struct to keep in one place all the
|
||||
* data related to one fresh coin, set by the reveal callback
|
||||
@ -160,10 +168,33 @@ struct RefreshRevealState
|
||||
*/
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -192,13 +223,59 @@ struct RefreshLinkState
|
||||
*/
|
||||
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
|
||||
@ -231,6 +308,27 @@ reveal_cb (void *cls,
|
||||
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 = GNUNET_TIME_STD_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,
|
||||
@ -258,16 +356,18 @@ reveal_cb (void *cls,
|
||||
(num_coins, struct FreshCoin);
|
||||
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *fresh_pks;
|
||||
unsigned int i;
|
||||
if (GNUNET_OK != TALER_TESTING_get_trait_denom_pub
|
||||
(melt_cmd, 0, &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 (i=0; i<num_coins; i++)
|
||||
for (unsigned int i=0; i<num_coins; i++)
|
||||
{
|
||||
struct FreshCoin *fc = &rrs->fresh_coins[i];
|
||||
|
||||
@ -352,6 +452,11 @@ refresh_reveal_cleanup (void *cls,
|
||||
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);
|
||||
@ -362,6 +467,36 @@ refresh_reveal_cleanup (void *cls,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -402,6 +537,27 @@ link_cb (void *cls,
|
||||
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 = GNUNET_TIME_STD_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,
|
||||
@ -514,11 +670,9 @@ 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;
|
||||
@ -605,6 +759,41 @@ refresh_link_cleanup (void *cls,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
@ -634,6 +823,27 @@ melt_cb (void *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 = GNUNET_TIME_STD_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,
|
||||
@ -668,7 +878,7 @@ melt_cb (void *cls,
|
||||
* @param cmd the command to execute.
|
||||
* @param is the interpreter state.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
refresh_melt_run (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd,
|
||||
struct TALER_TESTING_Interpreter *is)
|
||||
@ -819,6 +1029,11 @@ refresh_melt_cleanup (void *cls,
|
||||
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);
|
||||
@ -894,10 +1109,10 @@ TALER_TESTING_cmd_refresh_melt
|
||||
cmd.run = &refresh_melt_run;
|
||||
cmd.cleanup = &refresh_melt_cleanup;
|
||||
cmd.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
|
||||
@ -938,10 +1153,28 @@ TALER_TESTING_cmd_refresh_melt_double
|
||||
cmd.run = &refresh_melt_run;
|
||||
cmd.cleanup = &refresh_melt_cleanup;
|
||||
cmd.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.
|
||||
*
|
||||
@ -960,23 +1193,22 @@ refresh_reveal_traits (void *cls,
|
||||
{
|
||||
struct RefreshRevealState *rrs = cls;
|
||||
unsigned int num_coins = rrs->num_fresh_coins;
|
||||
#define NUM_TRAITS (num_coins * 3) + 3
|
||||
#define NUM_TRAITS (num_coins * 3) + 3
|
||||
struct TALER_TESTING_Trait traits[NUM_TRAITS];
|
||||
unsigned int i;
|
||||
|
||||
/* Making coin privs traits */
|
||||
for (i=0; i<num_coins; i++)
|
||||
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 (i=0; i<num_coins; i++)
|
||||
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 (i=0; i<num_coins; i++)
|
||||
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);
|
||||
@ -998,6 +1230,7 @@ refresh_reveal_traits (void *cls,
|
||||
index);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a "refresh reveal" command.
|
||||
*
|
||||
@ -1028,7 +1261,24 @@ TALER_TESTING_cmd_refresh_reveal
|
||||
cmd.run = &refresh_reveal_run;
|
||||
cmd.cleanup = &refresh_reveal_cleanup;
|
||||
cmd.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;
|
||||
}
|
||||
|
||||
@ -1062,6 +1312,23 @@ TALER_TESTING_cmd_refresh_link
|
||||
cmd.label = label;
|
||||
cmd.run = &refresh_link_run;
|
||||
cmd.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;
|
||||
}
|
||||
|
@ -169,15 +169,16 @@ reserve_withdraw_cb (void *cls,
|
||||
{
|
||||
if (GNUNET_YES == ws->do_retry)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Retrying withdraw failed with %u/%d\n",
|
||||
http_status,
|
||||
(int) ec);
|
||||
if ( (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) ||
|
||||
if ( (0 == http_status) ||
|
||||
(TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) ||
|
||||
(TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS == ec) ||
|
||||
(TALER_EC_WITHDRAW_RESERVE_UNKNOWN == ec) ||
|
||||
(MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) )
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Retrying withdraw 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)
|
||||
ws->backoff = GNUNET_TIME_UNIT_ZERO;
|
||||
|
@ -835,6 +835,17 @@ TALER_TESTING_cmd_deposit
|
||||
unsigned int expected_response_code);
|
||||
|
||||
|
||||
/**
|
||||
* Modify a deposit command to enable retries when we get transient
|
||||
* errors from the exchange.
|
||||
*
|
||||
* @param cmd a deposit command
|
||||
* @return the command with retries enabled
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_deposit_with_retry (struct TALER_TESTING_Command cmd);
|
||||
|
||||
|
||||
/**
|
||||
* Create a "refresh melt" command.
|
||||
*
|
||||
@ -855,6 +866,7 @@ TALER_TESTING_cmd_refresh_melt
|
||||
const char *coin_reference,
|
||||
unsigned int expected_response_code);
|
||||
|
||||
|
||||
/**
|
||||
* Create a "refresh melt" CMD that does TWO /refresh/melt
|
||||
* requests. This was needed to test the replay of a valid melt
|
||||
@ -878,6 +890,16 @@ TALER_TESTING_cmd_refresh_melt_double
|
||||
unsigned int expected_response_code);
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
|
||||
/**
|
||||
* Create a "refresh reveal" command.
|
||||
*
|
||||
@ -896,6 +918,16 @@ TALER_TESTING_cmd_refresh_reveal
|
||||
unsigned int expected_response_code);
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
|
||||
/**
|
||||
* Create a "refresh link" command.
|
||||
*
|
||||
@ -914,6 +946,16 @@ TALER_TESTING_cmd_refresh_link
|
||||
unsigned int expected_response_code);
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
|
||||
/**
|
||||
* Create a "track transaction" command.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user