gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: expand P2P query logic


From: gnunet
Subject: [taler-exchange] branch master updated: expand P2P query logic
Date: Sun, 08 May 2022 21:05:07 +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 60c08dcc expand P2P query logic
60c08dcc is described below

commit 60c08dccecd7e1aa578e497c57cc1fb6b29b655d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun May 8 21:04:55 2022 +0200

    expand P2P query logic
---
 src/exchange/taler-exchange-httpd_reserves_purse.c |  22 +-
 src/exchangedb/exchange-0001-part.sql              | 335 ++++++++++-----------
 src/exchangedb/plugin_exchangedb_postgres.c        |  14 +-
 src/include/taler_exchangedb_plugin.h              |   2 +-
 4 files changed, 183 insertions(+), 190 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_reserves_purse.c 
b/src/exchange/taler-exchange-httpd_reserves_purse.c
index ab105159..77321b2c 100644
--- a/src/exchange/taler-exchange-httpd_reserves_purse.c
+++ b/src/exchange/taler-exchange-httpd_reserves_purse.c
@@ -297,15 +297,19 @@ purse_transaction (void *cls,
     bool in_conflict = true;
     bool insufficient_funds = true;
 
-    qs = TEH_plugin->do_reserve_purse (TEH_plugin->cls,
-                                       &rpc->purse_pub,
-                                       &rpc->merge_sig,
-                                       rpc->merge_timestamp,
-                                       &rpc->reserve_sig,
-                                       &rpc->gf->fees.purse,
-                                       rpc->reserve_pub,
-                                       &in_conflict,
-                                       &insufficient_funds);
+    qs = TEH_plugin->do_reserve_purse (
+      TEH_plugin->cls,
+      &rpc->purse_pub,
+      &rpc->merge_sig,
+      rpc->merge_timestamp,
+      &rpc->reserve_sig,
+      (TALER_WAMF_MODE_CREATE_FROM_PURSE_QUOTA
+       == rpc->flags)
+      ? NULL
+      : &rpc->gf->fees.purse,
+      rpc->reserve_pub,
+      &in_conflict,
+      &insufficient_funds);
     if (qs < 0)
     {
       if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
diff --git a/src/exchangedb/exchange-0001-part.sql 
b/src/exchangedb/exchange-0001-part.sql
index b0c5171d..a8aebfba 100644
--- a/src/exchangedb/exchange-0001-part.sql
+++ b/src/exchangedb/exchange-0001-part.sql
@@ -1327,6 +1327,7 @@ CREATE OR REPLACE FUNCTION purse_requests_insert_trigger()
   LANGUAGE plpgsql
   AS $$
 BEGIN
+  ASSERT NOT NEW.finished,'Internal invariant violated';
   INSERT INTO
     purse_actions
     (purse_pub
@@ -1348,65 +1349,10 @@ COMMENT ON TRIGGER purse_requests_on_insert
   IS 'Here we install an entry for the purse expiration.';
 
 
-CREATE OR REPLACE FUNCTION purse_merge_insert_trigger()
-  RETURNS trigger
-  LANGUAGE plpgsql
-  AS $$
-DECLARE
-  bal_val INT8;
-DECLARE
-  bal_frac INT4;
-DECLARE
-  amount_val INT8;
-DECLARE
-  amount_frac INT4;
-DECLARE
-  was_paid BOOLEAN;
-BEGIN
-  SELECT balance_val
-        ,balance_frac
-        ,amount_with_fee_val
-        ,amount_with_fee_frac
-    INTO bal_val
-        ,bal_frac
-        ,amount_val
-        ,amount_frac
-    FROM purse_requests
-   WHERE purse_pub=NEW.purse_pub;
-  was_paid = (bal_val > NEW.amount_val) OR
-             ( (bal_val = NEW.amount_val) AND
-               (bal_frac >= NEW.amount_frac) );
-  IF (was_paid)
-  THEN
-    UPDATE purse_actions
-       SET action_date=0 --- "immediately"
-          ,partner_serial_id=NEW.partner_serial_id
-     WHERE purse_pub=NEW.purse_pub;
-  END IF;
-  RETURN NEW;
-END $$;
-COMMENT ON FUNCTION purse_merge_insert_trigger()
-  IS 'Triggers merge if purse is fully paid.';
-
-CREATE TRIGGER purse_merges_on_insert
-  AFTER INSERT
-   ON purse_merges
-   FOR EACH ROW EXECUTE FUNCTION purse_merge_insert_trigger();
-COMMENT ON TRIGGER purse_merges_on_insert
-  ON purse_merges
-  IS 'Here we install an entry that triggers the merge (if the purse is 
already full).';
-
-
 CREATE OR REPLACE FUNCTION purse_requests_on_update_trigger()
   RETURNS trigger
   LANGUAGE plpgsql
   AS $$
-DECLARE
-  was_merged BOOLEAN;
-DECLARE
-  psi INT8; -- partner's serial ID (set if merged)
-DECLARE
-  was_paid BOOLEAN;
 BEGIN
   IF (NEW.finished)
   THEN
@@ -1430,27 +1376,6 @@ BEGIN
     RETURN NEW;
   END IF;
 
-  -- Not finished, see if we need to update the
-  -- trigger time and partner.
-  SELECT partner_serial_id
-    INTO psi
-    FROM purse_merges
-   WHERE purse_pub=NEW.purse_pub;
-  was_merged = FOUND;
-  was_paid = (NEW.balance_val > NEW.amount_with_fee_val) OR
-             ( (NEW.balance_val = NEW.amount_with_fee_val) AND
-               (NEW.balance_frac >= NEW.amount_with_fee_frac) );
-  IF (was_merged AND was_paid)
-  THEN
-    -- FIXME: If 0==psi, why not simply DO the merge here?
-    -- Adding up reserve balance + setting finished
-    -- is hardly doing much, and could be combined
-    -- with the reserve update above!
-    UPDATE purse_actions
-       SET action_date=0 --- "immediately"
-          ,partner_serial_id=psi
-     WHERE purse_pub=NEW.purse_pub;
-  END IF;
   RETURN NEW;
 END $$;
 
@@ -2912,7 +2837,6 @@ END $$;
 
 
 
-
 CREATE OR REPLACE FUNCTION exchange_do_purse_deposit(
   IN in_partner_id INT8,
   IN in_purse_pub BYTEA,
@@ -2926,6 +2850,14 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_deposit(
   OUT out_conflict BOOLEAN)
 LANGUAGE plpgsql
 AS $$
+DECLARE
+  was_merged BOOLEAN;
+DECLARE
+  psi INT8; -- partner's serial ID (set if merged)
+DECLARE
+  was_paid BOOLEAN;
+DECLARE
+  my_reserve_pub BYTEA;
 BEGIN
 
 -- Store the deposit request.
@@ -3015,9 +2947,68 @@ UPDATE purse_requests
 out_conflict=FALSE;
 out_balance_ok=TRUE;
 
+-- See if we can finish the merge or need to update the trigger time and 
partner.
+SELECT partner_serial_id
+      ,reserve_pub
+  INTO psi
+      ,my_reserve_pub
+  FROM purse_merges
+ WHERE purse_pub=in_purse_pub;
+
+IF NOT FOUND
+THEN
+  RETURN;
+END IF;
+
+SELECT
+  1
+  FROM purse_requests
+  WHERE (purse_pub=in_purse_pub)
+    AND ( ( ( (amount_with_fee_val <= balance_val)
+          AND (amount_with_fee_frac <= balance_frac) )
+         OR (amount_with_fee_val < balance_val) ) );
+IF NOT FOUND
+THEN
+  RETURN;
+END IF;
+
+IF (0 != psi)
+THEN
+  -- The taler-exchange-router will take care of this.
+  UPDATE purse_actions
+     SET action_date=0 --- "immediately"
+        ,partner_serial_id=psi
+   WHERE purse_pub=in_purse_pub;
+ELSE
+  -- This is a local reserve, update balance immediately.
+  UPDATE reserves
+  SET
+    current_balance_frac=current_balance_frac+amount_frac
+       - CASE
+         WHEN current_balance_frac + amount_frac >= 100000000
+         THEN 100000000
+         ELSE 0
+         END,
+    current_balance_val=current_balance_val+amount_val
+       + CASE
+         WHEN current_balance_frac + amount_frac >= 100000000
+         THEN 1
+         ELSE 0
+         END
+  WHERE reserve_pub=my_reserve_pub;
+
+  -- ... and mark purse as finished.
+  UPDATE purse_requests
+     SET finished=true
+  WHERE purse_pub=in_purse_pub;
+END IF;
+
+
 END $$;
 
 
+
+
 CREATE OR REPLACE FUNCTION exchange_do_purse_merge(
   IN in_purse_pub BYTEA,
   IN in_merge_sig BYTEA,
@@ -3030,8 +3021,14 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_merge(
   OUT out_conflict BOOLEAN)
 LANGUAGE plpgsql
 AS $$
+DECLARE
+  amount_val INT8;
+DECLARE
+  amount_frac INT4;
 DECLARE
   my_partner_serial_id INT8;
+DECLARE
+  my_finished BOOLEAN;
 BEGIN
 
 IF in_partner_url IS NULL
@@ -3058,7 +3055,12 @@ out_no_partner=FALSE;
 
 
 -- Check purse is 'full'.
-PERFORM
+SELECT amount_with_fee_val
+      ,amount_with_fee_frac
+      ,finished
+  INTO amount_val
+      ,amount_frac
+      ,my_finished
   FROM purse_requests
   WHERE purse_pub=in_purse_pub
     AND balance_val >= amount_with_fee_val
@@ -3072,8 +3074,6 @@ THEN
 END IF;
 out_no_balance=FALSE;
 
-
-
 -- Store purse merge signature, checks for purse_pub uniqueness
 INSERT INTO purse_merges
     (partner_serial_id
@@ -3111,6 +3111,8 @@ THEN
 END IF;
 out_conflict=FALSE;
 
+ASSERT NOT my_finished, 'internal invariant failed';
+
 -- Store account merge signature.
 INSERT INTO account_merges
   (reserve_pub
@@ -3121,13 +3123,45 @@ INSERT INTO account_merges
   ,in_reserve_sig
   ,in_purse_pub);
 
+-- If we need a wad transfer, mark purse ready for it.
+IF (0 != my_partner_serial_id)
+THEN
+  -- The taler-exchange-router will take care of this.
+  UPDATE purse_actions
+     SET action_date=0 --- "immediately"
+        ,partner_serial_id=NEW.partner_serial_id
+   WHERE purse_pub=NEW.purse_pub;
+ELSE
+  -- This is a local reserve, update balance immediately.
+  UPDATE reserves
+  SET
+    current_balance_frac=current_balance_frac+amount_frac
+       - CASE
+         WHEN current_balance_frac + amount_frac >= 100000000
+         THEN 100000000
+         ELSE 0
+         END,
+    current_balance_val=current_balance_val+amount_val
+       + CASE
+         WHEN current_balance_frac + amount_frac >= 100000000
+         THEN 1
+         ELSE 0
+         END
+  WHERE reserve_pub=in_reserve_pub;
+
+  -- ... and mark purse as finished.
+  UPDATE purse_requests
+     SET finished=true
+  WHERE purse_pub=in_purse_pub;
+END IF;
+
 
 RETURN;
 
 END $$;
 
--- COMMENT ON FUNCTION exchange_do_purse_merge()
---  IS 'Checks that the partner exists, the purse has not been merged with a 
different reserve and that the purse is full. If so, persists the merge data. 
Caller MUST abort the transaction on failures so as to not persist data by 
accident.';
+COMMENT ON FUNCTION exchange_do_purse_merge(BYTEA, BYTEA, INT8, BYTEA, 
VARCHAR, BYTEA)
+  IS 'Checks that the partner exists, the purse has not been merged with a 
different reserve and that the purse is full. If so, persists the merge data 
and either merges the purse with the reserve or marks it as ready for the 
taler-exchange-router. Caller MUST abort the transaction on failures so as to 
not persist data by accident.';
 
 
 CREATE OR REPLACE FUNCTION exchange_do_reserve_purse(
@@ -3135,6 +3169,7 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_purse(
   IN in_merge_sig BYTEA,
   IN in_merge_timestamp INT8,
   IN in_reserve_sig BYTEA,
+  IN in_reserve_quota BOOLEAN,
   IN in_purse_fee_val INT8,
   IN in_purse_fee_frac INT4,
   IN in_reserve_pub BYTEA,
@@ -3142,26 +3177,8 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_purse(
   OUT out_conflict BOOLEAN)
 LANGUAGE plpgsql
 AS $$
-DECLARE
-  my_purses_active INT8;
-DECLARE
-  my_purses_allowed INT8;
-DECLARE
-  my_balance_val INT8;
-DECLARE
-  my_balance_frac INT4;
-DECLARE
-  my_kyc_passed BOOLEAN;
 BEGIN
 
--- comment out for now
-IF TRUE
-THEN
-  out_no_funds=FALSE;
-  out_conflict=FALSE;
-  RETURN;
-END IF;
-
 -- Store purse merge signature, checks for purse_pub uniqueness
 INSERT INTO purse_merges
     (partner_serial_id
@@ -3201,6 +3218,48 @@ END IF;
 out_conflict=FALSE;
 
 
+IF (in_reserve_quota)
+THEN
+  -- Increment active purses per reserve (and check this is allowed)
+  UPDATE reserves
+     SET purses_active=purses_active+1
+        ,kyc_required=TRUE
+   WHERE reserve_pub=in_reserve_pub
+     AND purses_active < purses_allowed;
+  IF NOT FOUND
+  THEN
+    out_no_funds=TRUE;
+  END IF;
+ELSE
+  --  UPDATE reserves balance (and check if balance is enough to pay the fee)
+  UPDATE reserves
+  SET
+    current_balance_frac=current_balance_frac-in_purse_fee_frac
+       + CASE
+         WHEN current_balance_frac < in_purse_fee_frac
+         THEN 100000000
+         ELSE 0
+         END,
+    current_balance_val=current_balance_val-in_purse_fee_val
+       - CASE
+         WHEN current_balance_frac < in_purse_fee_frac
+         THEN 1
+         ELSE 0
+         END
+    ,kyc_required=TRUE
+  WHERE reserve_pub=in_reserve_pub
+    AND ( (current_balance_val > in_purse_fee_val) OR
+          ( (current_balance_frac >= in_purse_fee_frac) AND
+            (current_balance_val >= in_purse_fee_val) ) );
+  IF NOT FOUND
+  THEN
+    out_no_funds=TRUE;
+  END IF;
+END IF;
+
+out_no_funds=FALSE;
+
+
 -- Store account merge signature.
 INSERT INTO account_merges
   (reserve_pub
@@ -3211,82 +3270,6 @@ INSERT INTO account_merges
   ,in_reserve_sig
   ,in_purse_pub);
 
-
-
--- Charge reserve for purse creation.
--- FIXME: Use different type of purse
--- signature in this case, so that we
--- can properly account for the purse
--- fees when auditing!!!
-SELECT
-  purses_active
- ,purses_allowed
- ,kyc_passed
- ,current_balance_val
- ,current_balance_frac
-INTO
-  my_purses_active
- ,my_purses_allowed
- ,my_kyc_passed
- ,my_balance_val
- ,my_balance_frac
-FROM reserves
-WHERE reserve_pub=in_reserve_pub;
-
-IF NOT FOUND
-THEN
-  out_no_funds=TRUE;
-  -- FIXME: be more specific in the returned
-  -- error that we don't know the reserve
-  -- (instead of merely saying it has no funds)
-  RETURN;
-END IF;
-
-IF NOT my_kyc_passed
-THEN
-  -- FIXME: might want to categorically disallow
-  -- purse creation without KYC (depending on
-  -- exchange settings => new argument?)
-END IF;
-
-IF ( (my_purses_active >= my_purses_allowed) AND
-     ( (my_balance_val < in_purse_fee_val) OR
-       ( (my_balance_val <= in_purse_fee_val) AND
-         (my_balance_frac < in_purse_fee_frac) ) ) )
-THEN
-  out_no_funds=TRUE;
-  RETURN;
-END IF;
-
-IF (my_purses_active < my_purses_allowed)
-THEN
-  my_purses_active = my_purses_active + 1;
-ELSE
-  -- FIXME: See above: we should probably have
-  -- very explicit wallet-approval in the
-  -- signature to charge the reserve!
-  my_balance_val = my_balance_val - in_purse_fee_val;
-  IF (my_balance_frac > in_purse_fee_frac)
-  THEN
-    my_balance_frac = my_balance_frac - in_purse_fee_frac;
-  ELSE
-    my_balance_val = my_balance_val - 1;
-    my_balance_frac = my_balance_frac + 100000000 - in_purse_fee_frac;
-  END IF;
-END IF;
-
-UPDATE reserves SET
-  gc_date=min_reserve_gc
- ,current_balance_val=my_balance_val
- ,current_balance_frac=my_balance_frac
- ,purses_active=my_purses_active
- ,kyc_required=TRUE
-WHERE
-  reserves.reserve_pub=rpub;
-
-out_no_funds=FALSE;
-
-
 END $$;
 
 
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index a4807d03..83a64be8 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -3630,8 +3630,8 @@ prepare_statements (struct PostgresClosure *pg)
       " out_no_funds AS insufficient_funds"
       ",out_conflict AS conflict"
       " FROM exchange_do_reserve_purse"
-      "  ($1, $2, $3, $4, $5, $6, $7);",
-      7),
+      "  ($1, $2, $3, $4, $5, $6, $7, $8);",
+      8),
     /* Used in #postgres_select_purse_merge */
     GNUNET_PQ_make_prepare (
       "select_purse_merge",
@@ -13853,7 +13853,7 @@ postgres_do_purse_merge (
  * @param merge_sig signature affirming the merge
  * @param merge_timestamp time of the merge
  * @param reserve_sig signature of the reserve affirming the merge
- * @param purse_fee amount to charge the reserve for the purse creation
+ * @param purse_fee amount to charge the reserve for the purse creation, NULL 
to use the quota
  * @param reserve_pub public key of the reserve to credit
  * @param[out] in_conflict set to true if @a purse_pub was merged into a 
different reserve already
  * @param[out] insufficient_funds set to true if @a reserve_pub has 
insufficient capacity to create another purse
@@ -13872,12 +13872,16 @@ postgres_do_reserve_purse (
   bool *insufficient_funds)
 {
   struct PostgresClosure *pg = cls;
+  struct TALER_Amount zero_fee;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (purse_pub),
     GNUNET_PQ_query_param_auto_from_type (merge_sig),
     GNUNET_PQ_query_param_timestamp (&merge_timestamp),
     GNUNET_PQ_query_param_auto_from_type (reserve_sig),
-    TALER_PQ_query_param_amount (purse_fee),
+    GNUNET_PQ_query_param_bool (NULL == purse_fee),
+    TALER_PQ_query_param_amount (NULL == purse_fee
+                                 ? &zero_fee
+                                 : purse_fee),
     GNUNET_PQ_query_param_auto_from_type (reserve_pub),
     GNUNET_PQ_query_param_end
   };
@@ -13889,6 +13893,8 @@ postgres_do_reserve_purse (
     GNUNET_PQ_result_spec_end
   };
 
+  TALER_amount_set_zero (pg->currency,
+                         &zero_fee);
   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "call_reserve_purse",
                                                    params,
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 7fafdb26..f95ba75a 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -4779,7 +4779,7 @@ struct TALER_EXCHANGEDB_Plugin
    * @param merge_sig signature affirming the merge
    * @param merge_timestamp time of the merge
    * @param reserve_sig signature of the reserve affirming the merge
-   * @param purse_fee amount to charge the reserve for the purse creation
+   * @param purse_fee amount to charge the reserve for the purse creation, 
NULL to use the quota
    * @param reserve_pub public key of the reserve to credit
    * @param[out] in_conflict set to true if @a purse_pub was merged into a 
different reserve already
    * @param[out] insufficient_funds set to true if @a reserve_pub has 
insufficient capacity to create another purse

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