gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-merchant] branch master updated: implementing #5281


From: gnunet
Subject: [GNUnet-SVN] [taler-merchant] branch master updated: implementing #5281 guards against hanging transactions, plus minor code cleanups
Date: Mon, 12 Mar 2018 12:29:48 +0100

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

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 9b56f3e  implementing #5281 guards against hanging transactions, plus 
minor code cleanups
9b56f3e is described below

commit 9b56f3e95fb3d6a80e0ab46b35c779ce01332b0d
Author: Christian Grothoff <address@hidden>
AuthorDate: Mon Mar 12 12:29:46 2018 +0100

    implementing #5281 guards against hanging transactions, plus minor code 
cleanups
---
 .gitignore                                         |  1 +
 src/backend/taler-merchant-httpd_check-payment.c   |  8 ++-
 src/backend/taler-merchant-httpd_exchanges.c       |  4 +-
 src/backend/taler-merchant-httpd_history.c         |  3 +-
 src/backend/taler-merchant-httpd_pay.c             |  5 +-
 src/backend/taler-merchant-httpd_proposal.c        |  4 +-
 src/backend/taler-merchant-httpd_refund.c          |  2 +
 src/backend/taler-merchant-httpd_tip-authorize.c   |  1 +
 src/backend/taler-merchant-httpd_tip-pickup.c      |  1 +
 src/backend/taler-merchant-httpd_tip-query.c       | 44 +++++++++-----
 .../taler-merchant-httpd_track-transaction.c       | 20 ++++---
 src/backend/taler-merchant-httpd_track-transfer.c  | 11 ++--
 src/backenddb/plugin_merchantdb_postgres.c         | 67 +++++++++++++++++++---
 src/include/taler_merchantdb_plugin.h              | 16 +++++-
 14 files changed, 141 insertions(+), 46 deletions(-)

diff --git a/.gitignore b/.gitignore
index 9ebe683..661e10f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,3 +58,4 @@ contrib/taler-merchant.tag
 src/merchant-tools/taler-merchant-tip-enable
 src/lib/reserve_dkey.priv
 src/lib/reserve_key.priv
+doc/version.texi
diff --git a/src/backend/taler-merchant-httpd_check-payment.c 
b/src/backend/taler-merchant-httpd_check-payment.c
index 8366186..60cd035 100644
--- a/src/backend/taler-merchant-httpd_check-payment.c
+++ b/src/backend/taler-merchant-httpd_check-payment.c
@@ -58,7 +58,10 @@ process_refunds_cb (void *cls,
 {
   struct TALER_Amount *acc_amount = cls;
 
-  GNUNET_assert (TALER_amount_add (acc_amount, acc_amount, refund_amount));
+  GNUNET_assert (GNUNET_SYSERR !=
+                 TALER_amount_add (acc_amount,
+                                   acc_amount,
+                                   refund_amount));
 }
 
 
@@ -187,6 +190,7 @@ MH_handler_check_payment (struct TMH_RequestHandler *rh,
 
   GNUNET_assert (NULL != order_id);
 
+  db->preflight (db->cls);
   qs = db->find_contract_terms (db->cls,
                                 &contract_terms,
                                 &last_session_id,
@@ -250,7 +254,7 @@ MH_handler_check_payment (struct TMH_RequestHandler *rh,
   /* Check if paid */
   {
     json_t *xcontract_terms = NULL;
-    
+
     qs = db->find_paid_contract_terms_from_hash (db->cls,
                                                  &xcontract_terms,
                                                  &h_contract_terms,
diff --git a/src/backend/taler-merchant-httpd_exchanges.c 
b/src/backend/taler-merchant-httpd_exchanges.c
index c82e831..1c90f00 100644
--- a/src/backend/taler-merchant-httpd_exchanges.c
+++ b/src/backend/taler-merchant-httpd_exchanges.c
@@ -360,8 +360,10 @@ process_wire_fees (void *cls,
                wire_method,
                GNUNET_STRINGS_absolute_time_to_string (af->start_date),
                TALER_amount2s (&af->wire_fee));
+    db->preflight (db->cls);
     if (GNUNET_OK !=
-        db->start (db->cls))
+        db->start (db->cls,
+                   "store wire fee"))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Failed to start database transaction!\n");
diff --git a/src/backend/taler-merchant-httpd_history.c 
b/src/backend/taler-merchant-httpd_history.c
index 53adf30..207ddca 100644
--- a/src/backend/taler-merchant-httpd_history.c
+++ b/src/backend/taler-merchant-httpd_history.c
@@ -174,8 +174,9 @@ MH_handler_history (struct TMH_RequestHandler *rh,
                                          "instance");
   }
 
-  /* Here goes the cherry-picking logic */
+  db->preflight (db->cls);
 
+  /* Here goes the cherry-picking logic */
   str = MHD_lookup_connection_value (connection,
                                      MHD_GET_ARGUMENT_KIND,
                                      "order_id");
diff --git a/src/backend/taler-merchant-httpd_pay.c 
b/src/backend/taler-merchant-httpd_pay.c
index b112edf..eee23c1 100644
--- a/src/backend/taler-merchant-httpd_pay.c
+++ b/src/backend/taler-merchant-httpd_pay.c
@@ -1651,7 +1651,10 @@ begin_transaction (struct PayContext *pc)
   GNUNET_assert (GNUNET_YES == pc->suspended);
 
   /* First, try to see if we have all we need already done */
-  if (GNUNET_OK != db->start (db->cls))
+  db->preflight (db->cls);
+  if (GNUNET_OK !=
+      db->start (db->cls,
+                 "run pay"))
   {
     GNUNET_break (0);
     resume_pay_with_error (pc,
diff --git a/src/backend/taler-merchant-httpd_proposal.c 
b/src/backend/taler-merchant-httpd_proposal.c
index 60f8941..64517b3 100644
--- a/src/backend/taler-merchant-httpd_proposal.c
+++ b/src/backend/taler-merchant-httpd_proposal.c
@@ -580,7 +580,6 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
     return TMH_RESPONSE_reply_arg_missing (connection,
                                           TALER_EC_PARAMETER_MISSING,
                                            "instance");
-
   mi = TMH_lookup_instance (instance);
   if (NULL == mi)
     return TMH_RESPONSE_reply_not_found (connection,
@@ -593,7 +592,6 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
     return TMH_RESPONSE_reply_arg_missing (connection,
                                           TALER_EC_PARAMETER_MISSING,
                                            "order_id");
-
   nonce = MHD_lookup_connection_value (connection,
                                        MHD_GET_ARGUMENT_KIND,
                                        "nonce");
@@ -601,7 +599,7 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh,
     return TMH_RESPONSE_reply_arg_missing (connection,
                                           TALER_EC_PARAMETER_MISSING,
                                            "nonce");
-
+  db->preflight (db->cls);
   qs = db->find_contract_terms (db->cls,
                                &contract_terms,
                                 &last_session_id,
diff --git a/src/backend/taler-merchant-httpd_refund.c 
b/src/backend/taler-merchant-httpd_refund.c
index 8a6060c..7498cd4 100644
--- a/src/backend/taler-merchant-httpd_refund.c
+++ b/src/backend/taler-merchant-httpd_refund.c
@@ -181,6 +181,8 @@ MH_handler_refund_increase (struct TMH_RequestHandler *rh,
                                         "Unknown instance given");
   }
 
+  db->preflight (db->cls);
+
   /* Convert order id to h_contract_terms */
   qs = db->find_contract_terms (db->cls,
                                &contract_terms,
diff --git a/src/backend/taler-merchant-httpd_tip-authorize.c 
b/src/backend/taler-merchant-httpd_tip-authorize.c
index 03d8ed3..ebef344 100644
--- a/src/backend/taler-merchant-httpd_tip-authorize.c
+++ b/src/backend/taler-merchant-httpd_tip-authorize.c
@@ -370,6 +370,7 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh,
                                         "exchange for tipping not configured 
for the instance");
   }
   tac->reserve_priv = mi->tip_reserve;
+  db->preflight (db->cls);
   ec = db->authorize_tip (db->cls,
                           tac->justification,
                           &tac->amount,
diff --git a/src/backend/taler-merchant-httpd_tip-pickup.c 
b/src/backend/taler-merchant-httpd_tip-pickup.c
index 3cc73af..7b3403d 100644
--- a/src/backend/taler-merchant-httpd_tip-pickup.c
+++ b/src/backend/taler-merchant-httpd_tip-pickup.c
@@ -554,6 +554,7 @@ MH_handler_tip_pickup (struct TMH_RequestHandler *rh,
                                  TALER_EC_PARAMETER_MALFORMED,
                                  "no planchets specified");
   }
+  db->preflight (db->cls);
   pc->planchets = GNUNET_new_array (pc->planchets_len,
                                    struct PlanchetDetail);
   for (unsigned int i=0;i<pc->planchets_len;i++)
diff --git a/src/backend/taler-merchant-httpd_tip-query.c 
b/src/backend/taler-merchant-httpd_tip-query.c
index 97d3fd1..bdf93be 100644
--- a/src/backend/taler-merchant-httpd_tip-query.c
+++ b/src/backend/taler-merchant-httpd_tip-query.c
@@ -222,7 +222,9 @@ handle_status (void *cls,
     return;
   }
 
-  if (GNUNET_OK != TALER_amount_get_zero (history[0].amount.currency, 
&tqc->amount_withdrawn))
+  if (GNUNET_OK !=
+      TALER_amount_get_zero (history[0].amount.currency,
+                             &tqc->amount_withdrawn))
   {
     GNUNET_break_op (0);
     resume_with_response (tqc, MHD_HTTP_SERVICE_UNAVAILABLE,
@@ -232,8 +234,8 @@ handle_status (void *cls,
   }
 
   if (GNUNET_YES == tqc->none_authorized)
-    memcpy (&tqc->amount_authorized, &tqc->amount_withdrawn, sizeof (struct 
TALER_Amount));
-  memcpy (&tqc->amount_deposited, &tqc->amount_withdrawn, sizeof (struct 
TALER_Amount));
+    tqc->amount_authorized = tqc->amount_withdrawn;
+  tqc->amount_deposited = tqc->amount_withdrawn;
 
   /* Update DB based on status! */
   for (unsigned int i=0;i<history_length;i++)
@@ -255,12 +257,14 @@ handle_status (void *cls,
                                      &uuid,
                                      &history[i].amount,
                                      expiration);
-        if (GNUNET_OK != TALER_amount_add (&tqc->amount_deposited,
-                                           &tqc->amount_deposited,
-                                           &history[i].amount))
+        if (GNUNET_OK !=
+            TALER_amount_add (&tqc->amount_deposited,
+                              &tqc->amount_deposited,
+                              &history[i].amount))
         {
           GNUNET_break_op (0);
-          resume_with_response (tqc, MHD_HTTP_SERVICE_UNAVAILABLE,
+          resume_with_response (tqc,
+                                MHD_HTTP_INTERNAL_SERVER_ERROR,
                                 TMH_RESPONSE_make_error (TALER_EC_NONE /* 
FIXME */,
                                                          "Exchange returned 
invalid reserve history (amount overflow)"));
           return;
@@ -275,12 +279,14 @@ handle_status (void *cls,
       }
       break;
     case TALER_EXCHANGE_RTT_WITHDRAWAL:
-      if (GNUNET_OK != TALER_amount_add (&tqc->amount_withdrawn,
-                                         &tqc->amount_withdrawn,
-                                         &history[i].amount))
+      if (GNUNET_OK !=
+          TALER_amount_add (&tqc->amount_withdrawn,
+                            &tqc->amount_withdrawn,
+                            &history[i].amount))
       {
         GNUNET_break_op (0);
-        resume_with_response (tqc, MHD_HTTP_SERVICE_UNAVAILABLE,
+        resume_with_response (tqc,
+                              MHD_HTTP_INTERNAL_SERVER_ERROR,
                               TMH_RESPONSE_make_error (TALER_EC_NONE /* FIXME 
*/,
                                                        "Exchange returned 
invalid reserve history (amount overflow)"));
         return;
@@ -300,20 +306,27 @@ handle_status (void *cls,
   {
     struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub;
     struct TALER_Amount amount_available;
+
     GNUNET_CRYPTO_eddsa_key_get_public (&tqc->reserve_priv.eddsa_priv,
                                         &reserve_pub);
-    if (GNUNET_SYSERR == TALER_amount_subtract (&amount_available, 
&tqc->amount_deposited, &tqc->amount_withdrawn))
+    if (GNUNET_SYSERR ==
+        TALER_amount_subtract (&amount_available,
+                               &tqc->amount_deposited,
+                               &tqc->amount_withdrawn))
     {
         GNUNET_break_op (0);
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "amount overflow, deposited %s 
but withdrawn %s\n",
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "amount overflow, deposited %s but withdrawn %s\n",
                     TALER_amount_to_string (&tqc->amount_deposited),
                     TALER_amount_to_string (&tqc->amount_withdrawn));
 
-        resume_with_response (tqc, MHD_HTTP_SERVICE_UNAVAILABLE,
+        resume_with_response (tqc,
+                              MHD_HTTP_INTERNAL_SERVER_ERROR,
                               TMH_RESPONSE_make_error (TALER_EC_NONE /* FIXME 
*/,
                                                        "Exchange returned 
invalid reserve history (amount overflow)"));
     }
-    resume_with_response (tqc, MHD_HTTP_OK,
+    resume_with_response (tqc,
+                          MHD_HTTP_OK,
                           TMH_RESPONSE_make_json_pack ("{s:o, s:o, s:o, s:o, 
s:o}",
                                                        "reserve_pub",
                                                        
GNUNET_JSON_from_data_auto (&reserve_pub),
@@ -452,6 +465,7 @@ MH_handler_tip_query (struct TMH_RequestHandler *rh,
   }
   tqc->reserve_priv = mi->tip_reserve;
 
+  db->preflight (db->cls);
   {
     int qs;
     for (unsigned int i=0;i<MAX_RETRIES;i++)
diff --git a/src/backend/taler-merchant-httpd_track-transaction.c 
b/src/backend/taler-merchant-httpd_track-transaction.c
index 99bd33b..b5e76ee 100644
--- a/src/backend/taler-merchant-httpd_track-transaction.c
+++ b/src/backend/taler-merchant-httpd_track-transaction.c
@@ -248,7 +248,7 @@ struct TrackTransactionContext
    * URL of the exchange we currently have in @e eh.
    */
   const char *current_exchange;
-  
+
   /**
    * Handle we use to resolve transactions for a given WTID.
    */
@@ -669,9 +669,9 @@ wtid_cb (void *cls,
 
 
 /**
- * We have obtained all WTIDs, now prepare the response 
+ * We have obtained all WTIDs, now prepare the response
  *
- * @param tctx handle for the operation 
+ * @param tctx handle for the operation
  */
 static void
 generate_response (struct TrackTransactionContext *tctx)
@@ -786,7 +786,7 @@ generate_response (struct TrackTransactionContext *tctx)
  * Find the exchange to trace the next coin(s).
  *
  * @param tctx operation context
- */ 
+ */
 static void
 find_exchange (struct TrackTransactionContext *tctx);
 
@@ -973,7 +973,7 @@ coin_cb (void *cls,
  * Find the exchange to trace the next coin(s).
  *
  * @param tctx operation context
- */ 
+ */
 static void
 find_exchange (struct TrackTransactionContext *tctx)
 {
@@ -989,7 +989,7 @@ find_exchange (struct TrackTransactionContext *tctx)
                                            NULL,
                                            
&process_track_transaction_with_exchange,
                                            tctx);
-    
+
   }
   else
   {
@@ -1137,9 +1137,10 @@ MH_handler_track_transaction (struct TMH_RequestHandler 
*rh,
       GNUNET_JSON_spec_end()
     };
 
-    if (GNUNET_YES != GNUNET_JSON_parse (contract_terms,
-                                         spec,
-                                         NULL, NULL))
+    if (GNUNET_YES !=
+        GNUNET_JSON_parse (contract_terms,
+                           spec,
+                           NULL, NULL))
     {
       GNUNET_break (0);
       GNUNET_JSON_parse_free (spec);
@@ -1152,6 +1153,7 @@ MH_handler_track_transaction (struct TMH_RequestHandler 
*rh,
   }
 
   tctx->qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+  db->preflight (db->cls);
   qs = db->find_payments (db->cls,
                          &tctx->h_contract_terms,
                          &tctx->mi->pubkey,
diff --git a/src/backend/taler-merchant-httpd_track-transfer.c 
b/src/backend/taler-merchant-httpd_track-transfer.c
index 197947f..e22b51e 100644
--- a/src/backend/taler-merchant-httpd_track-transfer.c
+++ b/src/backend/taler-merchant-httpd_track-transfer.c
@@ -211,7 +211,7 @@ hashmap_free (void *cls,
               void *value)
 {
   struct TALER_Amount *amount = value;
-  
+
   GNUNET_free (amount);
   return GNUNET_YES;
 }
@@ -472,7 +472,7 @@ check_transfer (void *cls,
                                      "exchange_deposit_proof", exchange_proof,
                                      "conflict_offset", (json_int_t) 
rctx->current_offset,
                                      "exchange_transfer_proof", 
rctx->original_response,
-                                     "coin_pub", GNUNET_JSON_from_data_auto 
(coin_pub), 
+                                     "coin_pub", GNUNET_JSON_from_data_auto 
(coin_pub),
                                      "h_contract_terms", 
GNUNET_JSON_from_data_auto (&ttd->h_contract_terms),
                                      "amount_with_fee", TALER_JSON_from_amount 
(amount_with_fee),
                                      "deposit_fee", TALER_JSON_from_amount 
(deposit_fee));
@@ -483,7 +483,7 @@ check_transfer (void *cls,
 
 
 /**
- * Check that the given @a wire_fee is what the 
+ * Check that the given @a wire_fee is what the
  * @a exchange_pub should charge at the @a execution_time.
  * If the fee is correct (according to our database),
  * return #GNUNET_OK.  If we do not have the fee structure
@@ -546,7 +546,7 @@ check_wire_fee (struct TrackTransferContext *rctx,
   if (0 <= TALER_amount_cmp (&expected_fee,
                             wire_fee))
     return GNUNET_OK; /* expected_fee >= wire_fee */
-  
+
   /* Wire fee check failed, export proof to client */
   resume_track_transfer_with_response
     (rctx,
@@ -987,6 +987,7 @@ MH_handler_track_transfer (struct TMH_RequestHandler *rh,
   }
 
   /* Check if reply is already in database! */
+  db->preflight (db->cls);
   qs = db->find_proof_by_wtid (db->cls,
                               rctx->url,
                               &rctx->wtid,
@@ -1000,7 +1001,7 @@ MH_handler_track_transfer (struct TMH_RequestHandler *rh,
     GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
     return TMH_RESPONSE_reply_internal_error (connection,
                                              
TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED,
-                                             "Fail to query database about 
proofs");   
+                                             "Fail to query database about 
proofs");
   }
   if (0 != rctx->response_code)
   {
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index 48b7244..96a5de9 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2014, 2015, 2016, 2017 INRIA
+  (C) 2014-2018 INRIA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -51,6 +51,11 @@ struct PostgresClosure
    */
   const struct GNUNET_CONFIGURATION_Handle *cfg;
 
+  /**
+   * Name of the currently active transaction, NULL if none is active.
+   */
+  const char *transaction_name;
+
 };
 
 
@@ -700,10 +705,13 @@ check_connection (struct PostgresClosure *pg)
  * Start a transaction.
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param name unique name identifying the transaction (for debugging),
+ *             must point to a constant
  * @return #GNUNET_OK on success
  */
-int
-postgres_start (void *cls)
+static int
+postgres_start (void *cls,
+                const char *name)
 {
   struct PostgresClosure *pg = cls;
   PGresult *result;
@@ -725,6 +733,7 @@ postgres_start (void *cls)
     return GNUNET_SYSERR;
   }
   PQclear (result);
+  pg->transaction_name = name;
   return GNUNET_OK;
 }
 
@@ -748,6 +757,43 @@ postgres_rollback (void *cls)
   GNUNET_break (PGRES_COMMAND_OK ==
                 PQresultStatus (result));
   PQclear (result);
+  pg->transaction_name = NULL;
+}
+
+
+/**
+ * Do a pre-flight check that we are not in an uncommitted transaction.
+ * If we are, try to commit the previous transaction and output a warning.
+ * Does not return anything, as we will continue regardless of the outcome.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ */
+static void
+postgres_preflight (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  PGresult *result;
+  ExecStatusType status;
+
+  if (NULL == pg->transaction_name)
+    return; /* all good */
+  result = PQexec (pg->conn,
+                   "COMMIT");
+  status = PQresultStatus (result);
+  if (PGRES_COMMAND_OK == status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check committed transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check failed to commit transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  pg->transaction_name = NULL;
+  PQclear (result);
 }
 
 
@@ -767,6 +813,7 @@ postgres_commit (void *cls)
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Committing merchant DB transaction\n");
+  pg->transaction_name = NULL;
   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                             "end_transaction",
                                             params);
@@ -2181,7 +2228,6 @@ postgres_get_refunds_from_contract_terms_hash (void *cls,
   TALER_LOG_DEBUG ("Looking for refund %s + %s\n",
                    GNUNET_h2s (h_contract_terms),
                    TALER_B2S (merchant_pub));
-
   check_connection (pg);
   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
                                             
"find_refunds_from_contract_terms_hash",
@@ -2702,7 +2748,8 @@ postgres_increase_refund_for_contract (void *cls,
               TALER_amount2s (refund),
               GNUNET_h2s (h_contract_terms));
   if (GNUNET_OK !=
-      postgres_start (cls))
+      postgres_start (cls,
+                      "increase refund"))
   {
     GNUNET_break (0);
     return GNUNET_DB_STATUS_HARD_ERROR;
@@ -2835,7 +2882,8 @@ postgres_enable_tip_reserve (void *cls,
   if (MAX_RETRIES < ++retries)
     return GNUNET_DB_STATUS_SOFT_ERROR;
   if (GNUNET_OK !=
-      postgres_start (pg))
+      postgres_start (pg,
+                      "enable tip reserve"))
   {
     GNUNET_break (0);
     return GNUNET_DB_STATUS_HARD_ERROR;
@@ -3039,7 +3087,8 @@ postgres_authorize_tip (void *cls,
   if (MAX_RETRIES < ++retries)
     return TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR;
   if (GNUNET_OK !=
-      postgres_start (pg))
+      postgres_start (pg,
+                      "authorize tip"))
   {
     GNUNET_break (0);
     return TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR;
@@ -3237,7 +3286,8 @@ postgres_pickup_tip (void *cls,
   if (MAX_RETRIES < ++retries)
     return TALER_EC_TIP_PICKUP_DB_ERROR_SOFT;
   if (GNUNET_OK !=
-      postgres_start (pg))
+      postgres_start (pg,
+                      "pickup tip"))
   {
     GNUNET_break (0);
     return TALER_EC_TIP_PICKUP_DB_ERROR_HARD;
@@ -3455,6 +3505,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
   plugin->pickup_tip = &postgres_pickup_tip;
   plugin->start = postgres_start;
   plugin->commit = postgres_commit;
+  plugin->preflight = postgres_preflight;
   plugin->rollback = postgres_rollback;
 
   return plugin;
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index 6f497b0..614d5dd 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -758,10 +758,24 @@ struct TALER_MERCHANTDB_Plugin
    * Start a transaction.
    *
    * @param cls the `struct PostgresClosure` with the plugin-specific state
+   * @param name unique name identifying the transaction (for debugging),
+   *             must point to a constant
    * @return #GNUNET_OK on success
    */
   int
-  (*start) (void *cls);
+  (*start) (void *cls,
+            const char *name);
+
+
+  /**
+   * Do a pre-flight check that we are not in an uncommitted transaction.
+   * If we are, try to commit the previous transaction and output a warning.
+   * Does not return anything, as we will continue regardless of the outcome.
+   *
+   * @param cls the `struct PostgresClosure` with the plugin-specific state
+   */
+  void
+  (*preflight) (void *cls);
 
 
   /**

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



reply via email to

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