exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 35b4a51e14dc08e1aa6a00d8edca5eda75c3e3de
parent 93eb88a8c9cb520808bb39c9f4bc527c9f01fc57
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 12 May 2022 13:31:15 +0200

combine auto-commited transactions in refresh/reveal into one big transaction

Diffstat:
Msrc/exchange/taler-exchange-httpd_refreshes_reveal.c | 51+++++++++++++++++++++++++++++++++++++++++++++------
Msrc/exchangedb/plugin_exchangedb_postgres.c | 6++++--
Msrc/include/taler_exchangedb_plugin.h | 4++--
3 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -444,6 +444,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, MHD_RESULT ret; struct TEH_KeyStateHandle *ksh; uint64_t melt_serial_id; + enum GNUNET_DB_QueryStatus qs; memset (dks, 0, sizeof (dks)); memset (rrcs, 0, sizeof (rrcs)); @@ -768,11 +769,20 @@ clean_age: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signatures ready, starting DB interaction\n"); - // FIXME: do all this (and the above) in ONE DB transaction! - /* Persist operation result in DB */ + for (unsigned int r = 0; r<MAX_TRANSACTION_COMMIT_RETRIES; r++) { - enum GNUNET_DB_QueryStatus qs; - + /* Persist operation result in DB */ + if (GNUNET_OK != + TEH_plugin->start (TEH_plugin->cls, + "insert_refresh_reveal batch")) + { + GNUNET_break (0); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_START_FAILED, + NULL); + goto cleanup; + } for (unsigned int i = 0; i<rctx->num_fresh_coins; i++) { struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &rrcs[i]; @@ -786,18 +796,47 @@ clean_age: TALER_CNC_KAPPA - 1, rctx->transfer_privs, &rctx->gamma_tp); + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + { + TEH_plugin->rollback (TEH_plugin->cls); + continue; + } /* 0 == qs is ok, as we did not check for repeated requests */ - if (0 > qs) + if (GNUNET_DB_STATUS_HARD_ERROR == qs) { GNUNET_break (0); + TEH_plugin->rollback (TEH_plugin->cls); ret = TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_STORE_FAILED, "insert_refresh_reveal"); goto cleanup; } + qs = TEH_plugin->commit (TEH_plugin->cls); + if (qs >= 0) + break; /* success */ + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + { + GNUNET_break (0); + TEH_plugin->rollback (TEH_plugin->cls); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_COMMIT_FAILED, + NULL); + goto cleanup; + } + TEH_plugin->rollback (TEH_plugin->cls); + } + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + { + GNUNET_break (0); + TEH_plugin->rollback (TEH_plugin->cls); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_SOFT_FAILURE, + NULL); + goto cleanup; } - /* Generate final (positive) response */ ret = reply_refreshes_reveal_success (connection, num_fresh_coins, diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c @@ -1263,7 +1263,8 @@ prepare_statements (struct PostgresClosure *pg) ") SELECT $1, $2, $3, " " denominations_serial, $5, $6, $7, $8" " FROM denominations" - " WHERE denom_pub_hash=$4;", + " WHERE denom_pub_hash=$4" + " ON CONFLICT DO NOTHING;", 8), /* Obtain information about the coins created in a refresh operation, used in #postgres_get_refresh_reveal() */ @@ -1293,7 +1294,8 @@ prepare_statements (struct PostgresClosure *pg) "(melt_serial_id" ",transfer_pub" ",transfer_privs" - ") VALUES ($1, $2, $3);", + ") VALUES ($1, $2, $3)" + " ON CONFLICT DO NOTHING;", 3), /* Used in #postgres_insert_refund() to store refund information */ GNUNET_PQ_make_prepare ( diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -635,8 +635,8 @@ struct TALER_EXCHANGEDB_Reserve struct TALER_EXCHANGEDB_DenominationKeyMetaData { /** - * Start time of the validity period for this key. - */ + * Start time of the validity period for this key. + */ struct GNUNET_TIME_Timestamp start; /**