gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -implement reserve history DB lo


From: gnunet
Subject: [taler-exchange] branch master updated: -implement reserve history DB logic
Date: Sun, 22 May 2022 16:18:12 +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 4a5d71cc -implement reserve history DB logic
4a5d71cc is described below

commit 4a5d71cca2297cfd98b5dd907df2fc355d0da297
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun May 22 16:18:09 2022 +0200

    -implement reserve history DB logic
---
 .../taler-exchange-httpd_reserves_history.c        | 42 +++++++++++++++-
 src/exchangedb/exchange-0001-part.sql              | 58 +++++++++++++++++++++-
 src/exchangedb/plugin_exchangedb_postgres.c        | 35 +++++++++++--
 src/include/taler_exchangedb_plugin.h              |  9 +++-
 4 files changed, 134 insertions(+), 10 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_reserves_history.c 
b/src/exchange/taler-exchange-httpd_reserves_history.c
index 96902d01..4766dadc 100644
--- a/src/exchange/taler-exchange-httpd_reserves_history.c
+++ b/src/exchange/taler-exchange-httpd_reserves_history.c
@@ -96,6 +96,8 @@ reply_reserve_history_success (struct MHD_Connection 
*connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_GENERIC_JSON_ALLOCATION_FAILURE,
                                        NULL);
+  /* FIXME: should set explicit cache control headers
+     for this response to enable caching! */
   return TALER_MHD_REPLY_JSON_PACK (
     connection,
     MHD_HTTP_OK,
@@ -129,7 +131,45 @@ reserve_history_transaction (void *cls,
   struct ReserveHistoryContext *rsc = cls;
   enum GNUNET_DB_QueryStatus qs;
 
-  // FIXME: first deduct rsc->gf->fees.history from reserve balance (and 
persist the signature justifying this)
+  if (! TALER_amount_is_zero (&rsc->gf->fees.history))
+  {
+    bool balance_ok = false;
+    bool idempotent = true;
+
+    qs = TEH_plugin->insert_history_request (TEH_plugin->cls,
+                                             rsc->reserve_pub,
+                                             &rsc->reserve_sig,
+                                             rsc->timestamp,
+                                             &rsc->gf->fees.history,
+                                             &balance_ok,
+                                             &idempotent);
+    if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+    {
+      GNUNET_break (0);
+      *mhd_ret
+        = TALER_MHD_reply_with_error (connection,
+                                      MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                      TALER_EC_GENERIC_DB_FETCH_FAILED,
+                                      "get_reserve_history");
+    }
+    if (qs <= 0)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      return qs;
+    }
+    if (! balance_ok)
+    {
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_CONFLICT,
+                                         
TALER_EC_EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS,
+                                         NULL);
+    }
+    if (idempotent)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Idempotent /reserves/history request observed. Is caching 
working?\n");
+    }
+  }
   qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
                                         rsc->reserve_pub,
                                         &rsc->balance,
diff --git a/src/exchangedb/exchange-0001-part.sql 
b/src/exchangedb/exchange-0001-part.sql
index d8855b01..a47a2aed 100644
--- a/src/exchangedb/exchange-0001-part.sql
+++ b/src/exchangedb/exchange-0001-part.sql
@@ -3429,11 +3429,65 @@ CREATE OR REPLACE FUNCTION exchange_do_history_request(
   IN in_history_fee_val INT8,
   IN in_history_fee_frac INT4,
   OUT out_balance_ok BOOLEAN,
-  OUT out_conflict BOOLEAN)
+  OUT out_idempotent BOOLEAN)
 LANGUAGE plpgsql
 AS $$
 BEGIN
-  -- FIXME
+
+  -- Insert and check for idempotency.
+  INSERT INTO history_requests
+  (reserve_pub
+  ,request_timestamp
+  ,reserve_sig
+  ,history_fee_val
+  ,history_fee_frac)
+  VALUES
+  (in_reserve_pub
+  ,in_request_timestamp
+  ,in_reserve_sig
+  ,in_history_fee_val
+  ,in_history_fee_frac)
+  ON CONFLICT DO NOTHING;
+
+  IF NOT FOUND
+  THEN
+    out_balance_ok=TRUE;
+    out_conflict=TRUE;
+    RETURN;
+  END IF;
+
+  out_conflict=FALSE;
+
+  -- Update reserve balance.
+  UPDATE reserves
+   SET
+    current_balance_frac=current_balance_frac-in_history_fee_frac
+       + CASE
+         WHEN reserve_frac < in_history_fee_frac
+         THEN 100000000
+         ELSE 0
+         END,
+    current_balance_val=current_balance_val-in_history_fee_val
+       - CASE
+         WHEN current_balance_frac < in_history_fee_frac
+         THEN 1
+         ELSE 0
+         END
+  WHERE
+    reserve_pub=in_reserve_pub
+    AND ( (current_balance_val > in_history_fee_val) OR
+          ( (current_balance_frac >= in_history_fee_frac) AND
+            (current_balance_val >= in_history_fee_val) ) );
+
+  IF NOT FOUND
+  THEN
+    -- Either reserve does not exist, or balance insufficient.
+    -- Both we treat the same here as balance insufficient.
+    out_balance_ok=FALSE;
+    RETURN;
+  END IF;
+
+  out_balance_ok=TRUE;
 END $$;
 
 
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 7a908398..5d84a2af 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -3641,7 +3641,9 @@ prepare_statements (struct PostgresClosure *pg)
     /* Used in #postgres_insert_history_request() */
     GNUNET_PQ_make_prepare (
       "call_history_request",
-      "SELECT 1"
+      "SELECT"
+      "  out_balance_ok AS balance_ok"
+      " ,out_idempotent AS idempotent"
       " FROM exchange_do_history_request"
       "  ($1, $2, $3, $4, $5)",
       5),
@@ -14014,6 +14016,9 @@ postgres_do_account_merge (
  * @param reserve_sig signature affirming the request
  * @param request_timestamp when was the request made
  * @param history_fee how much should the @a reserve_pub be charged for the 
request
+ * @param[out] balance_ok set to TRUE if the reserve balance
+ *         was sufficient
+ * @param[out] idempotent set to TRUE if the request is already in the DB
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
@@ -14021,11 +14026,31 @@ postgres_insert_history_request (
   void *cls,
   const struct TALER_ReservePublicKeyP *reserve_pub,
   const struct TALER_ReserveSignatureP *reserve_sig,
-  struct GNUNET_TIME_Absolute request_timestamp,
-  const struct TALER_Amount *history)
+  struct GNUNET_TIME_Timestamp request_timestamp,
+  const struct TALER_Amount *history,
+  bool *balance_ok,
+  bool *idempotent)
 {
-  GNUNET_break (0); // FIXME
-  return GNUNET_DB_STATUS_HARD_ERROR;
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (reserve_pub),
+    GNUNET_PQ_query_param_auto_from_type (reserve_sig),
+    GNUNET_PQ_query_param_timestamp (&request_timestamp),
+    TALER_PQ_query_param_amount (history),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_bool ("balance_ok",
+                                balance_ok),
+    GNUNET_PQ_result_spec_bool ("idempotent",
+                                idempotent),
+    GNUNET_PQ_result_spec_end
+  };
+
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "call_history_request",
+                                                   params,
+                                                   rs);
 }
 
 
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 213fe114..2ef29123 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -4864,6 +4864,9 @@ struct TALER_EXCHANGEDB_Plugin
    * @param reserve_sig signature affirming the request
    * @param request_timestamp when was the request made
    * @param history_fee how much should the @a reserve_pub be charged for the 
request
+   * @param[out] balance_ok set to TRUE if the reserve balance
+   *         was sufficient
+   * @param[out] idempotent set to TRUE if the request is already in the DB
    * @return transaction status code
    */
   enum GNUNET_DB_QueryStatus
@@ -4871,8 +4874,10 @@ struct TALER_EXCHANGEDB_Plugin
     void *cls,
     const struct TALER_ReservePublicKeyP *reserve_pub,
     const struct TALER_ReserveSignatureP *reserve_sig,
-    struct GNUNET_TIME_Absolute request_timestamp,
-    const struct TALER_Amount *history_fee);
+    struct GNUNET_TIME_Timestamp request_timestamp,
+    const struct TALER_Amount *history_fee,
+    bool *balance_ok,
+    bool *idempotent);
 
 
   /**

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