diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-08-19 16:01:57 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-08-19 16:01:57 +0200 |
commit | 0df2028f96f5977739d4659bf253e0c6d9468326 (patch) | |
tree | 906222af6c332e219af4a5d112891d7212237de3 /src/exchange | |
parent | ddca1f5c68e112928d715e1aee2758c40e14fb51 (diff) | |
download | exchange-0df2028f96f5977739d4659bf253e0c6d9468326.tar.gz exchange-0df2028f96f5977739d4659bf253e0c6d9468326.tar.bz2 exchange-0df2028f96f5977739d4659bf253e0c6d9468326.zip |
make transactions smaller to try to reduce rollbacks
Diffstat (limited to 'src/exchange')
-rw-r--r-- | src/exchange/taler-exchange-httpd_db.c | 37 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_db.h | 39 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposit.c | 24 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_payback.c | 16 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_refresh_melt.c | 16 | ||||
-rw-r--r-- | src/exchange/test_taler_exchange_aggregator.c | 9 |
6 files changed, 140 insertions, 1 deletions
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 5ba9f989f..34993150b 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -34,6 +34,43 @@ /** + * 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 DepositContext` + * @param connection MHD request context + * @param session database session and transaction to use + * @param[out] mhd_ret set to MHD status on error + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_DB_know_coin_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + int *mhd_ret) +{ + struct TEH_DB_KnowCoinContext *kcc = cls; + enum GNUNET_DB_QueryStatus qs; + + qs = TEH_plugin->ensure_coin_known (TEH_plugin->cls, + session, + kcc->coin); + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + *mhd_ret + = TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_COIN_HISTORY_STORE_ERROR); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} + + +/** * Run a database transaction for @a connection. * Starts a transaction and calls @a cb. Upon success, * attempts to commit the transaction. Upon soft failures, diff --git a/src/exchange/taler-exchange-httpd_db.h b/src/exchange/taler-exchange-httpd_db.h index 2a42bcd85..091421bb4 100644 --- a/src/exchange/taler-exchange-httpd_db.h +++ b/src/exchange/taler-exchange-httpd_db.h @@ -24,6 +24,45 @@ #include <microhttpd.h> #include "taler_exchangedb_plugin.h" + +/** + * 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 DepositContext` + * @param connection MHD request context + * @param session database session and transaction to use + * @param[out] mhd_ret set to MHD status on error + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_DB_know_coin_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + int *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 8bf47717e..53fe4222a 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -144,7 +144,15 @@ deposit_transaction (void *cls, session, deposit); if (qs < 0) + { + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DEPOSIT_HISTORY_DB_ERROR); + return GNUNET_DB_STATUS_HARD_ERROR; + } return qs; + } if (1 == qs) { struct TALER_Amount amount_without_fee; @@ -518,6 +526,22 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh, "deposited amount smaller than depositing fee"); } + /* make sure coin is 'known' in database */ + { + struct TEH_DB_KnowCoinContext kcc; + int mhd_ret; + + kcc.coin = &deposit.coin; + kcc.connection = connection; + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "know coin for deposit", + &mhd_ret, + &TEH_DB_know_coin_transaction, + &kcc)) + return mhd_ret; + } + res = verify_and_execute_deposit (connection, &deposit); GNUNET_JSON_parse_free (spec); diff --git a/src/exchange/taler-exchange-httpd_payback.c b/src/exchange/taler-exchange-httpd_payback.c index 6f910b55b..aebbe2b82 100644 --- a/src/exchange/taler-exchange-httpd_payback.c +++ b/src/exchange/taler-exchange-httpd_payback.c @@ -391,6 +391,22 @@ verify_and_execute_payback (struct MHD_Connection *connection, &pc.h_blind); GNUNET_free (coin_ev); + /* make sure coin is 'known' in database */ + { + struct TEH_DB_KnowCoinContext kcc; + int mhd_ret; + + kcc.coin = coin; + kcc.connection = connection; + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "know coin for payback", + &mhd_ret, + &TEH_DB_know_coin_transaction, + &kcc)) + return mhd_ret; + } + pc.coin_sig = coin_sig; pc.coin_bks = coin_bks; pc.coin = coin; diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c index 08ceaa868..83bf197e2 100644 --- a/src/exchange/taler-exchange-httpd_refresh_melt.c +++ b/src/exchange/taler-exchange-httpd_refresh_melt.c @@ -474,6 +474,22 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh, goto cleanup; } + /* make sure coin is 'known' in database */ + { + struct TEH_DB_KnowCoinContext kcc; + int mhd_ret; + + kcc.coin = &rmc.refresh_session.coin; + kcc.connection = connection; + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "know coin for refresh-melt", + &mhd_ret, + &TEH_DB_know_coin_transaction, + &kcc)) + return mhd_ret; + } + res = handle_refresh_melt (connection, &rmc); diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index f22e63815..3f813f76f 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -459,14 +459,21 @@ do_deposit (struct Command *cmd) plugin->start (plugin->cls, session, "aggregator-test-1")) || - (GNUNET_OK != + (0 > + plugin->ensure_coin_known (plugin->cls, + session, + &deposit.coin)) || + (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->insert_deposit (plugin->cls, session, &deposit)) || (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != plugin->commit (plugin->cls, session)) ) + { + GNUNET_break (0); ret = GNUNET_SYSERR; + } else ret = GNUNET_OK; GNUNET_CRYPTO_rsa_signature_free (deposit.coin.denom_sig.rsa_signature); |