gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 228/277: start with reserve processing logic


From: gnunet
Subject: [taler-merchant] 228/277: start with reserve processing logic
Date: Sun, 05 Jul 2020 20:52:21 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit da5f393967e9a4e6b7c78b72f1c9f74a49bb52c6
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Jun 20 18:22:33 2020 +0200

    start with reserve processing logic
---
 src/backend/Makefile.am                            |   4 +-
 src/backend/taler-merchant-httpd.c                 |  16 ++-
 .../taler-merchant-httpd_private-post-reserves.c   |   9 +-
 src/backend/taler-merchant-httpd_reserves.c        | 142 +++++++++++++++++++++
 src/backend/taler-merchant-httpd_reserves.h        |  61 +++++++++
 src/backenddb/plugin_merchantdb_postgres.c         | 134 ++++++++++++++++++-
 src/include/taler_merchantdb_plugin.h              |  32 +++++
 7 files changed, 384 insertions(+), 14 deletions(-)

diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 3682363..bb3f2bf 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -84,7 +84,9 @@ taler_merchant_httpd_SOURCES = \
   taler-merchant-httpd_post-orders-ID-pay.c \
     taler-merchant-httpd_post-orders-ID-pay.h \
   taler-merchant-httpd_post-tips-ID-pickup.c \
-    taler-merchant-httpd_post-tips-ID-pickup.h
+    taler-merchant-httpd_post-tips-ID-pickup.h \
+  taler-merchant-httpd_reserves.c \
+    taler-merchant-httpd_reserves.h
 
 DEAD = \
   taler-merchant-httpd_check-payment.c taler-merchant-httpd_check-payment.h \
diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index 804e10e..f3d8d75 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -59,7 +59,7 @@
 #include "taler-merchant-httpd_post-orders-ID-claim.h"
 #include "taler-merchant-httpd_post-orders-ID-pay.h"
 #include "taler-merchant-httpd_post-tips-ID-pickup.h"
-
+#include "taler-merchant-httpd_reserves.h"
 
 /**
  * Backlog for listen operation on unix-domain sockets.
@@ -472,6 +472,7 @@ do_shutdown (void *cls)
     MHD_stop_daemon (mhd);
     mhd = NULL;
   }
+  TMH_RESERVES_done ();
   if (NULL != TMH_db)
   {
     TALER_MERCHANTDB_plugin_unload (TMH_db);
@@ -1361,6 +1362,11 @@ run (void *cls,
   result = GNUNET_SYSERR;
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
                                  NULL);
+  resume_timeout_heap
+    = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
+  payment_trigger_map
+    = GNUNET_CONTAINER_multihashmap_create (16,
+                                            GNUNET_YES);
   if (GNUNET_OK !=
       TALER_config_get_currency (cfg,
                                  &TMH_currency))
@@ -1425,7 +1431,8 @@ run (void *cls,
       return;
     }
   }
-
+  /* start watching reserves */
+  TMH_RESERVES_init ();
   fh = TALER_MHD_bind (cfg,
                        "merchant",
                        &port);
@@ -1435,11 +1442,6 @@ run (void *cls,
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  resume_timeout_heap
-    = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
-  payment_trigger_map
-    = GNUNET_CONTAINER_multihashmap_create (16,
-                                            GNUNET_YES);
   mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME | MHD_USE_DUAL_STACK,
                           port,
                           NULL, NULL,
diff --git a/src/backend/taler-merchant-httpd_private-post-reserves.c 
b/src/backend/taler-merchant-httpd_private-post-reserves.c
index 77854a1..01bba5d 100644
--- a/src/backend/taler-merchant-httpd_private-post-reserves.c
+++ b/src/backend/taler-merchant-httpd_private-post-reserves.c
@@ -301,11 +301,10 @@ TMH_private_post_reserves (const struct 
TMH_RequestHandler *rh,
                                  &rc->initial_balance,
                                  rc->reserve_expiration);
     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
-    // Do this temporarily for testing
-    qs = TMH_db->activate_reserve (TMH_db->cls,
-                                   mi->settings.id,
-                                   &reserve_pub,
-                                   &rc->initial_balance);
+    TMH_RESERVES_check (mi->settings.id,
+                        rc->exchange_url,
+                        &reserve_pub,
+                        &rc->initial_balance);
     if (qs < 0)
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
diff --git a/src/backend/taler-merchant-httpd_reserves.c 
b/src/backend/taler-merchant-httpd_reserves.c
new file mode 100644
index 0000000..5876243
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_reserves.c
@@ -0,0 +1,142 @@
+/*
+  This file is part of TALER
+  (C) 2020 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file backend/taler-merchant-httpd_reserves.c
+ * @brief logic for initially tracking a reserve's status
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_json_lib.h>
+#include "taler-merchant-httpd.h"
+#include "taler-merchant-httpd_reserves.h"
+
+
+/**
+ * Our representation of a reserve that we are (still) checking the status of.
+ */
+struct Reserve
+{
+  /**
+   * Reserve's public key.
+   */
+  struct TALER_ReservePublicKeyP reserve_pub;
+
+  /**
+   * Amount the merchant expects to see in the reserve initially.
+   * We log a warning if there is a missmatch.
+   */
+  struct TALER_Amount expected_amount;
+
+  /**
+   * URL of the exchange hosting this reserve.
+   */
+  char *exchange_url;
+
+  /**
+   * Instance this reserve belongs with.
+   */
+  char *instance_id;
+};
+
+
+/**
+ * Function called with information about a reserve that we need
+ * to check the status from at the exchange to see if/when it has
+ * been filled (and with what amount).
+ *
+ * @param cls closure
+ * @param instance_id for which instance is this reserve
+ * @param exchange_url base URL of the exchange at which the reserve lives
+ * @param reserve_pub public key of the reserve
+ * @param expected_amount how much do we expect to see in the reserve
+ */
+static void
+add_reserve (void *cls,
+             const char *instance_id,
+             const char *exchange_url,
+             const struct TALER_ReservePublicKeyP *reserve_pub,
+             const struct TALER_Amount *expected_amount)
+{
+  struct Reserve *r;
+
+  r = GNUNET_new (struct Reserve);
+  r->exchange_url = GNUNET_strdup (exchange_url);
+  r->instance_id = GNUNET_strdup (instance_id);
+  r->reserve_pub = *reserve_pub;
+  r->expected_amount = *expected_amount;
+  // ....
+}
+
+
+/**
+ * Load information about reserves and start querying reserve status.
+ * Must be called after the database is available.
+ */
+void
+TMH_RESERVES_init (void)
+{
+  TMH_db->lookup_pending_reserves (TMH_db->cls,
+                                   &add_reserve,
+                                   NULL);
+}
+
+
+/**
+ * Add a reserve to the list of reserves to check.
+ *
+ * @param instance_id which instance is the reserve for
+ * @param exchange_url URL of the exchange with the reserve
+ * @param reserve_pub public key of the reserve to check
+ * @param expected_amount amount the merchant expects to see initially in the 
reserve
+ */
+void
+TMH_RESERVES_check (const char *instance_id,
+                    const char *exchange_url,
+                    const struct TALER_ReservePublicKeyP *reserve_pub,
+                    const struct TALER_Amount *expected_amount)
+{
+  enum GNUNET_DB_QueryStatus qs;
+
+  add_reserve (NULL,
+               instance_id,
+               exchange_url,
+               reserve_pub,
+               expected_amount);
+
+  // Do this temporarily for testing
+  qs = TMH_db->activate_reserve (TMH_db->cls,
+                                 instance_id,
+                                 reserve_pub,
+                                 expected_amount); // FIXME: change to REAL 
amount later!
+  if (qs <= 0)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to commit reserve activation to database (%d)\n",
+                (int) qs);
+  }
+}
+
+
+/**
+ * Stop checking reserve status.
+ */
+void
+TMH_RESERVES_done (void)
+{
+}
+
+
+/* end of taler-merchant-httpd_reserves.c */
diff --git a/src/backend/taler-merchant-httpd_reserves.h 
b/src/backend/taler-merchant-httpd_reserves.h
new file mode 100644
index 0000000..e7cab1b
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_reserves.h
@@ -0,0 +1,61 @@
+/*
+  This file is part of TALER
+  (C) 2020 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file backend/taler-merchant-httpd_reserves.h
+ * @brief logic for initially tracking a reserve's status
+ * @author Christian Grothoff
+ */
+#ifndef TALER_MERCHANT_HTTPD_RESERVES_H
+#define TALER_MERCHANT_HTTPD_RESERVES_H
+
+#include <jansson.h>
+#include <gnunet/gnunet_util_lib.h>
+#include <taler/taler_util.h>
+#include <taler/taler_exchange_service.h>
+#include "taler-merchant-httpd.h"
+
+
+/**
+ * Load information about reserves and start querying reserve status.
+ * Must be called after the database is available.
+ */
+void
+TMH_RESERVES_init (void);
+
+
+/**
+ * Add a reserve to the list of reserves to check.
+ *
+ * @param instance_id which instance is the reserve for
+ * @param exchange_url URL of the exchange with the reserve
+ * @param reserve_pub public key of the reserve to check
+ * @param expected_amount amount the merchant expects to see initially in the 
reserve
+ */
+void
+TMH_RESERVES_check (const char *instance_id,
+                    const char *exchange_url,
+                    const struct TALER_ReservePublicKeyP *reserve_pub,
+                    const struct TALER_Amount *expected_amount);
+
+
+/**
+ * Stop checking reserve status.
+ */
+void
+TMH_RESERVES_done (void);
+
+
+#endif
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index f218e43..12dc349 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -4239,7 +4239,7 @@ postgres_activate_reserve (void *cls,
 
 
 /**
- * Closure for #lookup_accounts_cb.
+ * Closure for #lookup_reserves_cb.
  */
 struct LookupReservesContext
 {
@@ -4419,6 +4419,123 @@ postgres_lookup_reserves (void *cls,
 }
 
 
+/**
+ * Closure for #lookup_pending_reserves_cb.
+ */
+struct LookupPendingReservesContext
+{
+  /**
+   * Postgres context.
+   */
+  struct PostgresClosure *pg;
+
+  /**
+   * Function to call with the results
+   */
+  TALER_MERCHANTDB_PendingReservesCallback cb;
+
+  /**
+   * Closure for @e cb
+   */
+  void *cb_cls;
+
+  /**
+   * Set in case of errors.
+   */
+  enum GNUNET_DB_QueryStatus qs;
+
+};
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results about accounts.
+ *
+ * @param[in,out] cls of type `struct LookupReservesContext *`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
+lookup_pending_reserves_cb (void *cls,
+                            PGresult *result,
+                            unsigned int num_results)
+{
+  struct LookupPendingReservesContext *lrc = cls;
+  struct PostgresClosure *pg = lrc->pg;
+
+  for (unsigned int i = 0; i < num_results; i++)
+  {
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct TALER_Amount merchant_initial_balance;
+    char *exchange_url;
+    char *instance_id;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                            &reserve_pub),
+      GNUNET_PQ_result_spec_string ("exchange_url",
+                                    &exchange_url),
+      GNUNET_PQ_result_spec_string ("instance_id",
+                                    &instance_id),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("merchant_initial_balance",
+                                   &merchant_initial_balance),
+      GNUNET_PQ_result_spec_end
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      lrc->qs = GNUNET_DB_STATUS_HARD_ERROR;
+      return;
+    }
+    lrc->cb (lrc->cb_cls,
+             instance_id,
+             exchange_url,
+             &reserve_pub,
+             &merchant_initial_balance);
+    GNUNET_PQ_cleanup_result (rs);
+  }
+}
+
+
+/**
+ * Lookup reserves pending activation across all instances.
+ *
+ * @param cls closure
+ * @param cb function to call with reserve summary data
+ * @param cb_cls closure for @a cb
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_lookup_pending_reserves (void *cls,
+                                  TALER_MERCHANTDB_PendingReservesCallback cb,
+                                  void *cb_cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct LookupPendingReservesContext lrc = {
+    .pg = pg,
+    .cb = cb,
+    .cb_cls = cb_cls
+  };
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_end
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  check_connection (pg);
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                             "lookup_pending_reserves",
+                                             params,
+                                             &lookup_pending_reserves_cb,
+                                             &lrc);
+  if (lrc.qs < 0)
+    return lrc.qs;
+  return qs;
+}
+
+
 /**
  * Closure for #lookup_reserve_tips_cb().
  */
@@ -7572,6 +7689,20 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
                             "        FROM merchant_instances"
                             "       WHERE merchant_id=$1)",
                             2),
+    /* For postgres_lookup_pending_reserves() */
+    GNUNET_PQ_make_prepare ("lookup_pending_reserves",
+                            "SELECT"
+                            " reserve_pub"
+                            ",merchant_id"
+                            ",exchange_url"
+                            ",merchant_initial_balance_val"
+                            ",merchant_initial_balance_frac"
+                            " FROM merchant_tip_reserves"
+                            " JOIN merchant_instances USING (merchant_serial)"
+                            " JOIN merchant_tip_reserve_keys USING 
(reserve_serial)"
+                            " WHERE exchange_initial_balance_val=0"
+                            "   AND exchange_initial_balance_frac=0",
+                            0),
     /* For postgres_lookup_reserve() */
     GNUNET_PQ_make_prepare ("lookup_reserve",
                             "SELECT"
@@ -8011,6 +8142,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
   plugin->insert_reserve = &postgres_insert_reserve;
   plugin->activate_reserve = &postgres_activate_reserve;
   plugin->lookup_reserves = &postgres_lookup_reserves;
+  plugin->lookup_pending_reserves = &postgres_lookup_pending_reserves;
   plugin->lookup_reserve = &postgres_lookup_reserve;
   plugin->delete_reserve = &postgres_delete_reserve;
   plugin->purge_reserve = &postgres_purge_reserve;
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index e8c7154..abd1ef0 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -483,6 +483,24 @@ typedef void
   bool active);
 
 
+/**
+ * Callback with details about a reserve pending exchange confirmation.
+ *
+ * @param cls closure
+ * @param instance_id for which instance is this reserve
+ * @param exchange_url base URL of the exchange
+ * @param reserve_pub public key of the reserve
+ * @param expected_amount how much do we expect to see in the reserve
+ */
+typedef void
+(*TALER_MERCHANTDB_PendingReservesCallback)(
+  void *cls,
+  const char *instance_id,
+  const char *exchange_url,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  const struct TALER_Amount *expected_amount);
+
+
 /**
  * Details about a tip.
  */
@@ -1702,6 +1720,20 @@ struct TALER_MERCHANTDB_Plugin
                      void *cb_cls);
 
 
+  /**
+   * Lookup reserves pending activation across all instances.
+   *
+   * @param cls closure
+   * @param cb function to call with reserve data
+   * @param cb_cls closure for @a cb
+   * @return transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*lookup_pending_reserves)(void *cls,
+                             TALER_MERCHANTDB_PendingReservesCallback cb,
+                             void *cb_cls);
+
+
   /**
    * Lookup reserve details.
    *

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