From 461dc8e36ccc2e31799087bee4604c33bee9afc6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 5 Dec 2022 11:15:59 +0100 Subject: [PATCH] -fix crash if there is a conflict on inserting into the purse_decision table --- contrib/gana | 2 +- .../taler-exchange-httpd_purses_deposit.c | 6 ++++- src/exchangedb/procedures.sql | 9 ++++++- src/include/taler_exchange_service.h | 27 +++++++++---------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/contrib/gana b/contrib/gana index a4a6b9ba4..212ee0a78 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit a4a6b9ba4b2634c56194d53e36344686d7052cef +Subproject commit 212ee0a78adc43cb5c04d6ea96ccc2fe74fed62b diff --git a/src/exchange/taler-exchange-httpd_purses_deposit.c b/src/exchange/taler-exchange-httpd_purses_deposit.c index dc1a256d7..0875ed2e6 100644 --- a/src/exchange/taler-exchange-httpd_purses_deposit.c +++ b/src/exchange/taler-exchange-httpd_purses_deposit.c @@ -185,13 +185,14 @@ deposit_transaction (void *cls, { if (GNUNET_DB_STATUS_SOFT_ERROR == qs) return qs; + GNUNET_break (0 != qs); TALER_LOG_WARNING ( "Failed to store purse deposit information in database\n"); *mhd_ret = TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_STORE_FAILED, "do purse deposit"); - return qs; + return GNUNET_DB_STATUS_HARD_ERROR; } if (! balance_ok) { @@ -203,6 +204,9 @@ deposit_transaction (void *cls, &coin->cpi.coin_pub); return GNUNET_DB_STATUS_HARD_ERROR; } + // FIXME: there is also a 'conflict' case where the purse was already + // decided (fully paid up OR expired), we should probably distinguish + // those better! if (conflict) { struct TALER_Amount amount; diff --git a/src/exchangedb/procedures.sql b/src/exchangedb/procedures.sql index ff3ddb3f7..a869d4739 100644 --- a/src/exchangedb/procedures.sql +++ b/src/exchangedb/procedures.sql @@ -1557,7 +1557,14 @@ INSERT INTO purse_decision VALUES (in_purse_pub ,in_now - ,FALSE); + ,FALSE) +ON CONFLICT DO NOTHING; + +IF NOT FOUND +THEN + out_conflict=TRUE; + RETURN; +END IF; IF (my_in_reserve_quota) THEN diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index d11f7d616..fcb75a1b9 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1171,9 +1171,8 @@ TALER_EXCHANGE_batch_deposit ( * @param deposit the batch deposit permission request handle */ void -TALER_EXCHANGE_batch_deposit_force_dc (struct - TALER_EXCHANGE_BatchDepositHandle * - deposit); +TALER_EXCHANGE_batch_deposit_force_dc ( + struct TALER_EXCHANGE_BatchDepositHandle *deposit); /** @@ -1183,8 +1182,8 @@ TALER_EXCHANGE_batch_deposit_force_dc (struct * @param deposit the deposit permission request handle */ void -TALER_EXCHANGE_batch_deposit_cancel (struct - TALER_EXCHANGE_BatchDepositHandle *deposit); +TALER_EXCHANGE_batch_deposit_cancel ( + struct TALER_EXCHANGE_BatchDepositHandle *deposit); /* ********************* /coins/$COIN_PUB/refund *********************** */ @@ -1241,15 +1240,15 @@ typedef void * signatures fail to verify). In this case, the callback is not called. */ struct TALER_EXCHANGE_RefundHandle * -TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_Amount *amount, - const struct - TALER_PrivateContractHashP *h_contract_terms, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - uint64_t rtransaction_id, - const struct TALER_MerchantPrivateKeyP *merchant_priv, - TALER_EXCHANGE_RefundCallback cb, - void *cb_cls); +TALER_EXCHANGE_refund ( + struct TALER_EXCHANGE_Handle *exchange, + const struct TALER_Amount *amount, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + uint64_t rtransaction_id, + const struct TALER_MerchantPrivateKeyP *merchant_priv, + TALER_EXCHANGE_RefundCallback cb, + void *cb_cls); /**