gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: -adapt to latest exchange API ch


From: gnunet
Subject: [taler-merchant] branch master updated: -adapt to latest exchange API change
Date: Sun, 25 Jun 2023 16:09:15 +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 0d8aeec5 -adapt to latest exchange API change
0d8aeec5 is described below

commit 0d8aeec575f6e12bb06a5eedeabf70436058595a
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Jun 25 16:09:11 2023 +0200

    -adapt to latest exchange API change
---
 src/backend/taler-merchant-httpd_exchanges.c       | 402 +++++++++++++++++++++
 src/backend/taler-merchant-httpd_exchanges.h       |  80 ++++
 .../taler-merchant-httpd_post-orders-ID-pay.c      | 213 +++++------
 3 files changed, 580 insertions(+), 115 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_exchanges.c 
b/src/backend/taler-merchant-httpd_exchanges.c
index 090cef95..5bce19a4 100644
--- a/src/backend/taler-merchant-httpd_exchanges.c
+++ b/src/backend/taler-merchant-httpd_exchanges.c
@@ -103,6 +103,86 @@ struct TMH_EXCHANGES_FindOperation
 };
 
 
+/**
+ * Information we keep for a pending #MMH_EXCHANGES_keys4exchange() operation.
+ */
+struct TMH_EXCHANGES_Find2Operation
+{
+
+  /**
+   * Kept in a DLL.
+   */
+  struct TMH_EXCHANGES_Find2Operation *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct TMH_EXCHANGES_Find2Operation *prev;
+
+  /**
+   * Function to call with the result.
+   */
+  TMH_EXCHANGES_Find2Continuation fc;
+
+  /**
+   * Closure for @e fc.
+   */
+  void *fc_cls;
+
+  /**
+   * Exchange we wait for the /keys for.
+   */
+  struct TMH_Exchange *my_exchange;
+
+  /**
+   * Task scheduled to asynchronously return the result to
+   * the find continuation.
+   */
+  struct GNUNET_SCHEDULER_Task *at;
+
+};
+
+
+/**
+ * Information we keep for a pending #MMH_EXCHANGES_wire4exchange() operation.
+ */
+struct TMH_EXCHANGES_WireOperation
+{
+
+  /**
+   * Kept in a DLL.
+   */
+  struct TMH_EXCHANGES_WireOperation *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct TMH_EXCHANGES_WireOperation *prev;
+
+  /**
+   * Function to call with the result.
+   */
+  TMH_EXCHANGES_WireContinuation fc;
+
+  /**
+   * Closure for @e fc.
+   */
+  void *fc_cls;
+
+  /**
+   * Exchange we wait for the /wire for.
+   */
+  struct TMH_Exchange *my_exchange;
+
+  /**
+   * Task scheduled to asynchronously return the result to
+   * the find continuation.
+   */
+  struct GNUNET_SCHEDULER_Task *at;
+
+};
+
+
 /**
  * Information about wire transfer fees of an exchange, by wire method.
  */
@@ -239,6 +319,26 @@ struct TMH_Exchange
    */
   struct TMH_EXCHANGES_FindOperation *fo_tail;
 
+  /**
+   * Head of FOs pending for this exchange.
+   */
+  struct TMH_EXCHANGES_Find2Operation *fo2_head;
+
+  /**
+   * Tail of FOs pending for this exchange.
+   */
+  struct TMH_EXCHANGES_Find2Operation *fo2_tail;
+
+  /**
+   * Head of /wire pending for this exchange.
+   */
+  struct TMH_EXCHANGES_WireOperation *w_head;
+
+  /**
+   * Tail of /wire pending for this exchange.
+   */
+  struct TMH_EXCHANGES_WireOperation *w_tail;
+
   /**
    * Head of accounts of this exchange.
    */
@@ -891,8 +991,20 @@ static bool
 process_find_operations (struct TMH_Exchange *exchange)
 {
   struct TMH_EXCHANGES_FindOperation *fn;
+  struct TMH_EXCHANGES_Find2Operation *fn2;
+  struct TMH_EXCHANGES_WireOperation *wn;
   struct GNUNET_TIME_Timestamp now;
 
+  fn2 = NULL;
+  for (struct TMH_EXCHANGES_Find2Operation *fo = exchange->fo2_head;
+       NULL != fo;
+       fo = fn2)
+  {
+    fo->fc (fo->fc_cls,
+            TALER_EXCHANGE_get_keys (exchange->conn));
+    fn2 = fo->next;
+    TMH_EXCHANGES_keys4exchange_cancel (fo);
+  }
   if (! exchange->have_wire)
     return true;
   now = GNUNET_TIME_timestamp_get ();
@@ -957,6 +1069,16 @@ process_find_operations (struct TMH_Exchange *exchange)
     fn = fo->next;
     TMH_EXCHANGES_find_exchange_cancel (fo);
   }
+  wn = NULL;
+  for (struct TMH_EXCHANGES_WireOperation *w = exchange->w_head;
+       NULL != w;
+       w = wn)
+  {
+    w->fc (w->fc_cls,
+           exchange);
+    wn = w->next;
+    TMH_EXCHANGES_wire4exchange_cancel (w);
+  }
   return false;
 }
 
@@ -992,6 +1114,7 @@ handle_wire_data (void *cls,
   if (MHD_HTTP_OK != wr->hr.http_status)
   {
     struct TMH_EXCHANGES_FindOperation *fo;
+    struct TMH_EXCHANGES_WireOperation *w;
 
     exchange->have_wire = false;
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -1007,6 +1130,12 @@ handle_wire_data (void *cls,
               false);
       TMH_EXCHANGES_find_exchange_cancel (fo);
     }
+    while (NULL != (w = exchange->w_head))
+    {
+      w->fc (w->fc_cls,
+             NULL);
+      TMH_EXCHANGES_wire4exchange_cancel (w);
+    }
     return;
   }
   keys = TALER_EXCHANGE_get_keys (exchange->conn);
@@ -1024,6 +1153,7 @@ handle_wire_data (void *cls,
   {
     /* Report hard failure to all callbacks! */
     struct TMH_EXCHANGES_FindOperation *fo;
+    struct TMH_EXCHANGES_Find2Operation *fo2;
     struct TALER_EXCHANGE_HttpResponse hrx = {
       .ec = ecx,
       .http_status = 0,
@@ -1040,6 +1170,12 @@ handle_wire_data (void *cls,
               false);
       TMH_EXCHANGES_find_exchange_cancel (fo);
     }
+    while (NULL != (fo2 = exchange->fo2_head))
+    {
+      fo2->fc (fo2->fc_cls,
+               NULL);
+      TMH_EXCHANGES_keys4exchange_cancel (fo2);
+    }
     return;
   }
   exchange->have_wire = true;
@@ -1148,6 +1284,10 @@ free_exchange_entry (struct TMH_Exchange *exchange)
   }
   GNUNET_assert (NULL == exchange->fo_head);
   GNUNET_assert (NULL == exchange->fo_tail);
+  GNUNET_assert (NULL == exchange->fo2_head);
+  GNUNET_assert (NULL == exchange->fo2_tail);
+  GNUNET_assert (NULL == exchange->w_head);
+  GNUNET_assert (NULL == exchange->w_tail);
   GNUNET_free (exchange->url);
   GNUNET_free (exchange);
 }
@@ -1165,6 +1305,8 @@ fail_and_retry (struct TMH_Exchange *exchange,
                 const struct TALER_EXCHANGE_HttpResponse *hr)
 {
   struct TMH_EXCHANGES_FindOperation *fo;
+  struct TMH_EXCHANGES_Find2Operation *fo2;
+  struct TMH_EXCHANGES_WireOperation *w;
 
   exchange->have_keys = false;
   if (NULL != exchange->wire_request)
@@ -1185,6 +1327,18 @@ fail_and_retry (struct TMH_Exchange *exchange,
             false);
     TMH_EXCHANGES_find_exchange_cancel (fo);
   }
+  while (NULL != (fo2 = exchange->fo2_head))
+  {
+    fo2->fc (fo2->fc_cls,
+             NULL);
+    TMH_EXCHANGES_keys4exchange_cancel (fo2);
+  }
+  while (NULL != (w = exchange->w_head))
+  {
+    w->fc (w->fc_cls,
+           NULL);
+    TMH_EXCHANGES_wire4exchange_cancel (w);
+  }
   if ( (NULL == exchange->fo_head) &&
        (TALER_EC_GENERIC_CONFIGURATION_INVALID == hr->ec) )
   {
@@ -1344,6 +1498,38 @@ return_result (void *cls)
 }
 
 
+/**
+ * Task to return find operation result asynchronously to caller.
+ *
+ * @param cls a `struct TMH_EXCHANGES_Find2Operation`
+ */
+static void
+return_result2 (void *cls)
+{
+  struct TMH_EXCHANGES_Find2Operation *fo = cls;
+  struct TMH_Exchange *exchange = fo->my_exchange;
+
+  fo->at = NULL;
+  process_find_operations (exchange);
+}
+
+
+/**
+ * Task to return find operation result asynchronously to caller.
+ *
+ * @param cls a `struct TMH_EXCHANGES_WireOperation`
+ */
+static void
+return_wire_result (void *cls)
+{
+  struct TMH_EXCHANGES_WireOperation *w = cls;
+  struct TMH_Exchange *exchange = w->my_exchange;
+
+  w->at = NULL;
+  process_find_operations (exchange);
+}
+
+
 /**
  * Lookup exchange by @a exchange_url.
  *
@@ -1481,6 +1667,188 @@ TMH_EXCHANGES_find_exchange (const char 
*chosen_exchange,
 }
 
 
+struct TMH_EXCHANGES_Find2Operation *
+TMH_EXCHANGES_keys4exchange (
+  const char *chosen_exchange,
+  TMH_EXCHANGES_Find2Continuation fc,
+  void *fc_cls)
+{
+  struct TMH_Exchange *exchange;
+  struct TMH_EXCHANGES_Find2Operation *fo;
+
+  if (NULL == merchant_curl_ctx)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Trying to find chosen exchange `%s'\n",
+              chosen_exchange);
+  /* Check if the exchange is known */
+  exchange = lookup_exchange (chosen_exchange);
+  if (NULL == exchange)
+  {
+    /* This is a new exchange */
+    exchange = GNUNET_new (struct TMH_Exchange);
+    exchange->url = GNUNET_strdup (chosen_exchange);
+    GNUNET_CONTAINER_DLL_insert (exchange_head,
+                                 exchange_tail,
+                                 exchange);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "The exchange `%s' is new\n",
+                chosen_exchange);
+  }
+
+  fo = GNUNET_new (struct TMH_EXCHANGES_Find2Operation);
+  fo->fc = fc;
+  fo->fc_cls = fc_cls;
+  fo->my_exchange = exchange;
+  GNUNET_CONTAINER_DLL_insert (exchange->fo2_head,
+                               exchange->fo2_tail,
+                               fo);
+
+  if (GNUNET_TIME_absolute_is_past (exchange->first_retry))
+  {
+    /* increment exponential-backoff */
+    exchange->retry_delay = RETRY_BACKOFF (exchange->retry_delay);
+    /* do not allow forced check until both backoff and #FORCED_RELOAD_DELAY
+       are satisfied again */
+    exchange->first_retry
+      = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_max (
+                                            exchange->retry_delay,
+                                            FORCED_RELOAD_DELAY));
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "/keys retry forced, waiting until %s\n",
+                GNUNET_TIME_absolute2s (exchange->first_retry));
+    if (NULL == exchange->conn)
+    {
+      /* Not connected at all yet */
+      exchange->retry_task
+        = GNUNET_SCHEDULER_add_now (&retry_exchange,
+                                    exchange);
+    }
+    else
+    {
+      /* Use existing connection, but update /keys */
+      exchange->keys_expiration
+        = TALER_EXCHANGE_check_keys_current (exchange->conn,
+                                             TALER_EXCHANGE_CKF_FORCE_DOWNLOAD,
+                                             NULL,
+                                             NULL);
+    }
+    return fo;
+  }
+
+  if (exchange->have_keys)
+  {
+    /* We are not currently waiting for a reply, immediately
+       return result */
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "The exchange `%s' is ready\n",
+                exchange->url);
+    GNUNET_assert (NULL == fo->at);
+    fo->at = GNUNET_SCHEDULER_add_now (&return_result2,
+                                       fo);
+    return fo;
+  }
+
+  /* If new or resumed, (re)try fetching /keys */
+  if ( (NULL == exchange->conn) &&
+       (NULL == exchange->retry_task) &&
+       (! exchange->have_keys) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Do not have current /keys data for `%s'. Will request /keys 
now\n",
+                exchange->url);
+    exchange->retry_task = GNUNET_SCHEDULER_add_now (&retry_exchange,
+                                                     exchange);
+    return fo;
+  }
+  /* No activity to launch, we are already doing so */
+  return fo;
+}
+
+
+struct TMH_EXCHANGES_WireOperation *
+TMH_EXCHANGES_wire4exchange (
+  const char *chosen_exchange,
+  TMH_EXCHANGES_WireContinuation fc,
+  void *fc_cls)
+{
+  struct TMH_Exchange *exchange;
+  struct TMH_EXCHANGES_WireOperation *w;
+
+  if (NULL == merchant_curl_ctx)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Trying to find chosen exchange `%s'\n",
+              chosen_exchange);
+  /* Check if the exchange is known */
+  exchange = lookup_exchange (chosen_exchange);
+  if (NULL == exchange)
+  {
+    /* This is a new exchange */
+    exchange = GNUNET_new (struct TMH_Exchange);
+    exchange->url = GNUNET_strdup (chosen_exchange);
+    GNUNET_CONTAINER_DLL_insert (exchange_head,
+                                 exchange_tail,
+                                 exchange);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "The exchange `%s' is new\n",
+                chosen_exchange);
+  }
+
+  w = GNUNET_new (struct TMH_EXCHANGES_WireOperation);
+  w->fc = fc;
+  w->fc_cls = fc_cls;
+  w->my_exchange = exchange;
+  GNUNET_CONTAINER_DLL_insert (exchange->w_head,
+                               exchange->w_tail,
+                               w);
+  if (exchange->have_wire)
+  {
+    /* We are not currently waiting for a reply, immediately
+       return result */
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "The exchange `%s' is ready\n",
+                exchange->url);
+    GNUNET_assert (NULL == w->at);
+    w->at = GNUNET_SCHEDULER_add_now (&return_wire_result,
+                                      w);
+    return w;
+  }
+
+  if (NULL == exchange->wire_request)
+  {
+    if (NULL == exchange->conn)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Requesting /keys from `%s' to connect\n",
+                  exchange->url);
+      exchange->conn = TALER_EXCHANGE_connect (merchant_curl_ctx,
+                                               exchange->url,
+                                               &keys_mgmt_cb,
+                                               exchange,
+                                               TALER_EXCHANGE_OPTION_END);
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Requesting /wire from `%s'\n",
+                  exchange->url);
+      exchange->wire_request
+        = TALER_EXCHANGE_wire (exchange->conn,
+                               &handle_wire_data,
+                               exchange);
+    }
+  }
+  return w;
+}
+
+
 void
 TMH_EXCHANGES_find_exchange_cancel (struct TMH_EXCHANGES_FindOperation *fo)
 {
@@ -1498,6 +1866,40 @@ TMH_EXCHANGES_find_exchange_cancel (struct 
TMH_EXCHANGES_FindOperation *fo)
 }
 
 
+void
+TMH_EXCHANGES_keys4exchange_cancel (struct TMH_EXCHANGES_Find2Operation *fo)
+{
+  struct TMH_Exchange *exchange = fo->my_exchange;
+
+  if (NULL != fo->at)
+  {
+    GNUNET_SCHEDULER_cancel (fo->at);
+    fo->at = NULL;
+  }
+  GNUNET_CONTAINER_DLL_remove (exchange->fo2_head,
+                               exchange->fo2_tail,
+                               fo);
+  GNUNET_free (fo);
+}
+
+
+void
+TMH_EXCHANGES_wire4exchange_cancel (struct TMH_EXCHANGES_WireOperation *w)
+{
+  struct TMH_Exchange *exchange = w->my_exchange;
+
+  if (NULL != w->at)
+  {
+    GNUNET_SCHEDULER_cancel (w->at);
+    w->at = NULL;
+  }
+  GNUNET_CONTAINER_DLL_remove (exchange->w_head,
+                               exchange->w_tail,
+                               w);
+  GNUNET_free (w);
+}
+
+
 /**
  * Function called on each configuration section. Finds sections
  * about exchanges, parses the entries and tries to connect to
diff --git a/src/backend/taler-merchant-httpd_exchanges.h 
b/src/backend/taler-merchant-httpd_exchanges.h
index 23424f40..89ba4030 100644
--- a/src/backend/taler-merchant-httpd_exchanges.h
+++ b/src/backend/taler-merchant-httpd_exchanges.h
@@ -99,11 +99,47 @@ typedef void
   struct TMH_Exchange *ih);
 
 
+/**
+ * Function called with the result of a #TMH_EXCHANGES_keys4exchange()
+ * operation.
+ *
+ * @param cls closure
+ * @param keys the keys of the exchange
+ */
+typedef void
+(*TMH_EXCHANGES_Find2Continuation)(
+  void *cls,
+  struct TALER_EXCHANGE_Keys *keys);
+
+
+/**
+ * Function called with the result of a #TMH_EXCHANGES_wire4exchange()
+ * operation.
+ *
+ * @param cls closure
+ * @param wire the wire data of the exchange
+ */
+typedef void
+(*TMH_EXCHANGES_WireContinuation)(
+  void *cls,
+  struct TMH_Exchange *wire);
+
+
 /**
  * Information we keep for a pending #MMH_EXCHANGES_find_exchange() operation.
  */
 struct TMH_EXCHANGES_FindOperation;
 
+/**
+ * Information we keep for a pending #MMH_EXCHANGES_keys4exchange() operation.
+ */
+struct TMH_EXCHANGES_Find2Operation;
+
+/**
+ * Information we keep for a pending #MMH_EXCHANGES_wire4exchange() operation.
+ */
+struct TMH_EXCHANGES_WireOperation;
+
 
 /**
  * Find a exchange that matches @a chosen_exchange. If we cannot connect
@@ -123,6 +159,32 @@ TMH_EXCHANGES_find_exchange (const char *chosen_exchange,
                              void *fc_cls);
 
 
+/**
+ * Get /keys of the given @a exchange.
+ *
+ * @param exchange URL of the exchange we would like to talk to
+ * @param fc function to call with the handles for the exchange
+ * @param fc_cls closure for @a fc
+ */
+struct TMH_EXCHANGES_Find2Operation *
+TMH_EXCHANGES_keys4exchange (const char *exchange,
+                             TMH_EXCHANGES_Find2Continuation fc,
+                             void *fc_cls);
+
+
+/**
+ * Get /wire of the given @a exchange.
+ *
+ * @param exchange URL of the exchange we would like to talk to
+ * @param fc function to call with the handles for the exchange
+ * @param fc_cls closure for @a fc
+ */
+struct TMH_EXCHANGES_WireOperation *
+TMH_EXCHANGES_wire4exchange (const char *exchange,
+                             TMH_EXCHANGES_WireContinuation fc,
+                             void *fc_cls);
+
+
 /**
  * Lookup current wire fee by @a exchange_url and
  * @a wire_method.
@@ -149,4 +211,22 @@ void
 TMH_EXCHANGES_find_exchange_cancel (struct TMH_EXCHANGES_FindOperation *fo);
 
 
+/**
+ * Abort pending keys details lookup operation.
+ *
+ * @param fo handle to operation to abort
+ */
+void
+TMH_EXCHANGES_keys4exchange_cancel (struct TMH_EXCHANGES_Find2Operation *fo);
+
+
+/**
+ * Abort pending wire details lookup operation.
+ *
+ * @param fo handle to operation to abort
+ */
+void
+TMH_EXCHANGES_wire4exchange_cancel (struct TMH_EXCHANGES_WireOperation *fo);
+
+
 #endif
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index 04224ac5..28ba72df 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -69,12 +69,6 @@ struct DepositConfirmation
    */
   struct PayContext *pc;
 
-  /**
-   * Handle to the deposit operation we are performing for
-   * this coin, NULL after the operation is done.
-   */
-  struct TALER_EXCHANGE_DepositHandle *dh;
-
   /**
    * URL of the exchange that issued this coin.
    */
@@ -179,7 +173,14 @@ struct ExchangeGroup
    * the exchange used for this transaction; NULL if no operation is
    * pending.
    */
-  struct TMH_EXCHANGES_FindOperation *fo;
+  struct TMH_EXCHANGES_Find2Operation *fo;
+
+  /**
+   * Handle for operation to lookup /wire from
+   * the exchange used for this transaction; NULL if no operation is
+   * pending.
+   */
+  struct TMH_EXCHANGES_WireOperation *gwo;
 
   /**
    * URL of the exchange that issued this coin. Aliases
@@ -570,29 +571,6 @@ get_pay_timeout (unsigned int num_coins)
 }
 
 
-/**
- * Abort all pending /deposit operations.
- *
- * @param pc pay context to abort
- */
-static void
-abort_active_deposits (struct PayContext *pc)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Aborting pending /deposit operations\n");
-  for (unsigned int i = 0; i<pc->coins_cnt; i++)
-  {
-    struct DepositConfirmation *dci = &pc->dc[i];
-
-    if (NULL != dci->dh)
-    {
-      TALER_EXCHANGE_deposit_cancel (dci->dh);
-      dci->dh = NULL;
-    }
-  }
-}
-
-
 void
 TMH_force_pc_resume ()
 {
@@ -609,7 +587,6 @@ TMH_force_pc_resume ()
        NULL != pc;
        pc = pc->next)
   {
-    abort_active_deposits (pc);
     if (NULL != pc->timeout_task)
     {
       GNUNET_SCHEDULER_cancel (pc->timeout_task);
@@ -638,7 +615,6 @@ resume_pay_with_response (struct PayContext *pc,
                           unsigned int response_code,
                           struct MHD_Response *response)
 {
-  abort_active_deposits (pc);
   pc->response_code = response_code;
   pc->response = response;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -697,7 +673,6 @@ pay_context_cleanup (void *cls)
     json_decref (pc->contract_terms);
     pc->contract_terms = NULL;
   }
-  abort_active_deposits (pc);
   for (unsigned int i = 0; i<pc->coins_cnt; i++)
   {
     struct DepositConfirmation *dc = &pc->dc[i];
@@ -711,7 +686,9 @@ pay_context_cleanup (void *cls)
     struct ExchangeGroup *eg = pc->egs[i];
 
     if (NULL != eg->fo)
-      TMH_EXCHANGES_find_exchange_cancel (eg->fo);
+      TMH_EXCHANGES_keys4exchange_cancel (eg->fo);
+    if (NULL != eg->gwo)
+      TMH_EXCHANGES_wire4exchange_cancel (eg->gwo);
     GNUNET_free (eg);
   }
   GNUNET_free (pc->egs);
@@ -1170,35 +1147,29 @@ batch_deposit_cb (
 
 
 /**
- * Function called with the result of our exchange lookup.
+ * Function called with the result of our exchange keys lookup.
  *
  * @param cls the `struct ExchangeGroup`
- * @param hr HTTP response details
- * @param exchange_handle NULL if exchange was not found to be acceptable
- * @param ih internal handle to the exchange
+ * @param keys the keys of the exchange
  */
 static void
-process_pay_with_exchange (
+process_pay_with_keys (
   void *cls,
-  const struct TALER_EXCHANGE_HttpResponse *hr,
-  struct TALER_EXCHANGE_Handle *exchange_handle,
-  struct TMH_Exchange *ih)
+  struct TALER_EXCHANGE_Keys *keys)
 {
   struct ExchangeGroup *eg = cls;
   struct PayContext *pc = eg->pc;
   struct TMH_HandlerContext *hc = pc->hc;
-  const struct TALER_EXCHANGE_Keys *keys;
   unsigned int group_size;
 
   eg->fo = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Processing payment with exchange %s\n",
-              (NULL == exchange_handle)
-              ? "<null>"
-              : TALER_EXCHANGE_get_base_url (exchange_handle));
+              eg->exchange_url);
   GNUNET_assert (GNUNET_YES == pc->suspended);
-  if (NULL == hr)
+  if (NULL == keys)
   {
+    GNUNET_break_op (0);
     pc->pending_at_eg--;
     resume_pay_with_response (
       pc,
@@ -1207,45 +1178,6 @@ process_pay_with_exchange (
         TALER_JSON_pack_ec (TALER_EC_MERCHANT_GENERIC_EXCHANGE_TIMEOUT)));
     return;
   }
-  if ( (MHD_HTTP_OK != hr->http_status) ||
-       (NULL == exchange_handle) )
-  {
-    pc->pending_at_eg--;
-    resume_pay_with_response (
-      pc,
-      MHD_HTTP_BAD_GATEWAY,
-      TALER_MHD_MAKE_JSON_PACK (
-        TALER_JSON_pack_ec (
-          TALER_EC_MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE),
-        TMH_pack_exchange_reply (hr)));
-    return;
-  }
-  if (GNUNET_OK !=
-      TMH_exchange_check_debit (ih,
-                                pc->wm))
-  {
-    GNUNET_break_op (0);
-    pc->pending_at_eg--;
-    resume_pay_with_response (
-      pc,
-      MHD_HTTP_CONFLICT,
-      TALER_MHD_MAKE_JSON_PACK (
-        TALER_JSON_pack_ec (
-          TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED)));
-    return;
-  }
-
-  keys = TALER_EXCHANGE_get_keys (exchange_handle);
-  if (NULL == keys)
-  {
-    pc->pending_at_eg--;
-    GNUNET_break (0); /* should not be possible if HTTP status is #MHD_HTTP_OK 
*/
-    resume_pay_with_error (pc,
-                           MHD_HTTP_BAD_GATEWAY,
-                           TALER_EC_MERCHANT_GENERIC_EXCHANGE_KEYS_FAILURE,
-                           NULL);
-    return;
-  }
 
   /* Initiate /batch-deposit operation for all coins of
      the current exchange (!) */
@@ -1267,21 +1199,6 @@ process_pay_with_exchange (
                                                      &dc->cdd.h_denom_pub);
     if (NULL == denom_details)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  "Denomination not found, re-fetching /keys\n");
-      if (! eg->tried_force_keys)
-      {
-        /* let's try *forcing* a re-download of /keys from the exchange.
-           Maybe the wallet has seen /keys that we missed. */
-        eg->tried_force_keys = true;
-        eg->fo = TMH_EXCHANGES_find_exchange (eg->exchange_url,
-                                              true,
-                                              &process_pay_with_exchange,
-                                              eg);
-        if (NULL != eg->fo)
-          return;
-      }
-      /* Forcing failed or we already did it, give up */
       pc->pending_at_eg--;
       resume_pay_with_response (
         pc,
@@ -1292,9 +1209,9 @@ process_pay_with_exchange (
           GNUNET_JSON_pack_data_auto ("h_denom_pub",
                                       &dc->cdd.h_denom_pub),
           GNUNET_JSON_pack_allow_null (
-            GNUNET_JSON_pack_object_incref (
+            GNUNET_JSON_pack_object_steal (
               "exchange_keys",
-              (json_t *) TALER_EXCHANGE_get_keys_raw (exchange_handle)))));
+              TALER_EXCHANGE_keys_to_json (keys)))));
       return;
     }
     dc->deposit_fee = denom_details->fees.deposit;
@@ -1458,13 +1375,16 @@ AGE_FAIL:
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Initiating batch deposit with %u coins\n",
                 group_size);
-    eg->bdh = TALER_EXCHANGE_batch_deposit (exchange_handle,
-                                            &dcd,
-                                            group_size,
-                                            cdds,
-                                            &batch_deposit_cb,
-                                            eg,
-                                            &ec);
+    eg->bdh = TALER_EXCHANGE_batch_deposit (
+      merchant_curl_ctx,
+      eg->exchange_url,
+      keys,
+      &dcd,
+      group_size,
+      cdds,
+      &batch_deposit_cb,
+      eg,
+      &ec);
     if (NULL == eg->bdh)
     {
       /* Signature was invalid or some other constraint was not satisfied.  If
@@ -1487,6 +1407,67 @@ AGE_FAIL:
 }
 
 
+/**
+ * Function called with the result of our exchange lookup.
+ *
+ * @param cls the `struct ExchangeGroup`
+ * @param keys the keys of the exchange
+ */
+static void
+process_pay_with_wire (
+  void *cls,
+  struct TMH_Exchange *wire)
+{
+  struct ExchangeGroup *eg = cls;
+  struct PayContext *pc = eg->pc;
+
+  eg->gwo = NULL;
+  if (NULL == wire)
+  {
+    GNUNET_break_op (0);
+    pc->pending_at_eg--;
+    /* FIXME: define more specific error code... */
+    resume_pay_with_response (
+      pc,
+      MHD_HTTP_BAD_GATEWAY,
+      TALER_MHD_MAKE_JSON_PACK (
+        TALER_JSON_pack_ec (
+          TALER_EC_MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE)));
+    return;
+  }
+  if (GNUNET_OK !=
+      TMH_exchange_check_debit (wire,
+                                pc->wm))
+  {
+    GNUNET_break_op (0);
+    pc->pending_at_eg--;
+    resume_pay_with_response (
+      pc,
+      MHD_HTTP_CONFLICT,
+      TALER_MHD_MAKE_JSON_PACK (
+        TALER_JSON_pack_ec (
+          TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED)));
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Fetching /keys for %s\n",
+              eg->exchange_url);
+  eg->fo = TMH_EXCHANGES_keys4exchange (eg->exchange_url,
+                                        &process_pay_with_keys,
+                                        eg);
+  if (NULL == eg->fo)
+  {
+    GNUNET_break (0);
+    pc->pending_at_eg--;
+    resume_pay_with_error (pc,
+                           MHD_HTTP_INTERNAL_SERVER_ERROR,
+                           
TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED,
+                           "Failed to lookup exchange by URL");
+    return;
+  }
+}
+
+
 /**
  * Start batch deposits for all exchanges involved
  * in this payment.
@@ -1515,11 +1496,13 @@ start_batch_deposits (struct PayContext *pc)
     }
     if (! have_coins)
       continue; /* no coins left to deposit at this exchange */
-    eg->fo = TMH_EXCHANGES_find_exchange (eg->exchange_url,
-                                          false,
-                                          &process_pay_with_exchange,
-                                          eg);
-    if (NULL == eg->fo)
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Getting /wire details for %s\n",
+                eg->exchange_url);
+    eg->gwo = TMH_EXCHANGES_wire4exchange (eg->exchange_url,
+                                           &process_pay_with_wire,
+                                           eg);
+    if (NULL == eg->gwo)
     {
       GNUNET_break (0);
       resume_pay_with_error (pc,

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