gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -pub


From: gnunet
Subject: [taler-exchange] branch master updated: -pub
Date: Sat, 07 May 2022 23:45:19 +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 6b8e732b -pub
6b8e732b is described below

commit 6b8e732bf8d8bfae268e7f5a9a09af9167fd0d47
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat May 7 23:45:17 2022 +0200

    -pub
---
 src/exchange/taler-exchange-router.c    |   3 +
 src/exchangedb/common-0001.sql          |   6 ++
 src/exchangedb/exchange-0001-part.sql   | 174 ++++++++++++++++++++++++++++++++
 src/include/taler_crypto_lib.h          |   4 +-
 src/testing/testing_api_cmd_purse_get.c |  12 +--
 5 files changed, 191 insertions(+), 8 deletions(-)

diff --git a/src/exchange/taler-exchange-router.c 
b/src/exchange/taler-exchange-router.c
index 8d5efff0..ca4499e3 100644
--- a/src/exchange/taler-exchange-router.c
+++ b/src/exchange/taler-exchange-router.c
@@ -33,6 +33,9 @@
 #include "taler_bank_service.h"
 
 
+// FIXME: revisit how (and if) we do sharding!
+// Maybe use different helpers for wads than
+// for local purses?!
 /**
  * Work shard we are processing.
  */
diff --git a/src/exchangedb/common-0001.sql b/src/exchangedb/common-0001.sql
index 6d45c22e..861e8547 100644
--- a/src/exchangedb/common-0001.sql
+++ b/src/exchangedb/common-0001.sql
@@ -1161,11 +1161,17 @@ BEGIN
       '(purse_requests_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY' 
--UNIQUE
       ',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
       ',merge_pub BYTEA NOT NULL CHECK (LENGTH(merge_pub)=32)'
+      ',purse_creation INT8 NOT NULL'
       ',purse_expiration INT8 NOT NULL'
       ',h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)'
       ',age_limit INT4 NOT NULL'
+      ',refunded BOOLEAN NOT NULL DEFAULT(FALSE)'
+      ',finished BOOLEAN NOT NULL DEFAULT(FALSE)'
+      ',in_reserve_quota BOOLEAN NOT NULL DEFAULT(FALSE)'
       ',amount_with_fee_val INT8 NOT NULL'
       ',amount_with_fee_frac INT4 NOT NULL'
+      ',purse_fee_val INT8 NOT NULL'
+      ',purse_fee_frac INT4 NOT NULL'
       ',balance_val INT8 NOT NULL DEFAULT (0)'
       ',balance_frac INT4 NOT NULL DEFAULT (0)'
       ',purse_sig BYTEA NOT NULL CHECK(LENGTH(purse_sig)=64)'
diff --git a/src/exchangedb/exchange-0001-part.sql 
b/src/exchangedb/exchange-0001-part.sql
index 56f1df29..4b9493bb 100644
--- a/src/exchangedb/exchange-0001-part.sql
+++ b/src/exchangedb/exchange-0001-part.sql
@@ -973,6 +973,7 @@ CREATE TABLE IF NOT EXISTS partners
   ,partner_master_pub BYTEA NOT NULL CHECK(LENGTH(partner_master_pub)=32)
   ,start_date INT8 NOT NULL
   ,end_date INT8 NOT NULL
+  ,next_wad INT8 NOT NULL DEFAULT (0)
   ,wad_frequency INT8 NOT NULL
   ,wad_fee_val INT8 NOT NULL
   ,wad_fee_frac INT4 NOT NULL
@@ -987,6 +988,8 @@ COMMENT ON COLUMN partners.start_date
   IS 'starting date of the partnership';
 COMMENT ON COLUMN partners.end_date
   IS 'end date of the partnership';
+COMMENT ON COLUMN partners.next_wad
+  IS 'at what time should we do the next wad transfer to this partner 
(frequently updated); set to forever after the end_date';
 COMMENT ON COLUMN partners.wad_frequency
   IS 'how often do we promise to do wad transfers';
 COMMENT ON COLUMN partners.wad_fee_val
@@ -996,6 +999,8 @@ COMMENT ON COLUMN partners.partner_base_url
 COMMENT ON COLUMN partners.master_sig
   IS 'signature of our master public key affirming the partnership, of purpose 
TALER_SIGNATURE_MASTER_PARTNER_DETAILS';
 
+CREATE INDEX IF NOT EXISTS partner_by_wad_time
+  ON partners (next_wad ASC);
 
 -- ------------------------------ purse_requests 
----------------------------------------
 
@@ -1005,12 +1010,24 @@ COMMENT ON TABLE purse_requests
   IS 'Requests establishing purses, associating them with a contract but 
without a target reserve';
 COMMENT ON COLUMN purse_requests.purse_pub
   IS 'Public key of the purse';
+COMMENT ON COLUMN purse_requests.purse_creation
+  IS 'Local time when the purse was created. Determines applicable purse 
fees.';
 COMMENT ON COLUMN purse_requests.purse_expiration
   IS 'When the purse is set to expire';
 COMMENT ON COLUMN purse_requests.h_contract_terms
   IS 'Hash of the contract the parties are to agree to';
+COMMENT ON COLUMN purse_requests.shard
+  IS 'for load distribution among router processes';
+COMMENT ON COLUMN purse_requests.finished
+  IS 'set to TRUE once the purse has been merged (into reserve or wad) or the 
coins were refunded (transfer aborted)';
+COMMENT ON COLUMN purse_requests.refunded
+  IS 'set to TRUE if the purse could not be merged and thus all deposited 
coins were refunded';
+COMMENT ON COLUMN purse_requests.in_reserve_quota
+  IS 'set to TRUE if this purse currently counts against the number of free 
purses in the respective reserve';
 COMMENT ON COLUMN purse_requests.amount_with_fee_val
   IS 'Total amount expected to be in the purse';
+COMMENT ON COLUMN purse_requests.purse_fee_val
+  IS 'Purse fee the client agreed to pay from the reserve (accepted by the 
exchange at the time the purse was created). Zero if in_reserve_quota is TRUE.';
 COMMENT ON COLUMN purse_requests.balance_val
   IS 'Total amount actually in the purse';
 COMMENT ON COLUMN purse_requests.purse_sig
@@ -1284,6 +1301,163 @@ COMMENT ON COLUMN partner_accounts.last_seen
   IS 'Last time we saw this account as being active at the partner exchange. 
Used to select the most recent entry, and to detect when we should check 
again.';
 
 
+----------------------- router helper table (not synchronzied) 
------------------------
+
+CREATE TABLE IF NOT EXISTS purse_actions
+  (purse_pub BYTEA NOT NULL PRIMARY KEY CHECK(LENGTH(purse_pub)=32)
+  ,action_date INT8 NOT NULL
+  ,partner_serial_id INT8
+  );
+COMMENT ON TABLE purse_actions
+  IS 'purses awaiting some action by the router';
+COMMENT ON COLUMN purse_actions.purse_pub
+  IS 'public (contract) key of the purse';
+COMMENT ON COLUMN purse_action.action_date
+  IS 'when is the purse ready for action';
+COMMENT ON COLUMN purse_action.partner_serial_id
+  IS 'wad target of an outgoing wire transfer, 0 for local, NULL if the purse 
is unmerged and thus the target is still unknown';
+
+CREATE INDEX IF NOT EXISTS purse_action_by_target
+  ON purse_actions
+  (partner_serial_id,action_date);
+
+
+CREATE OR REPLACE FUNCTION purse_requests_insert_trigger()
+  RETURNS trigger
+  LANGUAGE plpgsql
+  AS $$
+BEGIN
+  INSERT INTO
+    purse_actions
+    (purse_pub
+    ,action_date)
+  VALUES
+    (NEW.purse_pub
+    ,NEW.purse_expiration);
+  RETURN NEW;
+END $$;
+COMMENT ON FUNCTION purse_requests_insert_trigger()
+  IS 'When a purse is created, insert it into the purse_action table to take 
action when the purse expires.';
+
+CREATE TRIGGER purse_requests_on_insert
+  AFTER INSERT
+   ON purse_requests
+   FOR EACH ROW EXECUTE FUNCTION purse_requests_insert_trigger();
+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
+  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
+    -- If this purse counted against the reserve's
+    -- quota of purses, decrement the reserve accounting.
+    IF (NEW.in_reserve_quota)
+    THEN
+      UPDATE reserves
+         SET purses_active=purses_active-1
+       WHERE reserve_pub IN
+         (SELECT reserve_pub
+            FROM purse_merges
+           WHERE purse_pub=NEW.purse_pub
+           LIMIT 1);
+      NEW.in_reserve_quota=FALSE;
+    END IF;
+    -- Delete from the purse_actions table, we are done
+    -- with this purse for good.
+    DELETE FROM purse_actions
+          WHERE purse_pub=NEW.purse_pub;
+    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
+    UPDATE purse_actions
+       SET action_date=0 --- "immediately"
+          ,partner_serial_id=psi
+     WHERE purse_pub=NEW.purse_pub;
+  END IF;
+  RETURN NEW;
+END $$;
+
+COMMENT ON FUNCTION purse_requests_on_update_trigger
+  IS 'Trigger the router if the purse is ready. Also removes the entry from 
the router watchlist once the purse is fnished.';
+
+CREATE TRIGGER purse_requests_on_update
+  BEFORE UPDATE
+   ON purse_requests
+   FOR EACH ROW EXECUTE FUNCTION purse_requests_update_trigger();
+COMMENT ON TRIGGER purse_requests_on_update
+  IS 'This covers the case where a deposit is made into a purse, which 
inherently then changes the purse balance via an UPDATE. If the merge is 
already present and the balance matches the total, we trigger the router. Once 
the router sets the purse to finished, the trigger will remove the purse from 
the watchlist of the router.';
+
 ---------------------------------------------------------------------------
 --                      Stored procedures
 ---------------------------------------------------------------------------
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index cf160c68..e5572560 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -3977,7 +3977,7 @@ TALER_exchange_online_purse_merged_verify (
 
 
 enum TALER_ErrorCode
-TALER_exchange_purse_status_sign (
+TALER_exchange_online_purse_status_sign (
   TALER_ExchangeSignCallback scb,
   struct GNUNET_TIME_Timestamp merge_timestamp,
   struct GNUNET_TIME_Timestamp deposit_timestamp,
@@ -3987,7 +3987,7 @@ TALER_exchange_purse_status_sign (
 
 
 enum GNUNET_GenericReturnValue
-TALER_exchange_purse_status_verify (
+TALER_exchange_online_purse_status_verify (
   struct GNUNET_TIME_Timestamp merge_timestamp,
   struct GNUNET_TIME_Timestamp deposit_timestamp,
   const struct TALER_Amount *balance,
diff --git a/src/testing/testing_api_cmd_purse_get.c 
b/src/testing/testing_api_cmd_purse_get.c
index ed3ec3d6..828310ae 100644
--- a/src/testing/testing_api_cmd_purse_get.c
+++ b/src/testing/testing_api_cmd_purse_get.c
@@ -89,9 +89,9 @@ struct StatusState
   const char *expected_balance;
 
   /**
-   * Private key of the purse being analyzed.
+   * Public key of the purse being analyzed.
    */
-  const struct TALER_PurseContractPrivateKeyP *purse_priv;
+  const struct TALER_PurseContractPublicKeyP *purse_pub;
 
   /**
    * Interpreter state.
@@ -198,16 +198,16 @@ status_run (void *cls,
     return;
   }
   if (GNUNET_OK !=
-      TALER_TESTING_get_trait_purse_priv (create_purse,
-                                          &ss->purse_priv))
+      TALER_TESTING_get_trait_purse_pub (create_purse,
+                                         &ss->purse_pub))
   {
     GNUNET_break (0);
-    TALER_LOG_ERROR ("Failed to find purse_priv for status query\n");
+    TALER_LOG_ERROR ("Failed to find purse_pub for status query\n");
     TALER_TESTING_interpreter_fail (is);
     return;
   }
   ss->pgh = TALER_EXCHANGE_purse_get (is->exchange,
-                                      ss->purse_priv,
+                                      ss->purse_pub,
                                       ss->timeout,
                                       ss->wait_for_merge,
                                       &purse_status_cb,

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