summaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/taler-exchange-httpd_db.c37
-rw-r--r--src/exchange/taler-exchange-httpd_db.h39
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c24
-rw-r--r--src/exchange/taler-exchange-httpd_payback.c16
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_melt.c16
-rw-r--r--src/exchange/test_taler_exchange_aggregator.c9
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);