summaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/taler-exchange-httpd_db.c72
-rw-r--r--src/exchange/taler-exchange-httpd_db.h16
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c18
-rw-r--r--src/exchange/taler-exchange-httpd_melt.c18
-rw-r--r--src/exchange/taler-exchange-httpd_recoup.c18
5 files changed, 106 insertions, 36 deletions
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index dfef63c4c..b0e495226 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -41,6 +41,78 @@
/**
+ * Ensure coin is known in the database, and handle conflicts and errors.
+ *
+ * @param coin the coin to make known
+ * @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, negative on error (@a mhd_ret will be set in this case)
+ */
+enum GNUNET_DB_QueryStatus
+TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
+ struct MHD_Connection *connection,
+ struct TALER_EXCHANGEDB_Session *session,
+ MHD_RESULT *mhd_ret)
+{
+ enum TALER_EXCHANGEDB_CoinKnownStatus cks;
+
+ /* make sure coin is 'known' in database */
+ cks = TEH_plugin->ensure_coin_known (TEH_plugin->cls,
+ session,
+ coin);
+ switch (cks)
+ {
+ case TALER_EXCHANGEDB_CKS_ADDED:
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+ case TALER_EXCHANGEDB_CKS_PRESENT:
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ case TALER_EXCHANGEDB_CKS_SOFT_FAIL:
+ return GNUNET_DB_STATUS_SOFT_ERROR;
+ case TALER_EXCHANGEDB_CKS_HARD_FAIL:
+ *mhd_ret
+ = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_COIN_HISTORY_STORE_ERROR,
+ "could not persist coin data");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ case TALER_EXCHANGEDB_CKS_CONFLICT:
+ break;
+ }
+
+ {
+ struct TALER_EXCHANGEDB_TransactionList *tl;
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
+ session,
+ &coin->coin_pub,
+ GNUNET_NO,
+ &tl);
+ if (0 > qs)
+ {
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ *mhd_ret = TALER_MHD_reply_with_error (
+ connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR,
+ "could not fetch coin transaction history");
+ return qs;
+ }
+ *mhd_ret
+ = TEH_RESPONSE_reply_coin_insufficient_funds (
+ connection,
+ TALER_EC_COIN_CONFLICTING_DENOMINATION_KEY,
+ &coin->coin_pub,
+ tl);
+ TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
+ tl);
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+}
+
+
+/**
* 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 e0948d029..bc127b275 100644
--- a/src/exchange/taler-exchange-httpd_db.h
+++ b/src/exchange/taler-exchange-httpd_db.h
@@ -27,6 +27,22 @@
/**
+ * Ensure coin is known in the database, and handle conflicts and errors.
+ *
+ * @param coin the coin to make known
+ * @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, negative on error (@a mhd_ret will be set in this case)
+ */
+enum GNUNET_DB_QueryStatus
+TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
+ struct MHD_Connection *connection,
+ struct TALER_EXCHANGEDB_Session *session,
+ MHD_RESULT *mhd_ret);
+
+
+/**
* Function implementing a database transaction. 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
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index 30f754b6d..0b810220a 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -218,18 +218,12 @@ deposit_transaction (void *cls,
enum GNUNET_DB_QueryStatus qs;
/* make sure coin is 'known' in database */
- qs = TEH_plugin->ensure_coin_known (TEH_plugin->cls,
- session,
- &deposit->coin);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- {
- *mhd_ret
- = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_DB_COIN_HISTORY_STORE_ERROR,
- "could not persist coin data");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
+ qs = TEH_make_coin_known (&deposit->coin,
+ connection,
+ session,
+ mhd_ret);
+ if (qs < 0)
+ return qs;
/* Theoretically, someone other threat may have received
and committed the deposit in the meantime. Check now
diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c
index 7e332d24f..0af0da04a 100644
--- a/src/exchange/taler-exchange-httpd_melt.c
+++ b/src/exchange/taler-exchange-httpd_melt.c
@@ -311,18 +311,12 @@ melt_transaction (void *cls,
/* First, make sure coin is 'known' in database */
if (! rmc->coin_is_dirty)
{
- qs = TEH_plugin->ensure_coin_known (TEH_plugin->cls,
- session,
- &rmc->refresh_session.coin);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- {
- *mhd_ret
- = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_DB_COIN_HISTORY_STORE_ERROR,
- "could not persist coin data");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
+ qs = TEH_make_coin_known (&rmc->refresh_session.coin,
+ connection,
+ session,
+ mhd_ret);
+ if (qs < 0)
+ return qs;
}
/* Check if we already created a matching refresh_session */
diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c
index d9969d90a..b3ea90f5c 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -133,18 +133,12 @@ recoup_transaction (void *cls,
int existing_recoup_found;
/* make sure coin is 'known' in database */
- qs = TEH_plugin->ensure_coin_known (TEH_plugin->cls,
- session,
- pc->coin);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- {
- *mhd_ret
- = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_DB_COIN_HISTORY_STORE_ERROR,
- "could not persist coin data");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
+ qs = TEH_make_coin_known (&rmc->refresh_session.coin,
+ connection,
+ session,
+ mhd_ret);
+ if (qs < 0)
+ return qs;
/* Check whether a recoup is allowed, and if so, to which
reserve / account the money should go */