diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-12-04 23:24:44 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-12-04 23:24:50 +0100 |
commit | e61a53806e83f3682bfc027f8b6e8d542798c1d6 (patch) | |
tree | 21cd788ee18ae36db8ed8440eac29f1aef96d49c /src | |
parent | ec45eaae1826cc607472b0e61da1bb940534eea4 (diff) | |
download | exchange-e61a53806e83f3682bfc027f8b6e8d542798c1d6.tar.xz |
save 2ms on deposit by not doing idempotency check twice
Diffstat (limited to 'src')
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposit.c | 86 |
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 (); |