From c93f64710674bb4f635288c5e326f2cf47b8e8c7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 8 Jul 2020 18:20:44 +0200 Subject: merge known_coin transaction into main transaction (for #6416) --- src/exchange/taler-exchange-httpd_db.c | 40 ------------------------- src/exchange/taler-exchange-httpd_db.h | 38 ------------------------ src/exchange/taler-exchange-httpd_deposit.c | 34 +++++++++------------ src/exchange/taler-exchange-httpd_melt.c | 46 ++++++++++++++++------------- src/exchange/taler-exchange-httpd_recoup.c | 30 +++++++++---------- 5 files changed, 53 insertions(+), 135 deletions(-) (limited to 'src/exchange') diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 2e8f0a02e..dfef63c4c 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -40,46 +40,6 @@ #define MAX_TRANSACTION_COMMIT_RETRIES 100 -/** - * Execute database transaction to ensure coin is known. Run the transaction - * logic; IF it returns a non-error code, the transaction logic MUST - * NOT queue a MHD response. IF it returns an hard error, the - * transaction logic MUST queue a MHD response and set @a mhd_ret. IF - * it returns the soft error code, the function MAY be called again to - * retry and MUST not queue a MHD response. - * - * @param cls a `struct TEH_DB_KnowCoinContext` - * @param connection MHD request context, must not be NULL - * @param session database session and transaction to use - * @param[out] mhd_ret set to MHD status on error, must not be NULL - * @return transaction status - */ -enum GNUNET_DB_QueryStatus -TEH_DB_know_coin_transaction (void *cls, - struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - MHD_RESULT *mhd_ret) -{ - struct TEH_DB_KnowCoinContext *kcc = cls; - enum GNUNET_DB_QueryStatus qs; - - GNUNET_assert (NULL != mhd_ret); - qs = TEH_plugin->ensure_coin_known (TEH_plugin->cls, - session, - kcc->coin); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - { - *mhd_ret - = TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_DB_COIN_HISTORY_STORE_ERROR, - "could not persist coin data"); - return GNUNET_DB_STATUS_HARD_ERROR; - } - return qs; -} - - /** * Run a database transaction for @a connection. * Starts a transaction and calls @a cb. Upon success, diff --git a/src/exchange/taler-exchange-httpd_db.h b/src/exchange/taler-exchange-httpd_db.h index f97f488de..e0948d029 100644 --- a/src/exchange/taler-exchange-httpd_db.h +++ b/src/exchange/taler-exchange-httpd_db.h @@ -26,44 +26,6 @@ #include -/** - * Type of closure for #TEH_DB_know_coin_transaction. - */ -struct TEH_DB_KnowCoinContext -{ - /** - * The coin to make sure it is known. - */ - const struct TALER_CoinPublicInfo *coin; - - /** - * MHD connection to queue errors with. - */ - struct MHD_Connection *connection; -}; - - -/** - * Execute database transaction to ensure coin is known. Run the transaction - * logic; IF it returns a non-error code, the transaction logic MUST - * NOT queue a MHD response. IF it returns an hard error, the - * transaction logic MUST queue a MHD response and set @a mhd_ret. IF - * it returns the soft error code, the function MAY be called again to - * retry and MUST not queue a MHD response. - * - * @param cls a `struct TEH_DB_KnowCoinContext` - * @param connection MHD request context, must not be NULL - * @param session database session and transaction to use - * @param[out] mhd_ret set to MHD status on error, must not be NULL - * @return transaction status - */ -enum GNUNET_DB_QueryStatus -TEH_DB_know_coin_transaction (void *cls, - struct MHD_Connection *connection, - struct TALER_EXCHANGEDB_Session *session, - MHD_RESULT *mhd_ret); - - /** * Function implementing a database transaction. Runs the transaction * logic; IF it returns a non-error code, the transaction logic MUST diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index c2610b4b9..30f754b6d 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -217,6 +217,20 @@ deposit_transaction (void *cls, struct TALER_Amount spent; enum GNUNET_DB_QueryStatus qs; + /* make sure coin is 'known' in database */ + qs = TEH_plugin->ensure_coin_known (TEH_plugin->cls, + session, + &deposit->coin); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + *mhd_ret + = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_DB_COIN_HISTORY_STORE_ERROR, + "could not persist coin data"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + /* Theoretically, someone other threat may have received and committed the deposit in the meantime. Check now that we are in the transaction scope. */ @@ -493,26 +507,6 @@ TEH_handler_deposit (struct MHD_Connection *connection, "deposited amount smaller than depositing fee"); } - /* make sure coin is 'known' in database */ - { - MHD_RESULT mhd_ret; - struct TEH_DB_KnowCoinContext kcc = { - .coin = &deposit.coin, - .connection = connection - }; - - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "know coin for deposit", - &mhd_ret, - &TEH_DB_know_coin_transaction, - &kcc)) - { - GNUNET_JSON_parse_free (spec); - return mhd_ret; - } - } - /* check deposit signature */ { struct TALER_DepositRequestPS dr = { diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c index 2eab4b4a9..7e332d24f 100644 --- a/src/exchange/taler-exchange-httpd_melt.c +++ b/src/exchange/taler-exchange-httpd_melt.c @@ -157,6 +157,12 @@ struct MeltContext */ int zombie_required; + /** + * We already checked and noticed that the coin is known. Hence we + * can skip the "ensure_coin_known" step of the transaction. + */ + bool coin_is_dirty; + }; @@ -302,6 +308,23 @@ melt_transaction (void *cls, enum GNUNET_DB_QueryStatus qs; uint32_t noreveal_index; + /* First, make sure coin is 'known' in database */ + if (! rmc->coin_is_dirty) + { + qs = TEH_plugin->ensure_coin_known (TEH_plugin->cls, + session, + &rmc->refresh_session.coin); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + *mhd_ret + = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_DB_COIN_HISTORY_STORE_ERROR, + "could not persist coin data"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + } + /* Check if we already created a matching refresh_session */ qs = TEH_plugin->get_melt_index (TEH_plugin->cls, session, @@ -437,7 +460,6 @@ check_for_denomination_key (struct MHD_Connection *connection, struct MeltContext *rmc) { struct TEH_KS_StateHandle *key_state; - int coin_is_dirty = GNUNET_NO; key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); if (NULL == key_state) @@ -507,8 +529,8 @@ check_for_denomination_key (struct MHD_Connection *connection, else { /* Minor optimization: no need to run the - #TEH_DB_know_coin_transaction below */ - coin_is_dirty = GNUNET_YES; + "ensure_coin_known" part of the transaction */ + rmc->coin_is_dirty = true; } } } @@ -568,24 +590,6 @@ check_for_denomination_key (struct MHD_Connection *connection, } TEH_KS_release (key_state); - /* run actual logic, now that the request was parsed */ - /* First, make sure coin is 'known' in database */ - if (GNUNET_NO == coin_is_dirty) - { - struct TEH_DB_KnowCoinContext kcc; - MHD_RESULT mhd_ret; - - kcc.coin = &rmc->refresh_session.coin; - kcc.connection = connection; - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "know coin for melt", - &mhd_ret, - &TEH_DB_know_coin_transaction, - &kcc)) - return mhd_ret; - } - /* sanity-check that "total melt amount > melt fee" */ if (0 < TALER_amount_cmp (&rmc->coin_refresh_fee, diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c index c1f6ff330..d9969d90a 100644 --- a/src/exchange/taler-exchange-httpd_recoup.c +++ b/src/exchange/taler-exchange-httpd_recoup.c @@ -132,6 +132,20 @@ recoup_transaction (void *cls, enum GNUNET_DB_QueryStatus qs; int existing_recoup_found; + /* make sure coin is 'known' in database */ + qs = TEH_plugin->ensure_coin_known (TEH_plugin->cls, + session, + pc->coin); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + *mhd_ret + = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_DB_COIN_HISTORY_STORE_ERROR, + "could not persist coin data"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + /* Check whether a recoup is allowed, and if so, to which reserve / account the money should go */ if (pc->refreshed) @@ -450,22 +464,6 @@ verify_and_execute_recoup (struct MHD_Connection *connection, &pc.h_blind); GNUNET_free (coin_ev); - /* make sure coin is 'known' in database */ - { - struct TEH_DB_KnowCoinContext kcc; - MHD_RESULT mhd_ret; - - kcc.coin = coin; - kcc.connection = connection; - if (GNUNET_OK != - TEH_DB_run_transaction (connection, - "know coin for recoup", - &mhd_ret, - &TEH_DB_know_coin_transaction, - &kcc)) - return mhd_ret; - } - /* Perform actual recoup transaction */ pc.coin_sig = coin_sig; pc.coin_bks = coin_bks; -- cgit v1.2.3