From 32a3a0ffb04487fbd1025cdddbf1ff47d0b2b7b5 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 18 Apr 2019 14:38:24 +0200 Subject: add post HTTP request check for hanging transactions --- src/exchange/taler-exchange-httpd.c | 6 +++ src/exchange/taler-exchange-httpd_db.c | 30 +++++++-------- src/exchange/taler-exchange-httpd_deposit.c | 58 ++++++++++++++--------------- src/exchangedb/plugin_exchangedb_postgres.c | 36 +++++++++--------- 4 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 4813f9215..8f86bf798 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -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)); + } diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 579f0620b..1f47f8e1a 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -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; } diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 0cc16c254..530cff770 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -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); } diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index aabdfbbb9..82308ea86 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -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; -- cgit v1.2.3