gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: more work on #6854


From: gnunet
Subject: [taler-merchant] branch master updated: more work on #6854
Date: Sun, 09 May 2021 12:43:43 +0200

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 a3a2ebcc more work on #6854
a3a2ebcc is described below

commit a3a2ebccce82c5378c3c096eee8e8fc3c4239f20
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun May 9 12:43:41 2021 +0200

    more work on #6854
---
 .../taler-merchant-httpd_private-post-transfers.c  | 115 ++++++++++++++-------
 1 file changed, 79 insertions(+), 36 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_private-post-transfers.c 
b/src/backend/taler-merchant-httpd_private-post-transfers.c
index 9a425e9c..4c844c8f 100644
--- a/src/backend/taler-merchant-httpd_private-post-transfers.c
+++ b/src/backend/taler-merchant-httpd_private-post-transfers.c
@@ -140,6 +140,12 @@ struct PostTransfersContext
    * Should we retry the transaction due to a serialization error?
    */
   bool soft_retry;
+
+  /**
+   * Did we just download the exchange reply?
+   */
+  bool downloaded;
+
 };
 
 
@@ -390,8 +396,18 @@ check_wire_fee (struct PostTransfersContext *ptc,
                                 &start_date,
                                 &end_date,
                                 &master_sig);
-  if (0 >= qs)
+  switch (qs)
   {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    GNUNET_break (0);
+    ptc->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+    ptc->response = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                          "lookup_wire_fee");
+    return GNUNET_SYSERR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    ptc->soft_retry = true;
+    return GNUNET_NO;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Failed to find wire fee for `%s' and method `%s' at %s in DB, 
accepting blindly that the fee is %s\n",
                 TALER_B2S (&ptc->master_pub),
@@ -400,6 +416,8 @@ check_wire_fee (struct PostTransfersContext *ptc,
                 TALER_amount2s (wire_fee));
     GNUNET_free (wire_method);
     return GNUNET_NO;
+  case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+    break;
   }
   if (0 <= TALER_amount_cmp (&expected_fee,
                              wire_fee))
@@ -639,8 +657,9 @@ verify_exchange_claim_cb (void *cls,
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     break;
   }
-  if (GNUNET_NO == ptc->check_transfer_result)
+  switch (ptc->check_transfer_result)
   {
+  case GNUNET_NO:
     /* Internal error: how can we have called #check_transfer()
        but still have no result? */
     GNUNET_break (0);
@@ -649,13 +668,13 @@ verify_exchange_claim_cb (void *cls,
       TALER_MHD_make_error (TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
                             "check_transfer_result must not be NULL");
     return;
-  }
-  if (GNUNET_SYSERR == ptc->check_transfer_result)
-  {
+  case GNUNET_SYSERR:
     /* #check_transfer() failed, report conflict! */
     GNUNET_break_op (0);
     GNUNET_assert (NULL != ptc->response);
     return;
+  case GNUNET_OK:
+    break;
   }
 }
 
@@ -750,9 +769,9 @@ transfer_summary_cb (void *cls,
  *         #GNUNET_NO otherwise.
  */
 static int
-hashmap_free (void *cls,
-              const struct GNUNET_HashCode *key,
-              void *value)
+hashmap_update_and_free (void *cls,
+                         const struct GNUNET_HashCode *key,
+                         void *value)
 {
   json_t *ja = cls;
   struct Entry *entry = value;
@@ -835,6 +854,33 @@ queue (struct PostTransfersContext *ptc)
 }
 
 
+/**
+ * Download transfer data from the exchange.
+ *
+ * @param ptc request context
+ */
+static void
+download (struct PostTransfersContext *ptc)
+{
+  ptc->downloaded = true;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Suspending POST /private/transfers handling while working with 
exchange\n");
+  MHD_suspend_connection (ptc->connection);
+  GNUNET_CONTAINER_DLL_insert (ptc_head,
+                               ptc_tail,
+                               ptc);
+  ptc->fo = TMH_EXCHANGES_find_exchange (ptc->exchange_url,
+                                         NULL,
+                                         GNUNET_NO,
+                                         &process_transfer_with_exchange,
+                                         ptc);
+  ptc->timeout_task
+    = GNUNET_SCHEDULER_add_delayed (TRANSFER_GENERIC_TIMEOUT,
+                                    &handle_transfer_timeout,
+                                    ptc);
+}
+
+
 MHD_RESULT
 TMH_private_post_transfers (const struct TMH_RequestHandler *rh,
                             struct MHD_Connection *connection,
@@ -856,7 +902,7 @@ TMH_private_post_transfers (const struct TMH_RequestHandler 
*rh,
   if ( (NULL != ptc->fo) ||
        (NULL != ptc->wdh) )
   {
-    /* likely old MHD version */
+    /* likely old MHD version causing spurious wake-up */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Not sure why we are here, should be suspended\n");
     return MHD_YES; /* still work in progress */
@@ -886,7 +932,7 @@ TMH_private_post_transfers (const struct TMH_RequestHandler 
*rh,
         : MHD_NO;
   }
 
-  /* Check if transfer data is in database! */
+  /* Check if transfer data is in database, if not, add it. */
   for (unsigned int retry = 0; retry<MAX_RETRIES; retry++)
   {
     struct GNUNET_TIME_Absolute execution_time;
@@ -926,13 +972,11 @@ TMH_private_post_transfers (const struct 
TMH_RequestHandler *rh,
       TMH_db->rollback (TMH_db->cls);
       continue;
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
-      /* Transfer unknown */
+      /* Transfer so far unknown */
       {
         uint64_t account_serial;
 
-        /* Either the record already exists (we should ignore this), or
-           the INSERT failed because we did not find the account based on
-           the given payto-URI and the instance. */
+        /* Make sure the bank account is configured. */
         qs = TMH_db->lookup_account (TMH_db->cls,
                                      ptc->hc->instance->settings.id,
                                      ptc->payto_uri,
@@ -1006,30 +1050,22 @@ TMH_private_post_transfers (const struct 
TMH_RequestHandler *rh,
         case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
           break;
         }
-
-        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                    "Suspending POST /private/transfers handling while working 
with exchange\n");
-        MHD_suspend_connection (connection);
-        GNUNET_CONTAINER_DLL_insert (ptc_head,
-                                     ptc_tail,
-                                     ptc);
-        ptc->fo = TMH_EXCHANGES_find_exchange (ptc->exchange_url,
-                                               NULL,
-                                               GNUNET_NO,
-                                               &process_transfer_with_exchange,
-                                               ptc);
-        ptc->timeout_task
-          = GNUNET_SCHEDULER_add_delayed (TRANSFER_GENERIC_TIMEOUT,
-                                          &handle_transfer_timeout,
-                                          ptc);
+        download (ptc);
         return MHD_YES;
-
       }
-      break;
     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
       /* Transfer exists */
       if (! verified)
       {
+        if (! ptc->downloaded)
+        {
+          /* We may have previously attempted and failed to
+             download the exchange data, do it again! */
+          TMH_db->rollback (TMH_db->cls);
+          download (ptc);
+          return MHD_YES;
+        }
+        /* verify */
         if (GNUNET_SYSERR ==
             check_wire_fee (ptc,
                             execution_time,
@@ -1038,6 +1074,13 @@ TMH_private_post_transfers (const struct 
TMH_RequestHandler *rh,
           TMH_db->rollback (TMH_db->cls);
           return queue (ptc); /* generate error */
         }
+        if (ptc->soft_retry)
+        {
+          /* DB serialization failure */
+          ptc->soft_retry = false;
+          TMH_db->rollback (TMH_db->cls);
+          continue;
+        }
         qs = TMH_db->lookup_transfer_details (TMH_db->cls,
                                               ptc->exchange_url,
                                               &ptc->wtid,
@@ -1096,7 +1139,8 @@ TMH_private_post_transfers (const struct 
TMH_RequestHandler *rh,
         }
       } /* end of 'if (! verified)' */
 
-      /* Short version: we already verified, generate the summary response */
+      /* Short version: we verified that the exchange reply and
+         our own accounting match; generate the summary response */
       GNUNET_assert (verified);
       {
         struct GNUNET_CONTAINER_MultiHashMap *map;
@@ -1118,7 +1162,7 @@ TMH_private_post_transfers (const struct 
TMH_RequestHandler *rh,
           GNUNET_break (0);
           TMH_db->rollback (TMH_db->cls);
           GNUNET_CONTAINER_multihashmap_iterate (map,
-                                                 &hashmap_free,
+                                                 &hashmap_update_and_free,
                                                  NULL);
           GNUNET_CONTAINER_multihashmap_destroy (map);
           return TALER_MHD_reply_with_error (connection,
@@ -1131,11 +1175,10 @@ TMH_private_post_transfers (const struct 
TMH_RequestHandler *rh,
           break;
         }
 
-
         deposit_sums = json_array ();
         GNUNET_assert (NULL != deposit_sums);
         GNUNET_CONTAINER_multihashmap_iterate (map,
-                                               &hashmap_free,
+                                               &hashmap_update_and_free,
                                                deposit_sums);
         GNUNET_CONTAINER_multihashmap_destroy (map);
         return TALER_MHD_reply_json_pack (

-- 
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]