gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] 02/04: some modifications, there is one error which dis


From: gnunet
Subject: [taler-exchange] 02/04: some modifications, there is one error which display (no function matches the given name and argument types)
Date: Mon, 21 Nov 2022 16:40:15 +0100

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

joseph-xu pushed a commit to branch master
in repository exchange.

commit b9ccfbd66b192e11766f4129bae65c16fddffc5a
Author: Joseph <Joseph.xu@efrei.net>
AuthorDate: Fri Nov 18 11:18:45 2022 -0500

    some modifications, there is one error which display (no function matches 
the given name and argument types)
---
 ...by_j.c => perf_exchangedb_reserves_in_insert.c} |  25 ++-
 src/exchangedb/pg_batch_reserves_in_insert.c       | 195 ++++-----------------
 src/exchangedb/pg_batch_reserves_in_insert.h       |   1 +
 src/exchangedb/plugin_exchangedb_postgres.c        |   2 +
 src/exchangedb/procedures.sql                      | 150 +++++++++++-----
 src/exchangedb/test_exchangedb_by_j.c              |  11 +-
 6 files changed, 154 insertions(+), 230 deletions(-)

diff --git a/src/exchangedb/test_exchangedb_by_j.c 
b/src/exchangedb/perf_exchangedb_reserves_in_insert.c
similarity index 89%
copy from src/exchangedb/test_exchangedb_by_j.c
copy to src/exchangedb/perf_exchangedb_reserves_in_insert.c
index 175691e9..6c91b6bc 100644
--- a/src/exchangedb/test_exchangedb_by_j.c
+++ b/src/exchangedb/perf_exchangedb_reserves_in_insert.c
@@ -107,8 +107,8 @@ run (void *cls)
     struct GNUNET_TIME_Absolute now;
     struct GNUNET_TIME_Timestamp ts;
     struct GNUNET_TIME_Relative duration;
-    struct TALER_EXCHANGEDB_ReserveInInfo reserves[batch_size];
-    enum GNUNET_DB_QueryStatus *results;
+    struct TALER_ReservePublicKeyP reserve_pub;
+
     GNUNET_assert (GNUNET_OK ==
                    TALER_string_to_amount (CURRENCY ":1.000010",
                                            &value));
@@ -118,19 +118,16 @@ run (void *cls)
                    "test_by_exchange_j");
     for (unsigned int k = 0; k<batch_size; k++)
     {
-      RND_BLK (&reserves[k].reserve_pub);
-      reserves[k].balance = value;
-      reserves[k].execution_time = ts;
-      reserves[k].sender_account_details = sndr;
-      reserves[k].exchange_account_name = "name";
+      RND_BLK (&reserve_pub);
+      FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+              plugin->reserves_in_insert (plugin->cls,
+                                          &reserve_pub,
+                                          &value,
+                                          ts,
+                                          sndr,
+                                          "section",
+                                          4));
     }
-    FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
-            plugin->batch_reserves_in_insert (plugin->cls,
-                                              reserves,
-                                              batch_size,
-                                              &results));
-
-
     plugin->commit (plugin->cls);
     duration = GNUNET_TIME_absolute_get_duration (now);
     fprintf (stdout,
diff --git a/src/exchangedb/pg_batch_reserves_in_insert.c 
b/src/exchangedb/pg_batch_reserves_in_insert.c
index d7ce47dc..216de96b 100644
--- a/src/exchangedb/pg_batch_reserves_in_insert.c
+++ b/src/exchangedb/pg_batch_reserves_in_insert.c
@@ -14,7 +14,7 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file exchangedb/pg_bash_reserves_in_insert.c
+ * @file exchangedb/pg_batch_reserves_in_insert.c
  * @brief Implementation of the reserves_in_insert function for Postgres
  * @author JOSEPHxu
  */
@@ -70,7 +70,12 @@ TEH_PG_batch_reserves_in_insert (void *cls,
   struct TALER_EXCHANGEDB_Reserve reserve;
   struct GNUNET_TIME_Timestamp expiry;
   struct GNUNET_TIME_Timestamp gc;
+  struct TALER_PaytoHashP h_payto;
   uint64_t reserve_uuid;
+  bool conflicted;
+  bool transaction_duplicate;
+  struct GNUNET_TIME_Timestamp reserve_expiration
+    = GNUNET_TIME_relative_to_timestamp (pg->idle_reserve_expiration_time);
 
   reserve.pub = reserves->reserve_pub;
   expiry = GNUNET_TIME_absolute_to_timestamp (
@@ -91,15 +96,28 @@ TEH_PG_batch_reserves_in_insert (void *cls,
      the 'add' operation needs the reserve entry as a foreign key. */
   {
     struct GNUNET_PQ_QueryParam params[] = {
-      GNUNET_PQ_query_param_auto_from_type (&(reserves->reserve_pub)),
-      TALER_PQ_query_param_amount (&(reserves->balance)),
-      GNUNET_PQ_query_param_timestamp (&expiry),
-      GNUNET_PQ_query_param_timestamp (&gc),
+      GNUNET_PQ_query_param_auto_from_type (&reserves->reserve_pub), /*$1*/
+      TALER_PQ_query_param_amount (&reserves->balance),  /*$2+3*/
+      GNUNET_PQ_query_param_timestamp (&expiry),  /*$4*/
+      GNUNET_PQ_query_param_timestamp (&gc),  /*$5*/
+      GNUNET_PQ_query_param_uint64 (&reserves->wire_reference), /*6*/
+      TALER_PQ_query_param_amount (&reserves->balance), /*7+8*/
+      GNUNET_PQ_query_param_string (reserves->exchange_account_name), /*9*/
+      GNUNET_PQ_query_param_timestamp (&reserves->execution_time), /*10*/
+      GNUNET_PQ_query_param_auto_from_type (&h_payto), /*11*/
+      GNUNET_PQ_query_param_string (reserves->sender_account_details),/*12*/
+      GNUNET_PQ_query_param_timestamp (&reserve_expiration),/*13*/
       GNUNET_PQ_query_param_end
     };
+
+    /* We should get all our results into results[]*/
     struct GNUNET_PQ_ResultSpec rs[] = {
       GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
                                     &reserve_uuid),
+      GNUNET_PQ_result_spec_bool ("conflicted",
+                                  &conflicted),
+      GNUNET_PQ_result_spec_bool ("transaction_duplicate",
+                                  &transaction_duplicate),
       GNUNET_PQ_result_spec_end
     };
 
@@ -108,7 +126,12 @@ TEH_PG_batch_reserves_in_insert (void *cls,
     /* Note: query uses 'on conflict do nothing' */
     PREPARE (pg,
              "reserve_create",
-             "SELECT bash_reserves_in('34', '20','//asdddfs3', '60', 
'20'),bash_reserves_in('24', '10','//dfs3', '40', '50'),bash_reserves_in('42', 
'40','//d43', '40', '50'),bash_reserves_in('44', '10','//ghs3', '40', '50') AS 
existed from reserves;");
+             "SELECT "
+             "out_reserve_found AS conflicted"
+             ",transaction_duplicate"
+             ",ruuid"
+             " FROM batch_reserves_in"
+             " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12);");
 
     qs1 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                     "reserve_create",
@@ -118,167 +141,9 @@ TEH_PG_batch_reserves_in_insert (void *cls,
       return qs1;
   }
 
-  /* Create new incoming transaction, "ON CONFLICT DO NOTHING"
-     is again used to guard against duplicates. */
-  {
-    enum GNUNET_DB_QueryStatus qs2;
-    enum GNUNET_DB_QueryStatus qs3;
-    struct TALER_PaytoHashP h_payto;
-
-    qs3 = TEH_PG_setup_wire_target (pg,
-                                    reserves->sender_account_details,
-                                    &h_payto);
-    if (qs3 < 0)
-      return qs3;
-    /* We do not have the UUID, so insert by public key */
-    struct GNUNET_PQ_QueryParam params[] = {
-      GNUNET_PQ_query_param_auto_from_type (&reserve.pub),
-      GNUNET_PQ_query_param_uint64 (&(reserves->wire_reference)),
-      TALER_PQ_query_param_amount (&(reserves->balance)),
-      GNUNET_PQ_query_param_string (reserves->exchange_account_name),
-      GNUNET_PQ_query_param_auto_from_type (&h_payto),
-      GNUNET_PQ_query_param_timestamp (&reserves->execution_time),
-      GNUNET_PQ_query_param_end
-    };
-
-    PREPARE (pg,
-             "reserves_in_add_transaction",
-             "INSERT INTO reserves_in "
-             "(reserve_pub"
-             ",wire_reference"
-             ",credit_val"
-             ",credit_frac"
-             ",exchange_account_section"
-             ",wire_source_h_payto"
-             ",execution_date"
-             ") VALUES ($1, $2, $3, $4, $5, $6, $7)"
-             " ON CONFLICT DO NOTHING;");
-    qs2 = GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                              "reserves_in_add_transaction",
-                                              params);
-    /* qs2 could be 0 as statement used 'ON CONFLICT DO NOTHING' */
-    if (0 >= qs2)
-    {
-      if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs2) &&
-           (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs1) )
-      {
-        /* Conflict for the transaction, but the reserve was
-           just now created, that should be impossible. */
-        GNUNET_break (0); /* should be impossible: reserve was fresh,
-                             but transaction already known */
-        return GNUNET_DB_STATUS_HARD_ERROR;
-      }
-      /* Transaction was already known or error. We are finished. */
-      return qs2;
-    }
-  }
-  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs1)
-  {
-    /* New reserve, we are finished */
-    notify_on_reserve (pg,
-                       &(reserves->reserve_pub));
-    return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-  }
-
-  /* we were wrong with our optimistic assumption:
-     reserve did already exist, need to do an update instead */
-  {
-    /* We need to move away from 'read committed' to serializable.
-       Also, we know that it should be safe to commit at this point.
-       (We are only run in a larger transaction for performance.) */
-    enum GNUNET_DB_QueryStatus cs;
-
-    cs = TEH_PG_commit(pg);
-    if (cs < 0)
-      return cs;
-    if (GNUNET_OK !=
-        TEH_PG_start (pg,
-                      "reserve-update-serializable"))
-    {
-      GNUNET_break (0);
-      return GNUNET_DB_STATUS_HARD_ERROR;
-    }
-  }
-  {
-    enum GNUNET_DB_QueryStatus reserve_exists;
-
-    reserve_exists = TEH_PG_reserves_get (pg,
-                                          &reserve);
-    switch (reserve_exists)
-    {
-    case GNUNET_DB_STATUS_HARD_ERROR:
-      GNUNET_break (0);
-      return reserve_exists;
-    case GNUNET_DB_STATUS_SOFT_ERROR:
-      return reserve_exists;
-    case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
-      /* First we got a conflict, but then we cannot select? Very strange. */
-      GNUNET_break (0);
-      return GNUNET_DB_STATUS_SOFT_ERROR;
-    case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
-      /* continued below */
-      break;
-    }
-  }
-
-  {
-    struct TALER_EXCHANGEDB_Reserve updated_reserve;
-    enum GNUNET_DB_QueryStatus qs3;
-
-    /* If the reserve already existed, we need to still update the
-       balance; we do this after checking for duplication, as
-       otherwise we might have to actually pay the cost to roll this
-       back for duplicate transactions; like this, we should virtually
-       never actually have to rollback anything. */
-    updated_reserve.pub = reserve.pub;
-    if (0 >
-        TALER_amount_add (&updated_reserve.balance,
-                          &reserve.balance,
-                          &reserves->balance))
-    {
-      /* currency overflow or incompatible currency */
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Attempt to deposit incompatible amount into reserve\n");
-      return GNUNET_DB_STATUS_HARD_ERROR;
-    }
-    updated_reserve.expiry = GNUNET_TIME_timestamp_max (expiry,
-                                                        reserve.expiry);
-    updated_reserve.gc = GNUNET_TIME_timestamp_max (gc,
-                                                    reserve.gc);
-    qs3 = TEH_PG_reserves_update (pg,
-                           &updated_reserve);
-    switch (qs3)
-    {
-    case GNUNET_DB_STATUS_HARD_ERROR:
-      GNUNET_break (0);
-      return qs3;
-    case GNUNET_DB_STATUS_SOFT_ERROR:
-      return qs3;
-    case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
-      /* How can the UPDATE not work here? Very strange. */
-      GNUNET_break (0);
-      return GNUNET_DB_STATUS_HARD_ERROR;
-    case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
-      /* continued below */
-      break;
-    }
-  }
   notify_on_reserve (pg,
                      &reserves->reserve_pub);
-  /* Go back to original transaction mode */
-  {
-    enum GNUNET_DB_QueryStatus cs;
 
-    cs = TEH_PG_commit (pg);
-    if (cs < 0)
-      return cs;
-    if (GNUNET_OK !=
-        TEH_PG_start_read_committed (pg,
-                                     "reserve-insert-continued"))
-    {
-      GNUNET_break (0);
-      return GNUNET_DB_STATUS_HARD_ERROR;
-    }
-  }
+
   return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
 }
diff --git a/src/exchangedb/pg_batch_reserves_in_insert.h 
b/src/exchangedb/pg_batch_reserves_in_insert.h
index 9422096d..76679567 100644
--- a/src/exchangedb/pg_batch_reserves_in_insert.h
+++ b/src/exchangedb/pg_batch_reserves_in_insert.h
@@ -31,4 +31,5 @@ TEH_PG_batch_reserves_in_insert (void *cls,
                               const struct TALER_EXCHANGEDB_ReserveInInfo 
*reserves,
                               unsigned int reserves_length,
                                  enum GNUNET_DB_QueryStatus *results);
+
 #endif
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 11421700..5b59d4b0 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -5446,8 +5446,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
     = &TEH_PG_select_purse_by_merge_pub;
   plugin->set_purse_balance
     = &TEH_PG_set_purse_balance;
+
   plugin->batch_reserves_in_insert
     = &TEH_PG_batch_reserves_in_insert;
+
   return plugin;
 }
 
diff --git a/src/exchangedb/procedures.sql b/src/exchangedb/procedures.sql
index a9d90294..1e96301a 100644
--- a/src/exchangedb/procedures.sql
+++ b/src/exchangedb/procedures.sql
@@ -2520,62 +2520,120 @@ BEGIN
                policy_details_serial_id = out_policy_details_serial_id;
 END $$;
 
-COMMIT;
-
-/*************************************************************/
-
-
-CREATE OR REPLACE FUNCTION bash_reserves_in(
-  IN amount_val INT8,
-  IN amount_frac INT4,
-  IN rpub BYTEA,
-  IN now INT8,
-  IN min_reserve_gc INT8,
-  OUT reserve_found BOOLEAN,
+CREATE OR REPLACE FUNCTION batch_reserves_in(
+  IN in_reserve_pub BYTEA,
+  IN in_current_balance_val INT8,
+  IN in_current_balance_frac INT4,
+  IN in_expiration_date INT8,
+  IN in_gc_date INT8,
+  IN in_wire_ref INT8,
+  IN in_credit_val INT8,
+  IN in_credit_frac INT4,
+  IN in_exchange_account_name VARCHAR,
+  IN in_exectution_date INT4,
+  IN in_wire_source_h_payto BYTEA,    ---h_payto
+  IN in_payto_uri VARCHAR,
+  IN in_reserve_expiration INT8,
+  OUT out_reserve_found BOOLEAN,
+  OUT transaction_duplicate BOOLEAN,
   OUT ruuid INT8)
 LANGUAGE plpgsql
 AS $$
 DECLARE
-  existed BOOLEAN;
-  not_existed BOOLEAN;
+  my_amount_val INT8;
+DECLARE
+  my_amount_frac INT4;
 BEGIN
-  SELECT reserves.reserve_uuid into ruuid from reserves
-  where reserves.reserve_pub = rpub;
-  IF ruuid IS NOT NULL
-  THEN
-    existed = TRUE;
-    UPDATE reserves
-     SET (current_balance_val
-         ,current_balance_frac
-          ,expiration_date
-           ,gc_date) =
-            (amount_val
-             ,amount_frac
-              ,now
-               ,min_reserve_gc)
-      WHERE
-      reserve_pub = rpub
-      RETURNING existed into reserve_found;
-  END IF;
-  IF NOT FOUND
-  THEN
-    SELECT MAX(reserve_uuid)+1 into ruuid from reserves;
-    existed = FALSE;
-    INSERT INTO reserves
-    (reserve_uuid
-    ,reserve_pub
+
+  SELECT
+    current_balance_val
+   ,current_balance_frac
+  INTO
+    my_amount_val
+   ,my_amount_frac
+  FROM reserves
+  WHERE reserves.reserve_pub = in_reserve_pub;
+
+  INSERT INTO reserves
+    (reserve_pub
     ,current_balance_val
     ,current_balance_frac
     ,expiration_date
     ,gc_date)
     VALUES
-    (ruuid
-    ,rpub
-    ,amount_val
-    ,amount_frac
-    ,now
-    ,min_reserve_gc) RETURNING existed into reserve_found;
-
+    (in_reserve_pub
+    ,in_current_balance_val
+    ,in_current_balance_frac
+    ,in_expiration_date
+    ,in_gc_date)
+    ON CONFLICT DO NOTHING
+    RETURNING reserves.reserve_uuid INTO ruuid;
+
+  --IF THE INSERT WAS NOT SUCCESSFUL, REMEMBER IT
+  IF NOT FOUND
+  THEN
+    out_reserve_found = FALSE;
+  ELSE
+    out_reserve_found = TRUE;
   END IF;
 
+  --SIMPLE INSERT ON CONFLICT DO NOTHING
+  INSERT INTO wire_targets
+    (wire_target_h_payto
+    ,payto_uri)
+    VALUES
+    (in_wire_source_h_payto
+    ,in_payto_uri)
+  ON CONFLICT DO NOTHING;
+
+  INSERT INTO reserves_in
+    (reserve_pub
+    ,wire_reference
+    ,credit_val
+    ,credit_frac
+    ,exchange_account_section
+    ,wire_source_h_payto
+    ,execution_date)
+    VALUES
+    (in_reserve_pub
+    ,in_wire_ref
+    ,in_current_balance_val
+    ,in_credit_frac
+    ,in_exchange_account_section
+    ,in_wire_source_h_payto
+    ,in_execution_date);
+
+  --IF THE INSERTION WAS A SUCCESS IT MEANS NO DUPLICATED TRANSACTION
+  IF FOUND
+  THEN
+    transaction_duplicate = FALSE;
+    IF out_reserve_found = TRUE
+    THEN
+      UPDATE reserves
+        SET
+           in_current_balance_frac=in_current_balance_frac+my_amount_frac
+             - CASE
+               WHEN in_current_balance_frac + my_amount_frac >= 100000000
+                 THEN 100000000
+               ELSE 0
+               END
+              ,in_current_balance_val=in_current_balance_val+my_amount_val
+             + CASE
+               WHEN in_current_balance_frac + my_amount_frac >= 100000000
+                 THEN 1
+               ELSE 0
+               END
+               
,expiration_date=GREATEST(in_expiration_date,in_reserve_expiration)
+               ,gc_date=GREATEST(in_gc_date,in_reserve_expiration)
+             WHERE reserves.reserve_pub=in_reserve_pub;
+      RETURN;
+    ELSE
+      RETURN;
+    END IF;
+  ELSE
+    transaction_duplicate = TRUE;
+    RETURN;
+  END IF;
 END $$;
+
+COMMIT;
diff --git a/src/exchangedb/test_exchangedb_by_j.c 
b/src/exchangedb/test_exchangedb_by_j.c
index 175691e9..eb600103 100644
--- a/src/exchangedb/test_exchangedb_by_j.c
+++ b/src/exchangedb/test_exchangedb_by_j.c
@@ -33,7 +33,7 @@ static int result;
  */
 #define FAILIF(cond)                            \
   do {                                          \
-    if (! (cond)) { break;}                     \
+      if (! (cond)) {break;}                    \
     GNUNET_break (0);                           \
     goto drop;                                  \
   } while (0)
@@ -108,14 +108,15 @@ run (void *cls)
     struct GNUNET_TIME_Timestamp ts;
     struct GNUNET_TIME_Relative duration;
     struct TALER_EXCHANGEDB_ReserveInInfo reserves[batch_size];
-    enum GNUNET_DB_QueryStatus *results;
+    enum GNUNET_DB_QueryStatus results[batch_size];
     GNUNET_assert (GNUNET_OK ==
                    TALER_string_to_amount (CURRENCY ":1.000010",
                                            &value));
     now = GNUNET_TIME_absolute_get ();
     ts = GNUNET_TIME_timestamp_get ();
     plugin->start (plugin->cls,
-                   "test_by_exchange_j");
+                   "test_by_j");
+
     for (unsigned int k = 0; k<batch_size; k++)
     {
       RND_BLK (&reserves[k].reserve_pub);
@@ -123,13 +124,13 @@ run (void *cls)
       reserves[k].execution_time = ts;
       reserves[k].sender_account_details = sndr;
       reserves[k].exchange_account_name = "name";
+
     }
     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
             plugin->batch_reserves_in_insert (plugin->cls,
                                               reserves,
                                               batch_size,
-                                              &results));
-
+                                              results));
 
     plugin->commit (plugin->cls);
     duration = GNUNET_TIME_absolute_get_duration (now);

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