implement returning /paybacks as part of reserve history (#3887)

This commit is contained in:
Christian Grothoff 2017-04-02 18:02:07 +02:00
parent 94dddbbe82
commit d8542d729a
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 126 additions and 12 deletions

View File

@ -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)
{

View File

@ -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;

View File

@ -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
@ -220,6 +220,8 @@ postgres_drop_tables (void *cls)
"Dropping ALL tables\n");
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS prewire;");
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS payback;");
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS aggregation_tracking;");
SQLEXEC_ (conn,
@ -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
};

View File

@ -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);