[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-exchange] branch master updated: -implement reserve history DB logic,
gnunet <=