add post HTTP request check for hanging transactions
This commit is contained in:
parent
5d3ae9655e
commit
32a3a0ffb0
@ -146,6 +146,12 @@ handle_mhd_completion_callback (void *cls,
|
||||
return;
|
||||
TEH_PARSE_post_cleanup_callback (*con_cls);
|
||||
*con_cls = NULL;
|
||||
/* check that we didn't leave any transactions hanging */
|
||||
/* NOTE: In high-performance production, we might want to
|
||||
remove this. */
|
||||
TEH_plugin->preflight (TEH_plugin->cls,
|
||||
TEH_plugin->get_session (TEH_plugin->cls));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,9 +87,9 @@ TEH_DB_know_coin_transaction (void *cls,
|
||||
int
|
||||
TEH_DB_run_transaction (struct MHD_Connection *connection,
|
||||
const char *name,
|
||||
int *mhd_ret,
|
||||
TEH_DB_TransactionCallback cb,
|
||||
void *cb_cls)
|
||||
int *mhd_ret,
|
||||
TEH_DB_TransactionCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
|
||||
@ -100,7 +100,7 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
|
||||
GNUNET_break (0);
|
||||
if (NULL != mhd_ret)
|
||||
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_DB_SETUP_FAILED);
|
||||
TALER_EC_DB_SETUP_FAILED);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TEH_plugin->preflight (TEH_plugin->cls,
|
||||
@ -110,23 +110,23 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TEH_plugin->start (TEH_plugin->cls,
|
||||
session,
|
||||
TEH_plugin->start (TEH_plugin->cls,
|
||||
session,
|
||||
name))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
if (NULL != mhd_ret)
|
||||
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_DB_START_FAILED);
|
||||
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_DB_START_FAILED);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
qs = cb (cb_cls,
|
||||
connection,
|
||||
session,
|
||||
mhd_ret);
|
||||
connection,
|
||||
session,
|
||||
mhd_ret);
|
||||
if (0 > qs)
|
||||
TEH_plugin->rollback (TEH_plugin->cls,
|
||||
session);
|
||||
session);
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
return GNUNET_SYSERR;
|
||||
if (0 <= qs)
|
||||
@ -135,13 +135,13 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
{
|
||||
if (NULL != mhd_ret)
|
||||
*mhd_ret = TEH_RESPONSE_reply_commit_error (connection,
|
||||
TALER_EC_DB_COMMIT_FAILED_HARD);
|
||||
*mhd_ret = TEH_RESPONSE_reply_commit_error (connection,
|
||||
TALER_EC_DB_COMMIT_FAILED_HARD);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
/* make sure callback did not violate invariants! */
|
||||
GNUNET_assert ( (NULL == mhd_ret) ||
|
||||
(-1 == *mhd_ret) );
|
||||
(-1 == *mhd_ret) );
|
||||
if (0 <= qs)
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
@ -130,9 +130,9 @@ struct DepositContext
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
deposit_transaction (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
int *mhd_ret)
|
||||
struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
int *mhd_ret)
|
||||
{
|
||||
struct DepositContext *dc = cls;
|
||||
const struct TALER_EXCHANGEDB_Deposit *deposit = dc->deposit;
|
||||
@ -141,8 +141,8 @@ deposit_transaction (void *cls,
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
qs = TEH_plugin->have_deposit (TEH_plugin->cls,
|
||||
session,
|
||||
deposit,
|
||||
session,
|
||||
deposit,
|
||||
GNUNET_YES /* check refund deadline */);
|
||||
if (qs < 0)
|
||||
{
|
||||
@ -159,19 +159,19 @@ deposit_transaction (void *cls,
|
||||
struct TALER_Amount amount_without_fee;
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"/deposit replay, accepting again!\n");
|
||||
"/deposit replay, accepting again!\n");
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_subtract (&amount_without_fee,
|
||||
&deposit->amount_with_fee,
|
||||
&deposit->deposit_fee));
|
||||
*mhd_ret = reply_deposit_success (connection,
|
||||
&deposit->coin.coin_pub,
|
||||
&deposit->h_wire,
|
||||
&deposit->h_contract_terms,
|
||||
deposit->timestamp,
|
||||
deposit->refund_deadline,
|
||||
&deposit->merchant_pub,
|
||||
&amount_without_fee);
|
||||
&deposit->coin.coin_pub,
|
||||
&deposit->h_wire,
|
||||
&deposit->h_contract_terms,
|
||||
deposit->timestamp,
|
||||
deposit->refund_deadline,
|
||||
&deposit->merchant_pub,
|
||||
&amount_without_fee);
|
||||
/* Treat as 'hard' DB error as we want to rollback and
|
||||
never try again. */
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
@ -184,13 +184,13 @@ deposit_transaction (void *cls,
|
||||
session,
|
||||
&deposit->coin.coin_pub,
|
||||
GNUNET_NO,
|
||||
&tl);
|
||||
&tl);
|
||||
if (0 > qs)
|
||||
return qs;
|
||||
if (GNUNET_OK !=
|
||||
TEH_DB_calculate_transaction_list_totals (tl,
|
||||
&spent,
|
||||
&spent))
|
||||
&spent,
|
||||
&spent))
|
||||
{
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
@ -239,7 +239,7 @@ deposit_transaction (void *cls,
|
||||
*/
|
||||
static int
|
||||
verify_and_execute_deposit (struct MHD_Connection *connection,
|
||||
const struct TALER_EXCHANGEDB_Deposit *deposit)
|
||||
const struct TALER_EXCHANGEDB_Deposit *deposit)
|
||||
{
|
||||
struct TALER_DepositRequestPS dr;
|
||||
int mhd_ret;
|
||||
@ -269,7 +269,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
|
||||
{
|
||||
TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
|
||||
return TEH_RESPONSE_reply_signature_invalid (connection,
|
||||
TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID,
|
||||
TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID,
|
||||
"coin_sig");
|
||||
}
|
||||
|
||||
@ -284,7 +284,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
|
||||
}
|
||||
dki = TEH_KS_denomination_key_lookup (mks,
|
||||
&deposit->coin.denom_pub,
|
||||
TEH_KS_DKU_DEPOSIT);
|
||||
TEH_KS_DKU_DEPOSIT);
|
||||
if (NULL == dki)
|
||||
{
|
||||
TEH_KS_release (mks);
|
||||
@ -300,9 +300,9 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
|
||||
if (GNUNET_OK !=
|
||||
TEH_DB_run_transaction (connection,
|
||||
"execute deposit",
|
||||
&mhd_ret,
|
||||
&deposit_transaction,
|
||||
&dc))
|
||||
&mhd_ret,
|
||||
&deposit_transaction,
|
||||
&dc))
|
||||
return mhd_ret;
|
||||
|
||||
/* generate regular response */
|
||||
@ -311,13 +311,13 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
|
||||
&deposit->amount_with_fee,
|
||||
&deposit->deposit_fee));
|
||||
return reply_deposit_success (connection,
|
||||
&deposit->coin.coin_pub,
|
||||
&deposit->h_wire,
|
||||
&deposit->h_contract_terms,
|
||||
deposit->timestamp,
|
||||
deposit->refund_deadline,
|
||||
&deposit->merchant_pub,
|
||||
&amount_without_fee);
|
||||
&deposit->coin.coin_pub,
|
||||
&deposit->h_wire,
|
||||
&deposit->h_contract_terms,
|
||||
deposit->timestamp,
|
||||
deposit->refund_deadline,
|
||||
&deposit->merchant_pub,
|
||||
&amount_without_fee);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1075,11 +1075,9 @@ postgres_prepare (PGconn *db_conn)
|
||||
",h_contract_terms"
|
||||
",h_wire"
|
||||
" FROM deposits"
|
||||
" WHERE ("
|
||||
" (coin_pub=$1)"
|
||||
" WHERE ((coin_pub=$1)"
|
||||
" AND (merchant_pub=$3)"
|
||||
" AND (h_contract_terms=$2)"
|
||||
" )"
|
||||
" AND (h_contract_terms=$2))"
|
||||
" FOR UPDATE;",
|
||||
3),
|
||||
/* Fetch deposits with rowid '\geq' the given parameter */
|
||||
@ -2893,15 +2891,15 @@ postgres_have_deposit (void *cls,
|
||||
struct TALER_EXCHANGEDB_Deposit deposit2;
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||
&deposit2.amount_with_fee),
|
||||
&deposit2.amount_with_fee),
|
||||
TALER_PQ_result_spec_absolute_time ("timestamp",
|
||||
&deposit2.timestamp),
|
||||
&deposit2.timestamp),
|
||||
TALER_PQ_result_spec_absolute_time ("refund_deadline",
|
||||
&deposit2.refund_deadline),
|
||||
&deposit2.refund_deadline),
|
||||
TALER_PQ_result_spec_absolute_time ("wire_deadline",
|
||||
&deposit2.wire_deadline),
|
||||
&deposit2.wire_deadline),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("h_wire",
|
||||
&deposit2.h_wire),
|
||||
&deposit2.h_wire),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
@ -2910,9 +2908,9 @@ postgres_have_deposit (void *cls,
|
||||
"Getting deposits for coin %s\n",
|
||||
TALER_B2S (&deposit->coin.coin_pub));
|
||||
qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
|
||||
"get_deposit",
|
||||
params,
|
||||
rs);
|
||||
"get_deposit",
|
||||
params,
|
||||
rs);
|
||||
if (0 >= qs)
|
||||
return qs;
|
||||
/* Now we check that the other information in @a deposit
|
||||
@ -3650,19 +3648,19 @@ postgres_get_melt (void *cls,
|
||||
};
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||
&refresh_melt->session.coin.denom_pub.rsa_public_key),
|
||||
&refresh_melt->session.coin.denom_pub.rsa_public_key),
|
||||
TALER_PQ_result_spec_amount ("fee_refresh",
|
||||
&refresh_melt->melt_fee),
|
||||
&refresh_melt->melt_fee),
|
||||
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
|
||||
&refresh_melt->session.coin.denom_sig.rsa_signature),
|
||||
&refresh_melt->session.coin.denom_sig.rsa_signature),
|
||||
GNUNET_PQ_result_spec_uint32 ("noreveal_index",
|
||||
&refresh_melt->session.noreveal_index),
|
||||
&refresh_melt->session.noreveal_index),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
|
||||
&refresh_melt->session.coin.coin_pub),
|
||||
&refresh_melt->session.coin.coin_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
|
||||
&refresh_melt->session.coin_sig),
|
||||
&refresh_melt->session.coin_sig),
|
||||
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||
&refresh_melt->session.amount_with_fee),
|
||||
&refresh_melt->session.amount_with_fee),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
Loading…
Reference in New Issue
Block a user