gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -make batch withdraw requests id


From: gnunet
Subject: [taler-exchange] branch master updated: -make batch withdraw requests idempotent
Date: Tue, 17 May 2022 12:29:03 +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 b9d0b1aa -make batch withdraw requests idempotent
b9d0b1aa is described below

commit b9d0b1aae47ddbc8928e8c4d5a0188da91fc7735
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue May 17 12:29:00 2022 +0200

    -make batch withdraw requests idempotent
---
 src/exchange/taler-exchange-httpd_batch-withdraw.c | 162 +++++++++++----------
 1 file changed, 89 insertions(+), 73 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c 
b/src/exchange/taler-exchange-httpd_batch-withdraw.c
index 2b90eda4..e58548af 100644
--- a/src/exchange/taler-exchange-httpd_batch-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c
@@ -273,58 +273,88 @@ batch_withdraw_transaction (void *cls,
       return GNUNET_DB_STATUS_HARD_ERROR;
     }
   }
-
   return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
 }
 
 
+/**
+ * Generates our final (successful) response.
+ *
+ * @param rc request context
+ * @param wc operation context
+ * @return MHD queue status
+ */
+static MHD_RESULT
+generate_reply_success (const struct TEH_RequestContext *rc,
+                        const struct BatchWithdrawContext *wc)
+{
+  json_t *sigs;
+
+  sigs = json_array ();
+  GNUNET_assert (NULL != sigs);
+  for (unsigned int i = 0; i<wc->planchets_length; i++)
+  {
+    struct PlanchetContext *pc = &wc->planchets[i];
+
+    GNUNET_assert (
+      0 ==
+      json_array_append_new (
+        sigs,
+        GNUNET_JSON_PACK (
+          TALER_JSON_pack_blinded_denom_sig (
+            "ev_sig",
+            &pc->collectable.sig))));
+  }
+  TEH_METRICS_batch_withdraw_num_coins += wc->planchets_length;
+  return TALER_MHD_REPLY_JSON_PACK (
+    rc->connection,
+    MHD_HTTP_OK,
+    GNUNET_JSON_pack_array_steal ("ev_sigs",
+                                  sigs));
+}
+
+
 /**
  * Check if the @a rc is replayed and we already have an
  * answer. If so, replay the existing answer and return the
  * HTTP response.
  *
  * @param rc request context
- * @param[in,out] wc parsed request data
+ * @param wc parsed request data
  * @param[out] mret HTTP status, set if we return true
  * @return true if the request is idempotent with an existing request
  *    false if we did not find the request in the DB and did not set @a mret
  */
 static bool
-check_request_idempotent (struct TEH_RequestContext *rc,
-                          struct BatchWithdrawContext *wc,
+check_request_idempotent (const struct TEH_RequestContext *rc,
+                          const struct BatchWithdrawContext *wc,
                           MHD_RESULT *mret)
 {
-  /* FIXME: Not yet supported. Do we want to, or simply
-     generate an error in this case? */
-#if FIXME
-  enum GNUNET_DB_QueryStatus qs;
-
-  qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
-                                      &wc->h_coin_envelope,
-                                      &wc->collectable);
-  if (0 > qs)
+  for (unsigned int i = 0; i<wc->planchets_length; i++)
   {
-    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
-    if (GNUNET_DB_STATUS_HARD_ERROR == qs)
-      *mret = TALER_MHD_reply_with_error (rc->connection,
-                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                          TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                          "get_withdraw_info");
-    return true; /* well, kind-of */
+    struct PlanchetContext *pc = &wc->planchets[i];
+    enum GNUNET_DB_QueryStatus qs;
+
+    qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
+                                        &pc->h_coin_envelope,
+                                        &pc->collectable);
+    if (0 > qs)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+        *mret = TALER_MHD_reply_with_error (rc->connection,
+                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                            TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                            "get_withdraw_info");
+      return true; /* well, kind-of */
+    }
+    if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+      return false;
   }
-  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
-    return false;
   /* generate idempotent reply */
-  *mret = TALER_MHD_REPLY_JSON_PACK (
-    rc->connection,
-    MHD_HTTP_OK,
-    TALER_JSON_pack_blinded_denom_sig ("ev_sig",
-                                       &wc->collectable.sig));
-  TALER_blinded_denom_sig_free (&wc->collectable.sig);
+  *mret = generate_reply_success (rc,
+                                  wc);
   return true;
-#else
-  return false;
-#endif
 }
 
 
@@ -337,7 +367,7 @@ check_request_idempotent (struct TEH_RequestContext *rc,
  * @return MHD result for the @a rc
  */
 static MHD_RESULT
-prepare_transaction (struct TEH_RequestContext *rc,
+prepare_transaction (const struct TEH_RequestContext *rc,
                      struct BatchWithdrawContext *wc)
 {
   /* Note: We could check the reserve balance here,
@@ -379,31 +409,8 @@ prepare_transaction (struct TEH_RequestContext *rc,
     }
   }
   /* return final positive response */
-  {
-    json_t *sigs;
-
-    sigs = json_array ();
-    GNUNET_assert (NULL != sigs);
-    for (unsigned int i = 0; i<wc->planchets_length; i++)
-    {
-      struct PlanchetContext *pc = &wc->planchets[i];
-
-      GNUNET_assert (
-        0 ==
-        json_array_append_new (
-          sigs,
-          GNUNET_JSON_PACK (
-            TALER_JSON_pack_blinded_denom_sig (
-              "ev_sig",
-              &pc->collectable.sig))));
-    }
-    TEH_METRICS_batch_withdraw_num_coins += wc->planchets_length;
-    return TALER_MHD_REPLY_JSON_PACK (
-      rc->connection,
-      MHD_HTTP_OK,
-      GNUNET_JSON_pack_array_steal ("ev_sigs",
-                                    sigs));
-  }
+  return generate_reply_success (rc,
+                                 wc);
 }
 
 
@@ -417,27 +424,13 @@ prepare_transaction (struct TEH_RequestContext *rc,
  * @return MHD result for the @a rc
  */
 static MHD_RESULT
-parse_planchets (struct TEH_RequestContext *rc,
+parse_planchets (const struct TEH_RequestContext *rc,
                  struct BatchWithdrawContext *wc,
                  const json_t *planchets)
 {
   struct TEH_KeyStateHandle *ksh;
   MHD_RESULT mret;
 
-  ksh = TEH_keys_get_state ();
-  if (NULL == ksh)
-  {
-    if (! check_request_idempotent (rc,
-                                    wc,
-                                    &mret))
-    {
-      return TALER_MHD_reply_with_error (rc->connection,
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         
TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
-                                         NULL);
-    }
-    return mret;
-  }
   for (unsigned int i = 0; i<wc->planchets_length; i++)
   {
     struct PlanchetContext *pc = &wc->planchets[i];
@@ -450,7 +443,6 @@ parse_planchets (struct TEH_RequestContext *rc,
                                         &pc->blinded_planchet),
       GNUNET_JSON_spec_end ()
     };
-    struct TEH_DenominationKey *dk;
 
     {
       enum GNUNET_GenericReturnValue res;
@@ -463,6 +455,27 @@ parse_planchets (struct TEH_RequestContext *rc,
         return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
     }
     pc->collectable.reserve_pub = *wc->reserve_pub;
+  }
+
+  ksh = TEH_keys_get_state ();
+  if (NULL == ksh)
+  {
+    if (! check_request_idempotent (rc,
+                                    wc,
+                                    &mret))
+    {
+      return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         
TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
+                                         NULL);
+    }
+    return mret;
+  }
+  for (unsigned int i = 0; i<wc->planchets_length; i++)
+  {
+    struct PlanchetContext *pc = &wc->planchets[i];
+    struct TEH_DenominationKey *dk;
+
     dk = TEH_keys_denomination_by_hash2 (ksh,
                                          &pc->collectable.denom_pub_hash,
                                          NULL,
@@ -522,6 +535,7 @@ parse_planchets (struct TEH_RequestContext *rc,
     if (dk->denom_pub.cipher != pc->blinded_planchet.cipher)
     {
       /* denomination cipher and blinded planchet cipher not the same */
+      GNUNET_break_op (0);
       return TALER_MHD_reply_with_error (rc->connection,
                                          MHD_HTTP_BAD_REQUEST,
                                          
TALER_EC_EXCHANGE_GENERIC_CIPHER_MISMATCH,
@@ -532,6 +546,7 @@ parse_planchets (struct TEH_RequestContext *rc,
                           &dk->meta.value,
                           &dk->meta.fees.withdraw))
     {
+      GNUNET_break (0);
       return TALER_MHD_reply_with_error (rc->connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW,
@@ -542,6 +557,7 @@ parse_planchets (struct TEH_RequestContext *rc,
                           &wc->batch_total,
                           &pc->collectable.amount_with_fee))
     {
+      GNUNET_break (0);
       return TALER_MHD_reply_with_error (rc->connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW,

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