gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] 01/02: synchronize with latest GANA


From: gnunet
Subject: [taler-exchange] 01/02: synchronize with latest GANA
Date: Wed, 08 Jul 2020 19:37:52 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

commit c3cd21508b0900ee5437edb3828b4b7c2f359495
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed Jul 8 19:36:08 2020 +0200

    synchronize with latest GANA
---
 contrib/gana                                |  2 +-
 src/exchange/taler-exchange-httpd_db.c      | 72 +++++++++++++++++++++++++++++
 src/exchange/taler-exchange-httpd_db.h      | 16 +++++++
 src/exchange/taler-exchange-httpd_deposit.c | 18 +++-----
 src/exchange/taler-exchange-httpd_melt.c    | 18 +++-----
 src/exchange/taler-exchange-httpd_recoup.c  | 18 +++-----
 src/exchangedb/plugin_exchangedb_postgres.c | 42 +++++++++++------
 src/exchangedb/test_exchangedb.c            |  6 +--
 src/include/taler_exchangedb_plugin.h       | 28 ++++++++++-
 9 files changed, 164 insertions(+), 56 deletions(-)

diff --git a/contrib/gana b/contrib/gana
index c0fedb8d..f805e4f0 160000
--- a/contrib/gana
+++ b/contrib/gana
@@ -1 +1 @@
-Subproject commit c0fedb8d45c41fb283fec714b48278e6661d51be
+Subproject commit f805e4f09b45262cbbb6184659754e15aedfadfd
diff --git a/src/exchange/taler-exchange-httpd_db.c 
b/src/exchange/taler-exchange-httpd_db.c
index dfef63c4..b0e49522 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -40,6 +40,78 @@
 #define MAX_TRANSACTION_COMMIT_RETRIES 100
 
 
+/**
+ * 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,
diff --git a/src/exchange/taler-exchange-httpd_db.h 
b/src/exchange/taler-exchange-httpd_db.h
index e0948d02..bc127b27 100644
--- a/src/exchange/taler-exchange-httpd_db.h
+++ b/src/exchange/taler-exchange-httpd_db.h
@@ -26,6 +26,22 @@
 #include <gnunet/gnunet_mhd_compat.h>
 
 
+/**
+ * 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
diff --git a/src/exchange/taler-exchange-httpd_deposit.c 
b/src/exchange/taler-exchange-httpd_deposit.c
index 30f754b6..0b810220 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 7e332d24..0af0da04 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 d9969d90..b3ea90f5 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 */
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 0f96f0e8..8e45d671 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -3187,7 +3187,7 @@ postgres_count_known_coins (void *cls,
  * @param coin the coin that must be made known
  * @return database transaction status, non-negative on success
  */
-static enum GNUNET_DB_QueryStatus
+static enum TALER_EXCHANGEDB_CoinKnownStatus
 postgres_ensure_coin_known (void *cls,
                             struct TALER_EXCHANGEDB_Session *session,
                             const struct TALER_CoinPublicInfo *coin)
@@ -3207,33 +3207,45 @@ postgres_ensure_coin_known (void *cls,
 #endif
 
   /* check if the coin is already known */
+  // FIXME: modify to not also fetch the RSA signature, needlessly costly!
   qs = postgres_get_known_coin (pc,
                                 session,
                                 &coin->coin_pub,
                                 &known_coin);
-  if (0 > qs)
-  {
-    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+  switch (qs)
   {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return TALER_EXCHANGEDB_CKS_SOFT_FAIL;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    return TALER_EXCHANGEDB_CKS_HARD_FAIL;
+  case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     GNUNET_CRYPTO_rsa_signature_free (known_coin.denom_sig.rsa_signature);
-    return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;   /* no change! */
+    if (0 == GNUNET_memcmp (&known_coin.denom_pub_hash,
+                            &coin->denom_pub_hash))
+      return TALER_EXCHANGEDB_CKS_PRESENT;
+    GNUNET_break_op (0);
+    return TALER_EXCHANGEDB_CKS_CONFLICT;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    break;
   }
-  GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs);
+
   /* if not known, insert it */
   qs = insert_known_coin (pc,
                           session,
                           coin);
-  if (0 >= qs)
+  switch (qs)
   {
-    if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
-      qs = GNUNET_DB_STATUS_HARD_ERROR;   /* should be impossible */
-    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
-    return qs;
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return TALER_EXCHANGEDB_CKS_SOFT_FAIL;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    return TALER_EXCHANGEDB_CKS_HARD_FAIL;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    GNUNET_break (0);
+    return TALER_EXCHANGEDB_CKS_HARD_FAIL;
+  case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+    break;
   }
-  return qs;
+  return TALER_EXCHANGEDB_CKS_ADDED;
 }
 
 
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 8567c87c..c9b5c6ce 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -559,7 +559,7 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
                             session,
                             &refresh_session.rc,
                             &ret_refresh_session));
-  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+  FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
           plugin->ensure_coin_known (plugin->cls,
                                      session,
                                      &refresh_session.coin));
@@ -1746,7 +1746,7 @@ run (void *cls)
   deposit.coin.denom_sig = cbc.sig;
   deadline = GNUNET_TIME_absolute_get ();
   (void) GNUNET_TIME_round_abs (&deadline);
-  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+  FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
           plugin->ensure_coin_known (plugin->cls,
                                      session,
                                      &deposit.coin));
@@ -1921,7 +1921,7 @@ run (void *cls)
   deposit.refund_deadline = deadline;
   deposit.wire_deadline = deadline;
   result = 8;
-  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+  FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
           plugin->ensure_coin_known (plugin->cls,
                                      session,
                                      &deposit.coin));
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index a12aaa42..8b4e63cd 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1841,7 +1841,33 @@ struct TALER_EXCHANGEDB_Plugin
    * @param coin the coin that must be made known
    * @return database transaction status, non-negative on success
    */
-  enum GNUNET_DB_QueryStatus
+  enum TALER_EXCHANGEDB_CoinKnownStatus
+  {
+    /**
+     * The coin was successfully added.
+     */
+    TALER_EXCHANGEDB_CKS_ADDED = 1,
+
+    /**
+     * The coin was already present.
+     */
+    TALER_EXCHANGEDB_CKS_PRESENT = 0,
+
+    /**
+     * Serialization failure.
+     */
+    TALER_EXCHANGEDB_CKS_SOFT_FAIL = -1,
+
+    /**
+     * Hard database failure.
+     */
+    TALER_EXCHANGEDB_CKS_HARD_FAIL = -2,
+
+    /**
+     * Conflicting coin (different denomination key) already in database.
+     */
+    TALER_EXCHANGEDB_CKS_CONFLICT = -3,
+  }
   (*ensure_coin_known)(void *cls,
                        struct TALER_EXCHANGEDB_Session *session,
                        const struct TALER_CoinPublicInfo *coin);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]