gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated (c93f6471 -> 8a1402a5)


From: gnunet
Subject: [taler-exchange] branch master updated (c93f6471 -> 8a1402a5)
Date: Wed, 08 Jul 2020 19:37:51 +0200

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

grothoff pushed a change to branch master
in repository exchange.

    from c93f6471 merge known_coin transaction into main transaction (for #6416)
     new c3cd2150 synchronize with latest GANA
     new 8a1402a5 complete server-side logic to generate response for 
conflicting denomination keys for the same coin

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 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..e53c1d9d 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 (pc->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]