summaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_deposit.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-12-04 23:24:44 +0100
committerChristian Grothoff <christian@grothoff.org>2021-12-04 23:24:50 +0100
commite61a53806e83f3682bfc027f8b6e8d542798c1d6 (patch)
tree21cd788ee18ae36db8ed8440eac29f1aef96d49c /src/exchange/taler-exchange-httpd_deposit.c
parentec45eaae1826cc607472b0e61da1bb940534eea4 (diff)
downloadexchange-e61a53806e83f3682bfc027f8b6e8d542798c1d6.tar.gz
exchange-e61a53806e83f3682bfc027f8b6e8d542798c1d6.tar.bz2
exchange-e61a53806e83f3682bfc027f8b6e8d542798c1d6.zip
save 2ms on deposit by not doing idempotency check twice
Diffstat (limited to 'src/exchange/taler-exchange-httpd_deposit.c')
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c86
1 files changed, 19 insertions, 67 deletions
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index e9851de79..6b651f40e 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -139,11 +139,12 @@ struct DepositContext
/**
- * Check if /deposit is already in the database. 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. We do return a "hard" error also if we found the deposit in the
- * database and generated a regular response.
+ * Execute database transaction for /deposit. Runs 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
@@ -151,15 +152,24 @@ struct DepositContext
* @return transaction status
*/
static enum GNUNET_DB_QueryStatus
-deposit_precheck (void *cls,
- struct MHD_Connection *connection,
- MHD_RESULT *mhd_ret)
+deposit_transaction (void *cls,
+ struct MHD_Connection *connection,
+ MHD_RESULT *mhd_ret)
{
struct DepositContext *dc = cls;
const struct TALER_EXCHANGEDB_Deposit *deposit = dc->deposit;
- struct TALER_Amount deposit_fee;
+ struct TALER_Amount spent;
enum GNUNET_DB_QueryStatus qs;
+ struct TALER_Amount deposit_fee;
+
+ /* make sure coin is 'known' in database */
+ qs = TEH_make_coin_known (&deposit->coin,
+ connection,
+ mhd_ret);
+ if (qs < 0)
+ return qs;
+ /* Check for idempotency: did we get this request before? */
qs = TEH_plugin->have_deposit (TEH_plugin->cls,
deposit,
&deposit_fee,
@@ -196,51 +206,8 @@ deposit_precheck (void *cls,
deposit->wire_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;
}
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
-}
-
-
-/**
- * Execute database transaction for /deposit. Runs 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[out] mhd_ret set to MHD status on error
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-deposit_transaction (void *cls,
- struct MHD_Connection *connection,
- MHD_RESULT *mhd_ret)
-{
- struct DepositContext *dc = cls;
- const struct TALER_EXCHANGEDB_Deposit *deposit = dc->deposit;
- struct TALER_Amount spent;
- enum GNUNET_DB_QueryStatus qs;
-
- /* make sure coin is 'known' in database */
- qs = TEH_make_coin_known (&deposit->coin,
- connection,
- mhd_ret);
- if (qs < 0)
- return qs;
- /* Theoretically, someone other threat may have received
- and committed the deposit in the meantime. Check now
- that we are in the transaction scope. */
- qs = deposit_precheck (cls,
- connection,
- mhd_ret);
- if (qs < 0)
- return qs;
/* Start with fee for THIS transaction */
spent = deposit->amount_with_fee;
@@ -412,22 +379,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
TALER_merchant_wire_signature_hash (dc.payto_uri,
&deposit.wire_salt,
&dc.h_wire);
- /* Check for idempotency: did we get this request before? */
dc.deposit = &deposit;
- {
- MHD_RESULT mhd_ret;
-
- if (GNUNET_OK !=
- TEH_DB_run_transaction (connection,
- "precheck deposit",
- &mhd_ret,
- &deposit_precheck,
- &dc))
- {
- GNUNET_JSON_parse_free (spec);
- return mhd_ret;
- }
- }
/* new deposit */
dc.exchange_timestamp = GNUNET_TIME_absolute_get ();