gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-exchange] branch master updated: make transactions s


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: make transactions smaller to try to reduce rollbacks
Date: Sun, 19 Aug 2018 16:02:01 +0200

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

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 0df2028f make transactions smaller to try to reduce rollbacks
0df2028f is described below

commit 0df2028f96f5977739d4659bf253e0c6d9468326
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun Aug 19 16:01:57 2018 +0200

    make transactions smaller to try to reduce rollbacks
---
 ChangeLog                                          |  4 +++
 .../.config/taler/account-2.json                   |  4 +--
 src/exchange/taler-exchange-httpd_db.c             | 37 ++++++++++++++++++++
 src/exchange/taler-exchange-httpd_db.h             | 39 ++++++++++++++++++++++
 src/exchange/taler-exchange-httpd_deposit.c        | 24 +++++++++++++
 src/exchange/taler-exchange-httpd_payback.c        | 16 +++++++++
 src/exchange/taler-exchange-httpd_refresh_melt.c   | 16 +++++++++
 src/exchange/test_taler_exchange_aggregator.c      |  9 ++++-
 src/exchangedb/perf_taler_exchangedb_interpreter.c | 12 +++++--
 src/exchangedb/plugin_exchangedb_postgres.c        | 39 +++++++++++++---------
 src/exchangedb/test_exchangedb.c                   | 12 +++++++
 src/include/taler_error_codes.h                    |  5 +++
 src/include/taler_exchangedb_plugin.h              | 14 ++++++++
 13 files changed, 211 insertions(+), 20 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 506ad357..48bb761f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Sun Aug 19 15:15:48 CEST 2018
+       Increase various limits and rework transaction scopes to
+       improve scalability. -CG
+
 Tue Apr  3 23:29:06 CEST 2018
        Releasing Taler v0.5.0
 
diff --git a/src/benchmark/exchange_benchmark_home/.config/taler/account-2.json 
b/src/benchmark/exchange_benchmark_home/.config/taler/account-2.json
index 222f5558..d4695892 100644
--- a/src/benchmark/exchange_benchmark_home/.config/taler/account-2.json
+++ b/src/benchmark/exchange_benchmark_home/.config/taler/account-2.json
@@ -1,5 +1,5 @@
 {
   "url": "payto://x-taler-bank/localhost:8082/2",
-  "salt": 
"MHJ6P3XF2WEC6WA097H8N1MPCT37T7TBHJ3FDTRBPGX0JNQYHJW6D52J0269WS68WG04FMCD5C0E49YEW7R21EXKC7P1TYTJMVKXNZR",
-  "master_sig": 
"ZGZVVR4S9PH9A494B15QSAYCX6NDVF735JN3426T7QQ77VK6QR971TQX71NXHR8N54RGC5GMC49YPK4RSFCJ2Z9GG1CWJ7MAEQSDC08"
+  "salt": 
"6TBY14X6YB6D0J2PGKQX0VVV30118QEQG1R3PYP1GG5XWXHST3ZQ1J3R6EQ85HZXS8DFDTRJN6JGBT8KDQFT0KVFPMGXTWHWC7E1518",
+  "master_sig": 
"CET51EPQGW01BVQMFXQKYW0BMWGQJJT7QTMGNW1FXYC6T6AB1CRK14S5PH5V34JDX7J8JJPVNV3VKXKH4CM1SVRQTFC5QVVDMJ3JM30"
 }
\ No newline at end of file
diff --git a/src/exchange/taler-exchange-httpd_db.c 
b/src/exchange/taler-exchange-httpd_db.c
index 5ba9f989..34993150 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 2a42bcd8..091421bb 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 8bf47717..53fe4222 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 6f910b55..aebbe2b8 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 08ceaa86..83bf197e 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 f22e6381..3f813f76 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);
diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c 
b/src/exchangedb/perf_taler_exchangedb_interpreter.c
index 43891e55..2d0ec396 100644
--- a/src/exchangedb/perf_taler_exchangedb_interpreter.c
+++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c
@@ -1205,6 +1205,10 @@ interpret (struct 
PERF_TALER_EXCHANGEDB_interpreter_state *state)
 
           deposit_index = 
state->cmd[state->i].details.insert_deposit.index_deposit;
           deposit = state->cmd[deposit_index].exposed.data.deposit;
+          qs = state->plugin->ensure_coin_known (state->plugin->cls,
+                                                 state->session,
+                                                 &deposit->coin);
+          GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
           qs = state->plugin->insert_deposit (state->plugin->cls,
                                               state->session,
                                               deposit);
@@ -1434,7 +1438,11 @@ interpret (struct 
PERF_TALER_EXCHANGEDB_interpreter_state *state)
                                                  
&refresh_session.amount_with_fee));
           refresh_session.noreveal_index = 1;
           GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
-                        state->plugin->insert_melt (state->session,
+                        state->plugin->ensure_coin_known (state->plugin->cls,
+                                                           state->session,
+                                                           
&refresh_session.coin));
+          GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
+                        state->plugin->insert_melt (state->plugin->cls,
                                                      state->session,
                                                      &refresh_session));
           state->cmd[state->i].exposed.data.rc = refresh_session.rc;
@@ -1449,7 +1457,7 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state 
*state)
 
           hash_index = 
state->cmd[state->i].details.get_refresh_session.index_hash;
           rc = &state->cmd[hash_index].exposed.data.rc;
-          state->plugin->get_melt (state->session,
+          state->plugin->get_melt (state->plugin->cls,
                                    state->session,
                                    rc,
                                    &refresh);
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 724bf28a..d3efb931 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -3197,15 +3197,16 @@ insert_known_coin (void *cls,
  * @return database transaction status, non-negative on success
  */
 static enum GNUNET_DB_QueryStatus
-ensure_coin_known (struct PostgresClosure *cls,
-                  struct TALER_EXCHANGEDB_Session *session,
-                  const struct TALER_CoinPublicInfo *coin)
+postgres_ensure_coin_known (void *cls,
+                            struct TALER_EXCHANGEDB_Session *session,
+                            const struct TALER_CoinPublicInfo *coin)
 {
+  struct PostgresClosure *pc = cls;
   enum GNUNET_DB_QueryStatus qs;
   struct TALER_CoinPublicInfo known_coin;
 
   /* check if the coin is already known */
-  qs = get_known_coin (cls,
+  qs = get_known_coin (pc,
                       session,
                       &coin->coin_pub,
                       &known_coin);
@@ -3222,7 +3223,7 @@ ensure_coin_known (struct PostgresClosure *cls,
   }
   GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs);
   /* if not known, insert it */
-  qs = insert_known_coin (cls,
+  qs = insert_known_coin (pc,
                          session,
                          coin);
   if (0 >= qs)
@@ -3249,7 +3250,6 @@ postgres_insert_deposit (void *cls,
                          struct TALER_EXCHANGEDB_Session *session,
                          const struct TALER_EXCHANGEDB_Deposit *deposit)
 {
-  enum GNUNET_DB_QueryStatus qs;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
     TALER_PQ_query_param_amount (&deposit->amount_with_fee),
@@ -3264,10 +3264,14 @@ postgres_insert_deposit (void *cls,
     GNUNET_PQ_query_param_end
   };
 
-  if (0 > (qs = ensure_coin_known (cls,
-                                  session,
-                                  &deposit->coin)))
+#if 0
+  enum GNUNET_DB_QueryStatus qs;
+
+  if (0 > (qs = postgres_ensure_coin_known (cls,
+                                            session,
+                                            &deposit->coin)))
     return qs;
+#endif
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Inserting deposit to be executed at %s (%llu/%llu)\n",
              GNUNET_STRINGS_absolute_time_to_string (deposit->wire_deadline),
@@ -3501,12 +3505,14 @@ postgres_insert_melt (void *cls,
     GNUNET_PQ_query_param_uint32 (&refresh_session->noreveal_index),
     GNUNET_PQ_query_param_end
   };
+#if 0
   enum GNUNET_DB_QueryStatus qs;
 
-  if (0 > (qs = ensure_coin_known (cls,
-                                  session,
-                                  &refresh_session->coin)))
+  if (0 > (qs = postgres_ensure_coin_known (cls,
+                                            session,
+                                            &refresh_session->coin)))
     return qs;
+#endif
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
                                             "insert_melt",
                                             params);
@@ -6371,11 +6377,13 @@ postgres_insert_payback_request (void *cls,
   };
   enum GNUNET_DB_QueryStatus qs;
 
+#if 0
   /* check if the coin is already known */
-  if (0 > (qs = ensure_coin_known (cls,
-                                  session,
-                                  coin)))
+  if (0 > (qs = postgres_ensure_coin_known (cls,
+                                            session,
+                                            coin)))
     return qs;
+#endif
   /* now store actual payback information */
   qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
                                           "payback_insert",
@@ -6993,6 +7001,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
   plugin->insert_withdraw_info = &postgres_insert_withdraw_info;
   plugin->get_reserve_history = &postgres_get_reserve_history;
   plugin->free_reserve_history = &common_free_reserve_history;
+  plugin->ensure_coin_known = &postgres_ensure_coin_known;
   plugin->have_deposit = &postgres_have_deposit;
   plugin->mark_deposit_tiny = &postgres_mark_deposit_tiny;
   plugin->test_deposit_done = &postgres_test_deposit_done;
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 16467d57..8666f1a5 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -591,6 +591,10 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
                             &refresh_session.rc,
                             &ret_refresh_session));
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+          plugin->ensure_coin_known (plugin->cls,
+                                     session,
+                                     &refresh_session.coin));
+  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
          plugin->insert_melt (plugin->cls,
                                session,
                                &refresh_session));
@@ -1776,6 +1780,10 @@ run (void *cls)
   deadline = GNUNET_TIME_absolute_get ();
   (void) GNUNET_TIME_round_abs (&deadline);
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+          plugin->ensure_coin_known (plugin->cls,
+                                     session,
+                                     &deposit.coin));
+  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_payback_request (plugin->cls,
                                           session,
                                           &reserve_pub,
@@ -1923,6 +1931,10 @@ run (void *cls)
   deposit.wire_deadline = deadline;
   result = 8;
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+          plugin->ensure_coin_known (plugin->cls,
+                                     session,
+                                     &deposit.coin));
+  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
           plugin->insert_deposit (plugin->cls,
                                   session,
                                   &deposit));
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index 754681b4..35dceb7c 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -175,6 +175,11 @@ enum TALER_ErrorCode
    */
   TALER_EC_PAYTO_MALFORMED = 1013,
 
+  /**
+   * We failed to update the database of known coins.
+   */
+  TALER_EC_DB_COIN_HISTORY_STORE_ERROR = 1014,
+
   /* ********** request-specific error codes ************* */
 
   /**
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 6e594737..b06bc740 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1398,6 +1398,20 @@ struct TALER_EXCHANGEDB_Plugin
 
 
   /**
+   * Make sure the given @a coin is known to the database.
+   *
+   * @param cls database connection plugin state
+   * @param session database session
+   * @param coin the coin that must be made known
+   * @return database transaction status, non-negative on success
+   */
+  enum GNUNET_DB_QueryStatus
+  (*ensure_coin_known) (void *cls,
+                        struct TALER_EXCHANGEDB_Session *session,
+                        const struct TALER_CoinPublicInfo *coin);
+
+
+  /**
    * Check if we have the specified deposit already in the database.
    *
    * @param cls the @e cls of this struct with the plugin-specific state

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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