gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -implemented bounded history for


From: gnunet
Subject: [taler-exchange] branch master updated: -implemented bounded history for reserve status requests
Date: Tue, 05 Jul 2022 14:25:33 +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 36a8ecd4 -implemented bounded history for reserve status requests
36a8ecd4 is described below

commit 36a8ecd4c47eaaab767d679564aa4e87166fa361
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Jul 5 14:25:30 2022 +0200

    -implemented bounded history for reserve status requests
---
 .../taler-exchange-httpd_reserves_status.c         |  33 ++-
 src/exchangedb/plugin_exchangedb_postgres.c        | 224 +++++++++++++++++++--
 src/include/taler_exchangedb_plugin.h              |   8 +-
 3 files changed, 247 insertions(+), 18 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_reserves_status.c 
b/src/exchange/taler-exchange-httpd_reserves_status.c
index 5b7becb9..ff8a65c2 100644
--- a/src/exchange/taler-exchange-httpd_reserves_status.c
+++ b/src/exchange/taler-exchange-httpd_reserves_status.c
@@ -58,6 +58,18 @@ struct ReserveStatusContext
    */
   struct TALER_EXCHANGEDB_KycStatus kyc;
 
+  /**
+   * Sum of incoming transactions within the returned history.
+   * (currently not used).
+   */
+  struct TALER_Amount balance_in;
+
+  /**
+   * Sum of outgoing transactions within the returned history.
+   * (currently not used).
+   */
+  struct TALER_Amount balance_out;
+
   /**
    * Current reserve balance.
    */
@@ -135,10 +147,11 @@ reserve_status_transaction (void *cls,
                                            "inselect_wallet_status");
     return qs;
   }
-  qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
-                                        rsc->reserve_pub,
-                                        &rsc->balance,
-                                        &rsc->rh);
+  qs = TEH_plugin->get_reserve_status (TEH_plugin->cls,
+                                       rsc->reserve_pub,
+                                       &rsc->balance_in,
+                                       &rsc->balance_out,
+                                       &rsc->rh);
   if (GNUNET_DB_STATUS_HARD_ERROR == qs)
   {
     GNUNET_break (0);
@@ -148,6 +161,18 @@ reserve_status_transaction (void *cls,
                                     TALER_EC_GENERIC_DB_FETCH_FAILED,
                                     "get_reserve_status");
   }
+  qs = TEH_plugin->get_reserve_balance (TEH_plugin->cls,
+                                        rsc->reserve_pub,
+                                        &rsc->balance);
+  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_balance");
+  }
   return qs;
 }
 
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 63f07521..b9debfa4 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -815,6 +815,42 @@ prepare_statements (struct PostgresClosure *pg)
       "  SELECT wire_source_h_payto FROM ri "
       "); ",
       1),
+    /* Used in #postgres_get_reserve_status() to obtain inbound transactions
+       for a reserve */
+    GNUNET_PQ_make_prepare (
+      "reserves_in_get_transactions_truncated",
+      /*
+      "SELECT"
+      " wire_reference"
+      ",credit_val"
+      ",credit_frac"
+      ",execution_date"
+      ",payto_uri AS sender_account_details"
+      " FROM reserves_in"
+      " JOIN wire_targets"
+      "   ON (wire_source_h_payto = wire_target_h_payto)"
+      " WHERE reserve_pub=$1"
+      "   AND execution_date>=$2;",
+      */
+      "WITH ri AS MATERIALIZED ( "
+      "  SELECT * "
+      "  FROM reserves_in "
+      "  WHERE reserve_pub = $1 "
+      ") "
+      "SELECT  "
+      "  wire_reference "
+      "  ,credit_val "
+      "  ,credit_frac "
+      "  ,execution_date "
+      "  ,payto_uri AS sender_account_details "
+      "FROM wire_targets "
+      "JOIN ri  "
+      "  ON (wire_target_h_payto = wire_source_h_payto) "
+      "WHERE execution_date >= $2"
+      "  AND wire_target_h_payto = ( "
+      "  SELECT wire_source_h_payto FROM ri "
+      "); ",
+      2),
     /* Used in #postgres_do_withdraw() to store
        the signature of a blinded coin with the blinded coin's
        details before returning it during /reserve/withdraw. We store
@@ -1020,6 +1056,58 @@ prepare_statements (struct PostgresClosure *pg)
       "JOIN denominations denom "
       "  ON (ro.denominations_serial = denom.denominations_serial); ",
       1),
+    /* Used during #postgres_get_reserve_status() to
+       obtain all of the /reserve/withdraw operations that
+       have been performed on a given reserve. (i.e. to
+       demonstrate double-spending) */
+    GNUNET_PQ_make_prepare (
+      "get_reserves_out_truncated",
+      /*
+      "SELECT"
+      " ro.h_blind_ev"
+      ",denom.denom_pub_hash"
+      ",ro.denom_sig"
+      ",ro.reserve_sig"
+      ",ro.execution_date"
+      ",ro.amount_with_fee_val"
+      ",ro.amount_with_fee_frac"
+      ",denom.fee_withdraw_val"
+      ",denom.fee_withdraw_frac"
+      " FROM reserves res"
+      " JOIN reserves_out_by_reserve ror"
+      "   ON (res.reserve_uuid = ror.reserve_uuid)"
+      " JOIN reserves_out ro"
+      "   ON (ro.h_blind_ev = ror.h_blind_ev)"
+      " JOIN denominations denom"
+      "   ON (ro.denominations_serial = denom.denominations_serial)"
+      " WHERE res.reserve_pub=$1"
+      "   AND execution_date>=$2;",
+      */
+      "WITH robr AS MATERIALIZED ( "
+      "  SELECT h_blind_ev "
+      "  FROM reserves_out_by_reserve "
+      "  WHERE reserve_uuid= ( "
+      "    SELECT reserve_uuid "
+      "    FROM reserves "
+      "    WHERE reserve_pub = $1 "
+      "  ) "
+      ") SELECT "
+      "  ro.h_blind_ev "
+      "  ,denom.denom_pub_hash "
+      "  ,ro.denom_sig "
+      "  ,ro.reserve_sig "
+      "  ,ro.execution_date "
+      "  ,ro.amount_with_fee_val "
+      "  ,ro.amount_with_fee_frac "
+      "  ,denom.fee_withdraw_val "
+      "  ,denom.fee_withdraw_frac "
+      "FROM robr "
+      "JOIN reserves_out ro "
+      "  ON (ro.h_blind_ev = robr.h_blind_ev) "
+      "JOIN denominations denom "
+      "  ON (ro.denominations_serial = denom.denominations_serial)"
+      " WHERE ro.execution_date>=$2;",
+      2),
     /* Used in #postgres_select_withdrawals_above_serial_id() */
 
     GNUNET_PQ_make_prepare (
@@ -2240,6 +2328,51 @@ prepare_statements (struct PostgresClosure *pg)
       "  JOIN exchange_do_recoup_by_reserve($1) robr"
       " USING (denominations_serial);",
       1),
+    /* Used in #postgres_get_reserve_status() to obtain recoup transactions
+       for a reserve - query optimization should be disabled i.e.
+       BEGIN; SET LOCAL join_collapse_limit=1; query; COMMIT; */
+    GNUNET_PQ_make_prepare (
+      "recoup_by_reserve_truncated",
+      /*
+      "SELECT"
+      " recoup.coin_pub"
+      ",recoup.coin_sig"
+      ",recoup.coin_blind"
+      ",recoup.amount_val"
+      ",recoup.amount_frac"
+      ",recoup.recoup_timestamp"
+      ",denominations.denom_pub_hash"
+      ",known_coins.denom_sig"
+      " FROM denominations"
+      " JOIN (known_coins"
+      "   JOIN recoup "
+      "   ON (recoup.coin_pub = known_coins.coin_pub))"
+      "  ON (known_coins.denominations_serial = 
denominations.denominations_serial)"
+      " WHERE recoup_timestamp>=$2"
+      " AND recoup.coin_pub"
+      "  IN (SELECT coin_pub"
+      "     FROM recoup_by_reserve"
+      "     JOIN (reserves_out"
+      "       JOIN (reserves_out_by_reserve"
+      "         JOIN reserves"
+      "           ON (reserves.reserve_uuid = 
reserves_out_by_reserve.reserve_uuid))"
+      "       ON (reserves_out_by_reserve.h_blind_ev = 
reserves_out.h_blind_ev))"
+      "     ON (recoup_by_reserve.reserve_out_serial_id = 
reserves_out.reserve_out_serial_id)"
+      "     WHERE reserves.reserve_pub=$1);",
+      */
+      "SELECT robr.coin_pub "
+      "  ,robr.coin_sig "
+      "  ,robr.coin_blind "
+      "  ,robr.amount_val "
+      "  ,robr.amount_frac "
+      "  ,robr.recoup_timestamp "
+      "  ,denominations.denom_pub_hash "
+      "  ,robr.denom_sig "
+      "FROM denominations "
+      "  JOIN exchange_do_recoup_by_reserve($1) robr"
+      "    USING (denominations_serial)"
+      " WHERE recoup_timestamp>=$2;",
+      2),
     /* Used in #postgres_get_coin_transactions() to obtain recoup transactions
        affecting old coins of refreshed coins */
     GNUNET_PQ_make_prepare (
@@ -2282,6 +2415,23 @@ prepare_statements (struct PostgresClosure *pg)
       "     USING (wire_target_h_payto)"
       " WHERE reserve_pub=$1;",
       1),
+    /* Used in #postgres_get_reserve_status() */
+    GNUNET_PQ_make_prepare (
+      "close_by_reserve_truncated",
+      "SELECT"
+      " amount_val"
+      ",amount_frac"
+      ",closing_fee_val"
+      ",closing_fee_frac"
+      ",execution_date"
+      ",payto_uri AS receiver_account"
+      ",wtid"
+      " FROM reserves_close"
+      "   JOIN wire_targets"
+      "     USING (wire_target_h_payto)"
+      " WHERE reserve_pub=$1"
+      "   AND execution_date>=$2;",
+      2),
     /* Used in #postgres_get_reserve_history() */
     GNUNET_PQ_make_prepare (
       "merge_by_reserve",
@@ -2311,6 +2461,36 @@ prepare_statements (struct PostgresClosure *pg)
       "  AND pr.finished"
       "  AND NOT pr.refunded;",
       1),
+    /* Used in #postgres_get_reserve_status() */
+    GNUNET_PQ_make_prepare (
+      "merge_by_reserve_truncated",
+      "SELECT"
+      " pr.amount_with_fee_val"
+      ",pr.amount_with_fee_frac"
+      ",pr.balance_val"
+      ",pr.balance_frac"
+      ",pr.purse_fee_val"
+      ",pr.purse_fee_frac"
+      ",pr.h_contract_terms"
+      ",pr.merge_pub"
+      ",am.reserve_sig"
+      ",pm.purse_pub"
+      ",pm.merge_timestamp"
+      ",pr.purse_expiration"
+      ",pr.age_limit"
+      ",pr.flags"
+      " FROM purse_merges pm"
+      "   JOIN purse_requests pr"
+      "     USING (purse_pub)"
+      "   JOIN account_merges am"
+      "     ON (am.purse_pub = pm.purse_pub AND"
+      "         am.reserve_pub = pm.reserve_pub)"
+      " WHERE pm.reserve_pub=$1"
+      "  AND pm.merge_timestamp >= $2"
+      "  AND pm.partner_serial_id=0" /* must be local! */
+      "  AND pr.finished"
+      "  AND NOT pr.refunded;",
+      2),
     /* Used in #postgres_get_reserve_history() */
     GNUNET_PQ_make_prepare (
       "history_by_reserve",
@@ -2322,6 +2502,18 @@ prepare_statements (struct PostgresClosure *pg)
       " FROM history_requests"
       " WHERE reserve_pub=$1;",
       1),
+    /* Used in #postgres_get_reserve_status() */
+    GNUNET_PQ_make_prepare (
+      "history_by_reserve_truncated",
+      "SELECT"
+      " history_fee_val"
+      ",history_fee_frac"
+      ",request_timestamp"
+      ",reserve_sig"
+      " FROM history_requests"
+      " WHERE reserve_pub=$1"
+      "  AND request_timestamp>=$2;",
+      2),
     /* Used in #postgres_get_expired_reserves() */
     GNUNET_PQ_make_prepare (
       "get_expired_reserves",
@@ -7031,14 +7223,18 @@ postgres_get_reserve_history (void *cls,
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
  * @param reserve_pub public key of the reserve
- * @param[out] balance set to the reserve balance
+ * @param[out] balance_in set to the total of inbound
+ *             transactions in the returned history
+ * @param[out] balance_out set to the total of outbound
+ *             transactions in the returned history
  * @param[out] rhp set to known transaction history (NULL if reserve is 
unknown)
  * @return transaction status
  */
 static enum GNUNET_DB_QueryStatus
 postgres_get_reserve_status (void *cls,
                              const struct TALER_ReservePublicKeyP *reserve_pub,
-                             struct TALER_Amount *balance,
+                             struct TALER_Amount *balance_in,
+                             struct TALER_Amount *balance_out,
                              struct TALER_EXCHANGEDB_ReserveHistory **rhp)
 {
   struct PostgresClosure *pg = cls;
@@ -7055,33 +7251,39 @@ postgres_get_reserve_status (void *cls,
     GNUNET_PQ_PostgresResultHandler cb;
   } work[] = {
     /** #TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE */
-    { "reserves_in_get_transactions",
+    { "reserves_in_get_transactions_truncated",
       add_bank_to_exchange },
     /** #TALER_EXCHANGEDB_RO_WITHDRAW_COIN */
-    { "get_reserves_out",
+    { "get_reserves_out_truncated",
       &add_withdraw_coin },
     /** #TALER_EXCHANGEDB_RO_RECOUP_COIN */
-    { "recoup_by_reserve",
+    { "recoup_by_reserve_truncated",
       &add_recoup },
     /** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */
-    { "close_by_reserve",
+    { "close_by_reserve_truncated",
       &add_exchange_to_bank },
     /** #TALER_EXCHANGEDB_RO_PURSE_MERGE */
-    { "merge_by_reserve",
+    { "merge_by_reserve_truncated",
       &add_p2p_merge },
     /** #TALER_EXCHANGEDB_RO_HISTORY_REQUEST */
-    { "history_by_reserve",
+    { "history_by_reserve_truncated",
       &add_history_requests },
     /* List terminator */
     { NULL,
       NULL }
   };
   enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_TIME_Absolute timelimit;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (reserve_pub),
+    GNUNET_PQ_query_param_absolute_time (&timelimit),
     GNUNET_PQ_query_param_end
   };
 
+  timelimit = GNUNET_TIME_absolute_subtract (
+    GNUNET_TIME_absolute_get (),
+    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_WEEKS,
+                                   5));
   /* FIXME: actually implement reserve history truncation logic! */
   rhc.reserve_pub = reserve_pub;
   rhc.rh = NULL;
@@ -7119,10 +7321,8 @@ postgres_get_reserve_status (void *cls,
     }
   }
   *rhp = rhc.rh;
-  GNUNET_assert (0 <=
-                 TALER_amount_subtract (balance,
-                                        &rhc.balance_in,
-                                        &rhc.balance_out));
+  *balance_in = rhc.balance_in;
+  *balance_out = rhc.balance_out;
   return qs;
 }
 
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 4a871786..82c46cdc 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -3442,14 +3442,18 @@ struct TALER_EXCHANGEDB_Plugin
    *
    * @param cls the @e cls of this struct with the plugin-specific state
    * @param reserve_pub public key of the reserve
-   * @param[out] balance set to the reserve balance
+   * @param[out] balance_in set to the total of inbound
+   *             transactions in the returned history
+   * @param[out] balance_out set to the total of outbound
+   *             transactions in the returned history
    * @param[out] rhp set to known transaction history (NULL if reserve is 
unknown)
    * @return transaction status
    */
   enum GNUNET_DB_QueryStatus
   (*get_reserve_status)(void *cls,
                         const struct TALER_ReservePublicKeyP *reserve_pub,
-                        struct TALER_Amount *balance,
+                        struct TALER_Amount *balance_in,
+                        struct TALER_Amount *balance_out,
                         struct TALER_EXCHANGEDB_ReserveHistory **rhp);
 
 

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