aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-04-02 18:02:07 +0200
committerChristian Grothoff <christian@grothoff.org>2017-04-02 18:02:07 +0200
commitd8542d729ab8e285176bc29beb42ae7a19afa7e7 (patch)
tree4159ad02381c2ff5d89adf5c32feab3c944f0b1a
parent94dddbbe8281c71890eef1a9aa8384d99e26d5c2 (diff)
implement returning /paybacks as part of reserve history (#3887)
-rw-r--r--src/exchange/taler-exchange-httpd_db.c1
-rw-r--r--src/exchangedb/plugin_exchangedb_common.c5
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c105
-rw-r--r--src/include/taler_exchangedb_plugin.h27
4 files changed, 126 insertions, 12 deletions
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index 3c1a24778..686c06640 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -2367,6 +2367,7 @@ TEH_DB_execute_payback (struct MHD_Connection *connection,
coin_sig,
coin_blind,
&amount,
+ h_blind,
&payback_deadline);
if (GNUNET_SYSERR == ret)
{
diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c
index 7b29b1d85..2fb480415 100644
--- a/src/exchangedb/plugin_exchangedb_common.c
+++ b/src/exchangedb/plugin_exchangedb_common.c
@@ -32,6 +32,7 @@ common_free_reserve_history (void *cls,
{
struct TALER_EXCHANGEDB_BankTransfer *bt;
struct TALER_EXCHANGEDB_CollectableBlindcoin *cbc;
+ struct TALER_EXCHANGEDB_Payback *payback;
struct TALER_EXCHANGEDB_ReserveHistory *backref;
while (NULL != rh)
@@ -54,7 +55,9 @@ common_free_reserve_history (void *cls,
GNUNET_free (cbc);
break;
case TALER_EXCHANGEDB_RO_PAYBACK_COIN:
- GNUNET_free (rh->details.payback);
+ payback = rh->details.payback;
+ GNUNET_CRYPTO_rsa_public_key_free (payback->denom_pub.rsa_public_key);
+ GNUNET_free (payback);
break;
}
backref = rh;
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 4cda4b052..d69cb4180 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015, 2016 GNUnet e.V.
+ Copyright (C) 2014, 2015, 2016, 2017 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -221,6 +221,8 @@ postgres_drop_tables (void *cls)
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS prewire;");
SQLEXEC_ (conn,
+ "DROP TABLE IF EXISTS payback;");
+ SQLEXEC_ (conn,
"DROP TABLE IF EXISTS aggregation_tracking;");
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS wire_out CASCADE;");
@@ -243,7 +245,7 @@ postgres_drop_tables (void *cls)
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS known_coins CASCADE;");
SQLEXEC_ (conn,
- "DROP TABLE IF EXISTS reserves_out;");
+ "DROP TABLE IF EXISTS reserves_out CASCADE;");
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS reserves_in;");
SQLEXEC_ (conn,
@@ -521,6 +523,7 @@ postgres_create_tables (void *cls)
",amount_frac INT4 NOT NULL"
",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
",timestamp INT8 NOT NULL"
+ ",h_blind_ev BYTEA NOT NULL REFERENCES reserves_out (h_blind_ev) ON DELETE CASCADE"
")");
SQLEXEC_INDEX("CREATE INDEX payback_by_coin_index "
"ON payback(coin_pub)");
@@ -1410,9 +1413,30 @@ postgres_prepare (PGconn *db_conn)
",amount_frac"
",amount_curr"
",timestamp"
+ ",h_blind_ev"
") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8)",
- 8, NULL);
+ "($1, $2, $3, $4, $5, $6, $7, $8, $9)",
+ 9, NULL);
+
+ /* Used in #postgres_get_reserve_history() to obtain payback transactions
+ for a reserve */
+ PREPARE ("payback_by_reserve",
+ "SELECT"
+ " coin_pub"
+ ",coin_sig"
+ ",coin_blind"
+ ",amount_val"
+ ",amount_frac"
+ ",amount_curr"
+ ",timestamp"
+ ",denom.denom_pub"
+ ",denom.denom_sig"
+ " FROM payback"
+ " JOIN reserves_out denom USING (h_blind_ev)"
+ " WHERE payback.reserve_pub=$1",
+ 1, NULL);
+
+
/* Used in #postgres_get_reserve_by_h_blind() */
PREPARE ("reserve_by_h_blind",
@@ -2202,6 +2226,7 @@ postgres_get_reserve_history (void *cls,
rh = NULL;
rh_tail = NULL;
ret = GNUNET_SYSERR;
+ /** #TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE */
{
struct TALER_EXCHANGEDB_BankTransfer *bt;
struct GNUNET_PQ_QueryParam params[] = {
@@ -2265,6 +2290,7 @@ postgres_get_reserve_history (void *cls,
} /* end of 'while (0 < rows)' */
PQclear (result);
}
+ /** #TALER_EXCHANGEDB_RO_WITHDRAW_COIN */
{
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
@@ -2325,6 +2351,74 @@ postgres_get_reserve_history (void *cls,
ret = GNUNET_OK;
PQclear (result);
}
+ /** #TALER_EXCHANGEDB_RO_PAYBACK_COIN */
+ {
+ struct TALER_EXCHANGEDB_Payback *payback;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (reserve_pub),
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "payback_by_reserve",
+ params);
+ if (PGRES_TUPLES_OK != PQresultStatus (result))
+ {
+ QUERY_ERR (result);
+ goto cleanup;
+ }
+ rows = PQntuples (result);
+ while (0 < rows)
+ {
+ payback = GNUNET_new (struct TALER_EXCHANGEDB_Payback);
+ {
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("amount",
+ &payback->value),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &payback->coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+ &payback->coin_blind),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+ &payback->coin_sig),
+ GNUNET_PQ_result_spec_absolute_time ("timestamp",
+ &payback->timestamp),
+ GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+ &payback->denom_pub.rsa_public_key),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result,
+ rs,
+ --rows))
+ {
+ GNUNET_break (0);
+ GNUNET_free (payback);
+ PQclear (result);
+ goto cleanup;
+ }
+ }
+ payback->reserve_pub = *reserve_pub;
+ if (NULL != rh_tail)
+ {
+ rh_tail->next = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
+ rh_tail = rh_tail->next;
+ }
+ else
+ {
+ rh_tail = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
+ rh = rh_tail;
+ }
+ rh_tail->type = TALER_EXCHANGEDB_RO_PAYBACK_COIN;
+ rh_tail->details.payback = payback;
+ } /* end of 'while (0 < rows)' */
+ PQclear (result);
+ }
+
+
+ /** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */
+ /* TODO: #4956 */
+
cleanup:
if (GNUNET_SYSERR == ret)
{
@@ -5453,6 +5547,7 @@ postgres_select_wire_out_above_serial_id (void *cls,
* @param coin_blind blinding key of the coin
* @param amount total amount to be paid back
* @param receiver_account_details who should receive the funds
+ * @parma h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
* @param[out] deadline set to absolute time by when the exchange plans to pay it back
* @return #GNUNET_OK on success,
* #GNUNET_SYSERR on DB errors
@@ -5465,6 +5560,7 @@ postgres_insert_payback_request (void *cls,
const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_DenominationBlindingKeyP *coin_blind,
const struct TALER_Amount *amount,
+ const struct GNUNET_HashCode *h_blind_ev,
struct GNUNET_TIME_Absolute *deadline)
{
PGresult *result;
@@ -5478,6 +5574,7 @@ postgres_insert_payback_request (void *cls,
GNUNET_PQ_query_param_auto_from_type (coin_blind),
TALER_PQ_query_param_amount (amount),
GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_auto_from_type (h_blind_ev),
GNUNET_PQ_query_param_end
};
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 781d4e60d..37040d39a 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -153,14 +153,9 @@ struct TALER_EXCHANGEDB_Payback
{
/**
- * Which coin was paid back?
+ * Public key of the coin that was paid back.
*/
- struct TALER_CoinPublicInfo coin;
-
- /**
- * How much was the coin still worth at this time?
- */
- struct TALER_Amount value;
+ struct TALER_CoinSpendPublicKeyP coin_pub;
/**
* Blinding factor supplied to prove to the exchange that
@@ -179,6 +174,22 @@ struct TALER_EXCHANGEDB_Payback
*/
struct TALER_ReservePublicKeyP reserve_pub;
+ /**
+ * How much was the coin still worth at this time?
+ */
+ struct TALER_Amount value;
+
+ /**
+ * When did the /payback operation happen?
+ */
+ struct GNUNET_TIME_Absolute timestamp;
+
+ /**
+ * Public key representing the denomination of
+ * @e coin_pub.
+ */
+ struct TALER_DenominationPublicKey denom_pub;
+
};
@@ -1944,6 +1955,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param h_blind_ev blinded envelope, as calculated by the exchange
* @param amount total amount to be paid back
* @param receiver_account_details who should receive the funds
+ * @parma h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
* @param[out] deadline set to absolute time by when the exchange plans to pay it back
* @return #GNUNET_OK on success,
* #GNUNET_SYSERR on DB errors
@@ -1956,6 +1968,7 @@ struct TALER_EXCHANGEDB_Plugin
const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_DenominationBlindingKeyP *coin_blind,
const struct TALER_Amount *amount,
+ const struct GNUNET_HashCode *h_blind_ev,
struct GNUNET_TIME_Absolute *deadline);