aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-07-21 20:15:11 +0200
committerChristian Grothoff <christian@grothoff.org>2019-07-21 20:15:11 +0200
commit721c1ee73e1ee65ab9a246456ef4acce3e2338f5 (patch)
tree0529603b8b6bf2ac3043af3d64e7cd0705f138d9 /src
parentbafe0c772a7b93934ff2d3797dcd4d9993764d16 (diff)
extending postgres plugin with functions required to store payback data on refreshed coins for #5777
Diffstat (limited to 'src')
-rw-r--r--src/exchangedb/plugin_exchangedb_common.c6
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c725
-rw-r--r--src/include/taler_exchangedb_plugin.h177
3 files changed, 743 insertions, 165 deletions
diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c
index fd2620c7b..4a72f5460 100644
--- a/src/exchangedb/plugin_exchangedb_common.c
+++ b/src/exchangedb/plugin_exchangedb_common.c
@@ -99,6 +99,9 @@ common_free_coin_transaction_list (void *cls,
GNUNET_CRYPTO_rsa_signature_free (list->details.melt->session.coin.denom_sig.rsa_signature);
GNUNET_free (list->details.melt);
break;
+ case TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK:
+ GNUNET_free (list->details.old_coin_payback);
+ break;
case TALER_EXCHANGEDB_TT_REFUND:
if (NULL != list->details.refund->coin.denom_sig.rsa_signature)
GNUNET_CRYPTO_rsa_signature_free (list->details.refund->coin.denom_sig.rsa_signature);
@@ -109,6 +112,9 @@ common_free_coin_transaction_list (void *cls,
GNUNET_CRYPTO_rsa_signature_free (list->details.payback->coin.denom_sig.rsa_signature);
GNUNET_free (list->details.payback);
break;
+ case TALER_EXCHANGEDB_TT_PAYBACK_REFRESH:
+ GNUNET_free (list->details.payback_refresh);
+ break;
}
GNUNET_free (list);
list = next;
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index b4c2d49d8..cbf4c0938 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -115,6 +115,7 @@ postgres_drop_tables (void *cls)
GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS kyc_merchants CASCADE;"),
GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS prewire CASCADE;"),
GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS payback CASCADE;"),
+ GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS payback_refresh CASCADE;"),
GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS aggregation_tracking CASCADE;"),
GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS wire_out CASCADE;"),
GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS wire_fee CASCADE;"),
@@ -317,7 +318,7 @@ postgres_create_tables (void *cls)
",newcoin_index INT4 NOT NULL"
",link_sig BYTEA NOT NULL CHECK(LENGTH(link_sig)=64)"
",denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE"
- ",coin_ev BYTEA NOT NULL"
+ ",coin_ev BYTEA UNIQUE NOT NULL"
",ev_sig BYTEA NOT NULL"
",PRIMARY KEY (rc, newcoin_index)"
");"),
@@ -449,6 +450,27 @@ postgres_create_tables (void *cls)
GNUNET_PQ_make_try_execute("CREATE INDEX payback_for_by_reserve "
"ON payback(coin_pub,denom_pub_hash,h_blind_ev);"),
+ /* Table for /payback-refresh information */
+ GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS payback_refresh "
+ "(payback_refresh_uuid BIGSERIAL UNIQUE"
+ ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)" /* do NOT CASCADE on delete, we may keep the coin alive! */
+ ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)"
+ ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)"
+ ",amount_val INT8 NOT NULL"
+ ",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 refresh_revealed_coins (coin_ev) ON DELETE CASCADE"
+ ");"),
+ GNUNET_PQ_make_try_execute("CREATE INDEX payback_refresh_by_coin_index "
+ "ON payback_refresh(coin_pub);"),
+ GNUNET_PQ_make_try_execute("CREATE INDEX payback_refresh_by_h_blind_ev "
+ "ON payback_refresh(h_blind_ev);"),
+ GNUNET_PQ_make_try_execute("CREATE INDEX payback_refresh_by_reserve_index "
+ "ON payback_refresh(reserve_pub);"),
+ GNUNET_PQ_make_try_execute("CREATE INDEX payback_refresh_for_by_reserve "
+ "ON payback_refresh(coin_pub,denom_pub_hash,h_blind_ev);"),
+
/* This table contains the pre-commit data for
wire transfers the exchange is about to execute. */
GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS prewire "
@@ -658,14 +680,14 @@ postgres_prepare (PGconn *db_conn)
") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);",
10),
- /* Used in #postgres_reserves_update() when the reserve is updated */
+ /* Used in #reserves_update() when the reserve is updated */
GNUNET_PQ_make_prepare ("reserve_update",
"UPDATE reserves"
" SET"
" expiration_date=$1 "
",current_balance_val=$2"
",current_balance_frac=$3"
- ",current_balance_curr=$4"
+ ",current_balance_curr=$4"
" WHERE"
" reserve_pub=$5;",
5),
@@ -1521,6 +1543,21 @@ postgres_prepare (PGconn *db_conn)
") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8);",
8),
+ /* Used in #postgres_insert_payback_request() to store payback-refresh
+ information */
+ GNUNET_PQ_make_prepare ("payback_refresh_insert",
+ "INSERT INTO payback_refresh "
+ "(coin_pub"
+ ",coin_sig"
+ ",coin_blind"
+ ",amount_val"
+ ",amount_frac"
+ ",amount_curr"
+ ",timestamp"
+ ",h_blind_ev"
+ ") VALUES "
+ "($1, $2, $3, $4, $5, $6, $7, $8);",
+ 8),
/* Used in #postgres_select_payback_above_serial_id() to obtain payback transactions */
GNUNET_PQ_make_prepare ("payback_get_incr",
"SELECT"
@@ -1547,6 +1584,35 @@ postgres_prepare (PGconn *db_conn)
" WHERE payback_uuid>=$1"
" ORDER BY payback_uuid ASC;",
1),
+ /* Used in #postgres_select_payback_refresh_above_serial_id() to obtain
+ payback-refresh transactions */
+ GNUNET_PQ_make_prepare ("payback_refresh_get_incr",
+ "SELECT"
+ " payback_refresh_uuid"
+ ",timestamp"
+ ",rc.old_coin_pub"
+ ",coin_pub"
+ ",coin_sig"
+ ",coin_blind"
+ ",h_blind_ev"
+ ",coins.denom_pub_hash"
+ ",denoms.denom_pub"
+ ",coins.denom_sig"
+ ",amount_val"
+ ",amount_frac"
+ ",amount_curr"
+ " FROM payback_refresh"
+ " JOIN refresh_revealed_coins rrc"
+ " ON (rrc.coin_ev = h_blind_ev)"
+ " JOIN refresh_commitments rc"
+ " ON (rrc.rc = rc.rc)"
+ " JOIN known_coins coins"
+ " USING (coin_pub)"
+ " JOIN denominations denoms"
+ " ON (coins.denom_pub_hash = denoms.denom_pub_hash)"
+ " WHERE payback_refresh_uuid>=$1"
+ " ORDER BY payback_refresh_uuid ASC;",
+ 1),
/* Used in #postgres_select_reserve_closed_above_serial_id() to
obtain information about closed reserves */
GNUNET_PQ_make_prepare ("reserves_close_get_incr",
@@ -1587,6 +1653,29 @@ postgres_prepare (PGconn *db_conn)
" WHERE ro.reserve_pub=$1"
" FOR UPDATE;",
1),
+ /* Used in #postgres_get_coin_transactions() to obtain payback transactions
+ affecting old coins of refreshed coins */
+ GNUNET_PQ_make_prepare ("payback_by_old_coin",
+ "SELECT"
+ " pr.coin_pub"
+ ",pr.coin_sig"
+ ",pr.coin_blind"
+ ",pr.amount_val"
+ ",pr.amount_frac"
+ ",pr.amount_curr"
+ ",pr.timestamp"
+ ",coins.denom_pub_hash"
+ ",coins.denom_sig"
+ " FROM refresh_commitments"
+ " JOIN refresh_revealed_coins rrc"
+ " USING (rc)"
+ " JOIN payback_refresh pr"
+ " ON (rrc.coin_ev = pr.h_blind_ev)"
+ " JOIN known_coins coins"
+ " ON (coins.coin_pub = pr.coin_pub)"
+ " WHERE old_coin_pub=$1"
+ " FOR UPDATE;",
+ 1),
/* Used in #postgres_get_reserve_history() */
GNUNET_PQ_make_prepare ("close_by_reserve",
"SELECT"
@@ -1616,8 +1705,8 @@ postgres_prepare (PGconn *db_conn)
" WHERE expiration_date<=$1"
" AND (current_balance_val != 0 "
" OR current_balance_frac != 0)"
- " ORDER BY expiration_date ASC"
- " LIMIT 1;",
+ " ORDER BY expiration_date ASC"
+ " LIMIT 1;",
1),
/* Used in #postgres_get_coin_transactions() to obtain payback transactions
for a coin */
@@ -1637,7 +1726,31 @@ postgres_prepare (PGconn *db_conn)
" USING (coin_pub)"
" JOIN reserves_out ro"
" USING (h_blind_ev)"
- " WHERE payback.coin_pub=$1;",
+ " WHERE payback.coin_pub=$1"
+ " FOR UPDATE;",
+ 1),
+ /* Used in #postgres_get_coin_transactions() to obtain payback transactions
+ for a refreshed coin */
+ GNUNET_PQ_make_prepare ("payback_by_refreshed_coin",
+ "SELECT"
+ " rc.old_coin_pub"
+ ",coin_sig"
+ ",coin_blind"
+ ",amount_val"
+ ",amount_frac"
+ ",amount_curr"
+ ",timestamp"
+ ",coins.denom_pub_hash"
+ ",coins.denom_sig"
+ " FROM payback_refresh"
+ " JOIN refresh_revealed_coins rrc"
+ " ON (rrc.coin_ev = h_blind_ev)"
+ " JOIN refresh_commitments rc"
+ " ON (rrc.rc = rc.rc)"
+ " JOIN known_coins coins"
+ " USING (coin_pub)"
+ " WHERE coin_pub=$1"
+ " FOR UPDATE;",
1),
/* Used in #postgres_get_reserve_by_h_blind() */
GNUNET_PQ_make_prepare ("reserve_by_h_blind",
@@ -2181,8 +2294,8 @@ reserves_update (void *cls,
};
return GNUNET_PQ_eval_prepared_non_select (session->conn,
- "reserve_update",
- params);
+ "reserve_update",
+ params);
}
@@ -2334,8 +2447,8 @@ postgres_reserves_in_insert (void *cls,
updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry,
reserve.expiry);
return reserves_update (cls,
- session,
- &updated_reserve);
+ session,
+ &updated_reserve);
}
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
@@ -2504,8 +2617,8 @@ postgres_insert_withdraw_info (void *cls,
reserve.expiry = GNUNET_TIME_absolute_max (expiry,
reserve.expiry);
qs = reserves_update (cls,
- session,
- &reserve);
+ session,
+ &reserve);
GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
@@ -4253,8 +4366,8 @@ struct CoinHistoryContext
*/
static void
add_coin_deposit (void *cls,
- PGresult *result,
- unsigned int num_results)
+ PGresult *result,
+ unsigned int num_results)
{
struct CoinHistoryContext *chc = cls;
@@ -4267,38 +4380,38 @@ add_coin_deposit (void *cls,
deposit = GNUNET_new (struct TALER_EXCHANGEDB_Deposit);
{
struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_result_spec_amount ("amount_with_fee",
- &deposit->amount_with_fee),
- TALER_PQ_result_spec_amount ("fee_deposit",
- &deposit->deposit_fee),
- TALER_PQ_result_spec_absolute_time ("timestamp",
- &deposit->timestamp),
- TALER_PQ_result_spec_absolute_time ("refund_deadline",
- &deposit->refund_deadline),
- TALER_PQ_result_spec_absolute_time ("wire_deadline",
- &deposit->wire_deadline),
- GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
- &deposit->merchant_pub),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- &deposit->h_contract_terms),
- GNUNET_PQ_result_spec_auto_from_type ("h_wire",
- &deposit->h_wire),
- TALER_PQ_result_spec_json ("wire",
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &deposit->amount_with_fee),
+ TALER_PQ_result_spec_amount ("fee_deposit",
+ &deposit->deposit_fee),
+ TALER_PQ_result_spec_absolute_time ("timestamp",
+ &deposit->timestamp),
+ TALER_PQ_result_spec_absolute_time ("refund_deadline",
+ &deposit->refund_deadline),
+ TALER_PQ_result_spec_absolute_time ("wire_deadline",
+ &deposit->wire_deadline),
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+ &deposit->merchant_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+ &deposit->h_contract_terms),
+ GNUNET_PQ_result_spec_auto_from_type ("h_wire",
+ &deposit->h_wire),
+ TALER_PQ_result_spec_json ("wire",
&deposit->receiver_wire_account),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &deposit->csig),
- GNUNET_PQ_result_spec_end
+ GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+ &deposit->csig),
+ GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
{
- GNUNET_break (0);
- GNUNET_free (deposit);
- chc->status = GNUNET_DB_STATUS_HARD_ERROR;
- return;
+ GNUNET_break (0);
+ GNUNET_free (deposit);
+ chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
}
deposit->coin.coin_pub = *chc->coin_pub;
}
@@ -4332,8 +4445,8 @@ add_coin_deposit (void *cls,
*/
static void
add_coin_melt (void *cls,
- PGresult *result,
- unsigned int num_results)
+ PGresult *result,
+ unsigned int num_results)
{
struct CoinHistoryContext *chc = cls;
@@ -4346,27 +4459,27 @@ add_coin_melt (void *cls,
melt = GNUNET_new (struct TALER_EXCHANGEDB_RefreshMelt);
{
struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("rc",
- &melt->session.rc),
- /* oldcoin_index not needed */
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
- &melt->session.coin_sig),
- TALER_PQ_result_spec_amount ("amount_with_fee",
- &melt->session.amount_with_fee),
- TALER_PQ_result_spec_amount ("fee_refresh",
- &melt->melt_fee),
- GNUNET_PQ_result_spec_end
+ GNUNET_PQ_result_spec_auto_from_type ("rc",
+ &melt->session.rc),
+ /* oldcoin_index not needed */
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
+ &melt->session.coin_sig),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &melt->session.amount_with_fee),
+ TALER_PQ_result_spec_amount ("fee_refresh",
+ &melt->melt_fee),
+ GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
{
- GNUNET_break (0);
- GNUNET_free (melt);
- chc->status = GNUNET_DB_STATUS_HARD_ERROR;
- return;
+ GNUNET_break (0);
+ GNUNET_free (melt);
+ chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
}
melt->session.coin.coin_pub = *chc->coin_pub;
}
@@ -4401,8 +4514,8 @@ add_coin_melt (void *cls,
*/
static void
add_coin_refund (void *cls,
- PGresult *result,
- unsigned int num_results)
+ PGresult *result,
+ unsigned int num_results)
{
struct CoinHistoryContext *chc = cls;
@@ -4415,30 +4528,30 @@ add_coin_refund (void *cls,
refund = GNUNET_new (struct TALER_EXCHANGEDB_Refund);
{
struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
- &refund->merchant_pub),
- GNUNET_PQ_result_spec_auto_from_type ("merchant_sig",
- &refund->merchant_sig),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- &refund->h_contract_terms),
- GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
- &refund->rtransaction_id),
- TALER_PQ_result_spec_amount ("amount_with_fee",
- &refund->refund_amount),
- TALER_PQ_result_spec_amount ("fee_refund",
- &refund->refund_fee),
- GNUNET_PQ_result_spec_end
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+ &refund->merchant_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_sig",
+ &refund->merchant_sig),
+ GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+ &refund->h_contract_terms),
+ GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
+ &refund->rtransaction_id),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &refund->refund_amount),
+ TALER_PQ_result_spec_amount ("fee_refund",
+ &refund->refund_fee),
+ GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
{
- GNUNET_break (0);
- GNUNET_free (refund);
- chc->status = GNUNET_DB_STATUS_HARD_ERROR;
- return;
+ GNUNET_break (0);
+ GNUNET_free (refund);
+ chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
}
refund->coin.coin_pub = *chc->coin_pub;
}
@@ -4471,9 +4584,70 @@ add_coin_refund (void *cls,
* @param num_result the number of results in @a result
*/
static void
+add_old_coin_payback (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct CoinHistoryContext *chc = cls;
+
+ for (unsigned int i=0;i<num_results;i++)
+ {
+ struct TALER_EXCHANGEDB_PaybackRefresh *payback;
+ struct TALER_EXCHANGEDB_TransactionList *tl;
+
+ payback = GNUNET_new (struct TALER_EXCHANGEDB_PaybackRefresh);
+ {
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &payback->coin.coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+ &payback->coin_sig),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+ &payback->coin_blind),
+ TALER_PQ_result_spec_amount ("amount",
+ &payback->value),
+ TALER_PQ_result_spec_absolute_time ("timestamp",
+ &payback->timestamp),
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+ &payback->coin.denom_pub_hash),
+ GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+ &payback->coin.denom_sig.rsa_signature),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
+ {
+ GNUNET_break (0);
+ GNUNET_free (payback);
+ chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
+ }
+ payback->old_coin_pub = *chc->coin_pub;
+ }
+ tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
+ tl->next = chc->head;
+ tl->type = TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK;
+ tl->details.old_coin_payback = payback;
+ chc->head = tl;
+ }
+}
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct CoinHistoryContext`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
add_coin_payback (void *cls,
- PGresult *result,
- unsigned int num_results)
+ PGresult *result,
+ unsigned int num_results)
{
struct CoinHistoryContext *chc = cls;
@@ -4485,32 +4659,32 @@ add_coin_payback (void *cls,
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 ("reserve_pub",
- &payback->reserve_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),
- TALER_PQ_result_spec_absolute_time ("timestamp",
- &payback->timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &payback->coin.denom_pub_hash),
- GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
- &payback->coin.denom_sig.rsa_signature),
- GNUNET_PQ_result_spec_end
+ TALER_PQ_result_spec_amount ("amount",
+ &payback->value),
+ GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+ &payback->reserve_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),
+ TALER_PQ_result_spec_absolute_time ("timestamp",
+ &payback->timestamp),
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+ &payback->coin.denom_pub_hash),
+ GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+ &payback->coin.denom_sig.rsa_signature),
+ GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
{
- GNUNET_break (0);
- GNUNET_free (payback);
- chc->status = GNUNET_DB_STATUS_HARD_ERROR;
- return;
+ GNUNET_break (0);
+ GNUNET_free (payback);
+ chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
}
payback->coin.coin_pub = *chc->coin_pub;
}
@@ -4524,6 +4698,67 @@ add_coin_payback (void *cls,
/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct CoinHistoryContext`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
+add_coin_payback_refresh (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct CoinHistoryContext *chc = cls;
+
+ for (unsigned int i=0;i<num_results;i++)
+ {
+ struct TALER_EXCHANGEDB_PaybackRefresh *payback;
+ struct TALER_EXCHANGEDB_TransactionList *tl;
+
+ payback = GNUNET_new (struct TALER_EXCHANGEDB_PaybackRefresh);
+ {
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
+ &payback->old_coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+ &payback->coin_sig),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+ &payback->coin_blind),
+ TALER_PQ_result_spec_amount ("amount",
+ &payback->value),
+ TALER_PQ_result_spec_absolute_time ("timestamp",
+ &payback->timestamp),
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+ &payback->coin.denom_pub_hash),
+ GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+ &payback->coin.denom_sig.rsa_signature),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
+ {
+ GNUNET_break (0);
+ GNUNET_free (payback);
+ chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+ return;
+ }
+ payback->coin.coin_pub = *chc->coin_pub;
+ }
+ tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
+ tl->next = chc->head;
+ tl->type = TALER_EXCHANGEDB_TT_PAYBACK_REFRESH;
+ tl->details.payback_refresh = payback;
+ chc->head = tl;
+ }
+}
+
+
+/**
* Work we need to do.
*/
struct Work
@@ -4541,8 +4776,8 @@ struct Work
/**
- * Compile a list of all (historic) transactions performed
- * with the given coin (/refresh/melt, /deposit and /refund operations).
+ * Compile a list of all (historic) transactions performed with the given coin
+ * (/refresh/melt, /deposit, /refund and /payback operations).
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
* @param session database connection
@@ -4555,7 +4790,7 @@ postgres_get_coin_transactions (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
int include_payback,
- struct TALER_EXCHANGEDB_TransactionList **tlp)
+ struct TALER_EXCHANGEDB_TransactionList **tlp)
{
static const struct Work work_op[] = {
/** #TALER_EXCHANGEDB_TT_DEPOSIT */
@@ -4567,6 +4802,9 @@ postgres_get_coin_transactions (void *cls,
/** #TALER_EXCHANGEDB_TT_REFUND */
{ "get_refunds_by_coin",
&add_coin_refund },
+ /** #TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK */
+ { "payback_by_old_coin",
+ &add_old_coin_payback },
{ NULL, NULL }
};
static const struct Work work_wp[] = {
@@ -4579,9 +4817,15 @@ postgres_get_coin_transactions (void *cls,
/** #TALER_EXCHANGEDB_TT_REFUND */
{ "get_refunds_by_coin",
&add_coin_refund },
+ /** #TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK */
+ { "payback_by_old_coin",
+ &add_old_coin_payback },
/** #TALER_EXCHANGEDB_TT_PAYBACK */
{ "payback_by_coin",
&add_coin_payback },
+ /** #TALER_EXCHANGEDB_TT_PAYBACK_REFRESH */
+ { "payback_by_refreshed_coin",
+ &add_coin_payback_refresh },
{ NULL, NULL }
};
struct CoinHistoryContext chc;
@@ -4604,19 +4848,19 @@ postgres_get_coin_transactions (void *cls,
for (unsigned int i=0;NULL != work[i].statement; i++)
{
qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
- work[i].statement,
- params,
- work[i].cb,
- &chc);
+ work[i].statement,
+ params,
+ work[i].cb,
+ &chc);
if ( (0 > qs) ||
(GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != chc.status) )
{
if (NULL != chc.head)
- common_free_coin_transaction_list (cls,
- chc.head);
+ common_free_coin_transaction_list (cls,
+ chc.head);
*tlp = NULL;
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != chc.status)
- qs = chc.status;
+ qs = chc.status;
return qs;
}
}
@@ -4660,8 +4904,8 @@ struct WireTransferResultContext
*/
static void
handle_wt_result (void *cls,
- PGresult *result,
- unsigned int num_results)
+ PGresult *result,
+ unsigned int num_results)
{
struct WireTransferResultContext *ctx = cls;
@@ -5207,8 +5451,8 @@ postgres_insert_reserve_closed (void *cls,
}
GNUNET_break (GNUNET_NO == ret);
return reserves_update (cls,
- session,
- &reserve);
+ session,
+ &reserve);
}
@@ -6369,8 +6613,8 @@ struct PaybackSerialContext
*/
static void
payback_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
+ PGresult *result,
+ unsigned int num_results)
{
struct PaybackSerialContext *psc = cls;
@@ -6422,14 +6666,14 @@ payback_serial_helper_cb (void *cls,
return;
}
ret = psc->cb (psc->cb_cls,
- rowid,
- timestamp,
- &amount,
- &reserve_pub,
- &coin,
+ rowid,
+ timestamp,
+ &amount,
+ &reserve_pub,
+ &coin,
&denom_pub,
- &coin_sig,
- &coin_blind);
+ &coin_sig,
+ &coin_blind);
GNUNET_PQ_cleanup_result (rs);
if (GNUNET_OK != ret)
break;
@@ -6478,6 +6722,147 @@ postgres_select_payback_above_serial_id (void *cls,
/**
+ * Closure for #payback_refresh_serial_helper_cb().
+ */
+struct PaybackRefreshSerialContext
+{
+
+ /**
+ * Callback to call.
+ */
+ TALER_EXCHANGEDB_PaybackRefreshCallback cb;
+
+ /**
+ * Closure for @e cb.
+ */
+ void *cb_cls;
+
+ /**
+ * Status code, set to #GNUNET_SYSERR on hard errors.
+ */
+ int status;
+};
+
+
+/**
+ * Helper function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct PaybackRefreshSerialContext`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
+payback_refresh_serial_helper_cb (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct PaybackRefreshSerialContext *psc = cls;
+
+ for (unsigned int i=0;i<num_results;i++)
+ {
+ uint64_t rowid;
+ struct TALER_CoinSpendPublicKeyP old_coin_pub;
+ struct TALER_CoinPublicInfo coin;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ struct TALER_DenominationBlindingKeyP coin_blind;
+ struct TALER_DenominationPublicKey denom_pub;
+ struct TALER_Amount amount;
+ struct GNUNET_HashCode h_blind_ev;
+ struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("payback_uuid",
+ &rowid),
+ TALER_PQ_result_spec_absolute_time ("timestamp",
+ &timestamp),
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
+ &old_coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &coin.coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+ &coin_sig),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+ &coin_blind),
+ GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
+ &h_blind_ev),
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+ &coin.denom_pub_hash),
+ GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+ &denom_pub.rsa_public_key),
+ GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+ &coin.denom_sig.rsa_signature),
+ TALER_PQ_result_spec_amount ("amount",
+ &amount),
+ GNUNET_PQ_result_spec_end
+ };
+ int ret;
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
+ {
+ GNUNET_break (0);
+ psc->status = GNUNET_SYSERR;
+ return;
+ }
+ ret = psc->cb (psc->cb_cls,
+ rowid,
+ timestamp,
+ &amount,
+ &old_coin_pub,
+ &coin,
+ &denom_pub,
+ &coin_sig,
+ &coin_blind);
+ GNUNET_PQ_cleanup_result (rs);
+ if (GNUNET_OK != ret)
+ break;
+ }
+}
+
+
+/**
+ * Function called to select payback requests the exchange received for
+ * refreshed coins, ordered by serial ID (monotonically increasing).
+ *
+ * @param cls closure
+ * @param session database connection
+ * @param serial_id lowest serial ID to include (select larger or equal)
+ * @param cb function to call for ONE unfinished item
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_select_payback_refresh_above_serial_id (void *cls,
+ struct TALER_EXCHANGEDB_Session *session,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_PaybackRefreshCallback cb,
+ void *cb_cls)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ struct PaybackRefreshSerialContext psc = {
+ .cb = cb,
+ .cb_cls = cb_cls,
+ .status = GNUNET_OK
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+ "payback_refresh_get_incr",
+ params,
+ &payback_refresh_serial_helper_cb,
+ &psc);
+ if (GNUNET_OK != psc.status)
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ return qs;
+}
+
+
+/**
* Closure for #reserve_closed_serial_helper_cb().
*/
struct ReserveClosedSerialContext
@@ -6580,10 +6965,10 @@ reserve_closed_serial_helper_cb (void *cls,
*/
static enum GNUNET_DB_QueryStatus
postgres_select_reserve_closed_above_serial_id (void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- uint64_t serial_id,
- TALER_EXCHANGEDB_ReserveClosedCallback cb,
- void *cb_cls)
+ struct TALER_EXCHANGEDB_Session *session,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_ReserveClosedCallback cb,
+ void *cb_cls)
{
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&serial_id),
@@ -6649,17 +7034,10 @@ postgres_insert_payback_request (void *cls,
};
enum GNUNET_DB_QueryStatus qs;
-#if 0
- /* check if the coin is already known */
- if (0 > (qs = postgres_ensure_coin_known (cls,
- session,
- coin)))
- return qs;
-#endif
/* now store actual payback information */
qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
- "payback_insert",
- params);
+ "payback_insert",
+ params);
if (0 > qs)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -6669,8 +7047,8 @@ postgres_insert_payback_request (void *cls,
/* Update reserve balance */
reserve.pub = *reserve_pub;
qs = postgres_reserve_get (cls,
- session,
- &reserve);
+ session,
+ &reserve);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -6689,8 +7067,8 @@ postgres_insert_payback_request (void *cls,
reserve.expiry = GNUNET_TIME_absolute_max (expiry,
reserve.expiry);
qs = reserves_update (cls,
- session,
- &reserve);
+ session,
+ &reserve);
if (0 >= qs)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -6701,6 +7079,57 @@ postgres_insert_payback_request (void *cls,
/**
+ * Function called to add a request for an emergency payback for a
+ * refreshed coin. The funds are to be added back to the original coin
+ * (which is implied via @a h_blind_ev, see the prepared statement
+ * "payback_by_old_coin" used in #postgres_get_coin_transactions()).
+ *
+ * @param cls closure
+ * @param session database connection
+ * @param coin public information about the refreshed coin
+ * @param coin_sig signature of the coin of type #TALER_SIGNATURE_WALLET_COIN_PAYBACK
+ * @param coin_blind blinding key of the coin
+ * @param h_blind_ev blinded envelope, as calculated by the exchange
+ * @param amount total amount to be paid back
+ * @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
+ * @param timestamp a timestamp to store
+ * @return transaction result status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_insert_payback_refresh_request (void *cls,
+ struct TALER_EXCHANGEDB_Session *session,
+ const struct TALER_CoinPublicInfo *coin,
+ 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 timestamp)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (coin_sig),
+ GNUNET_PQ_query_param_auto_from_type (coin_blind),
+ TALER_PQ_query_param_amount (amount),
+ TALER_PQ_query_param_absolute_time (&timestamp),
+ GNUNET_PQ_query_param_auto_from_type (h_blind_ev),
+ GNUNET_PQ_query_param_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ /* now store actual payback information */
+ qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+ "payback_refresh_insert",
+ params);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ return qs;
+ }
+ return qs;
+}
+
+
+/**
* Obtain information about which reserve a coin was generated
* from given the hash of the blinded coin.
*
@@ -7325,10 +7754,14 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &postgres_select_wire_out_above_serial_id_by_account;
plugin->select_payback_above_serial_id
= &postgres_select_payback_above_serial_id;
+ plugin->select_payback_refresh_above_serial_id
+ = &postgres_select_payback_refresh_above_serial_id;
plugin->select_reserve_closed_above_serial_id
= &postgres_select_reserve_closed_above_serial_id;
plugin->insert_payback_request
= &postgres_insert_payback_request;
+ plugin->insert_payback_refresh_request
+ = &postgres_insert_payback_refresh_request;
plugin->get_reserve_by_h_blind
= &postgres_get_reserve_by_h_blind;
plugin->insert_denomination_revocation
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 49aac827f..8450fb04f 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -234,6 +234,47 @@ struct TALER_EXCHANGEDB_Payback
/**
+ * Information the exchange records about a /payback-refresh request.
+ */
+struct TALER_EXCHANGEDB_PaybackRefresh
+{
+
+ /**
+ * Information about the coin that was paid back.
+ */
+ struct TALER_CoinPublicInfo coin;
+
+ /**
+ * Blinding factor supplied to prove to the exchange that
+ * the coin came from this reserve.
+ */
+ struct TALER_DenominationBlindingKeyP coin_blind;
+
+ /**
+ * Signature of the coin of type
+ * #TALER_SIGNATURE_WALLET_COIN_PAYBACK.
+ */
+ struct TALER_CoinSpendSignatureP coin_sig;
+
+ /**
+ * Public key of the old coin that the refresh'ed coin was paid back to.
+ */
+ struct TALER_CoinSpendPublicKeyP old_coin_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;
+
+};
+
+
+/**
* @brief Types of operations on a reserve.
*/
enum TALER_EXCHANGEDB_ReserveOperation
@@ -572,9 +613,19 @@ enum TALER_EXCHANGEDB_TransactionType {
TALER_EXCHANGEDB_TT_REFUND = 2,
/**
+ * /payback-refresh operation (on the old coin, adding to the old coin's value)
+ */
+ TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK = 3,
+
+ /**
* /payback operation.
*/
- TALER_EXCHANGEDB_TT_PAYBACK = 3
+ TALER_EXCHANGEDB_TT_PAYBACK = 4,
+
+ /**
+ * /payback-refresh operation (on the new coin, eliminating its value)
+ */
+ TALER_EXCHANGEDB_TT_PAYBACK_REFRESH = 5
};
@@ -603,24 +654,42 @@ struct TALER_EXCHANGEDB_TransactionList
/**
* Details if transaction was a /deposit operation.
+ * (#TALER_EXCHANGEDB_TT_DEPOSIT)
*/
struct TALER_EXCHANGEDB_Deposit *deposit;
/**
* Details if transaction was a /refresh/melt operation.
+ * (#TALER_EXCHANGEDB_TT_REFRESH_MELT)
*/
struct TALER_EXCHANGEDB_RefreshMelt *melt;
/**
* Details if transaction was a /refund operation.
+ * (#TALER_EXCHANGEDB_TT_REFUND)
*/
struct TALER_EXCHANGEDB_Refund *refund;
/**
+ * Details if transaction was a /payback-refund operation where
+ * this coin was the OLD coin.
+ * (#TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK).
+ */
+ struct TALER_EXCHANGEDB_PaybackRefresh *old_coin_payback;
+
+ /**
* Details if transaction was a /payback operation.
+ * (#TALER_EXCHANGEDB_TT_PAYBACK)
*/
struct TALER_EXCHANGEDB_Payback *payback;
+ /**
+ * Details if transaction was a /payback-refund operation where
+ * this coin was the REFRESHED coin.
+ * (#TALER_EXCHANGEDB_TT_PAYBACK_REFRESH)
+ */
+ struct TALER_EXCHANGEDB_PaybackRefresh *payback_refresh;
+
} details;
};
@@ -804,7 +873,7 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin
* link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
*/
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
-
+
/**
* Blinded message to be signed (in envelope), with @e coin_env_size bytes.
*/
@@ -1062,6 +1131,35 @@ typedef int
const struct TALER_DenominationBlindingKeyP *coin_blind);
+
+/**
+ * Function called about paybacks on refreshed coins the exchange has to
+ * perform.
+ *
+ * @param cls closure
+ * @param rowid row identifier used to uniquely identify the payback operation
+ * @param timestamp when did we receive the payback request
+ * @param amount how much should be added back to the reserve
+ * @param old_coin_pub original coin that was refreshed to create @a coin
+ * @param coin public information about the coin
+ * @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_PAYBACK
+ * @param coin_blind blinding factor used to blind the coin
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef int
+(*TALER_EXCHANGEDB_PaybackRefreshCallback)(void *cls,
+ uint64_t rowid,
+ struct GNUNET_TIME_Absolute timestamp,
+ const struct TALER_Amount *amount,
+ const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ const struct TALER_CoinPublicInfo *coin,
+ const struct TALER_DenominationPublicKey *denom_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ const struct TALER_DenominationBlindingKeyP *coin_blind);
+
+
+
+
/**
* Function called about reserve closing operations
* the aggregator triggered.
@@ -1463,7 +1561,7 @@ struct TALER_EXCHANGEDB_Plugin
struct TALER_EXCHANGEDB_Session *session,
const struct TALER_CoinPublicInfo *coin);
-
+
/**
* Retrieve information about the given @a coin from the database.
*
@@ -2223,6 +2321,25 @@ struct TALER_EXCHANGEDB_Plugin
/**
+ * Function called to select payback requests the exchange received for
+ * refreshed coins, ordered by serial ID (monotonically increasing).
+ *
+ * @param cls closure
+ * @param session database connection
+ * @param serial_id lowest serial ID to include (select larger or equal)
+ * @param cb function to call for ONE unfinished item
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_payback_refresh_above_serial_id)(void *cls,
+ struct TALER_EXCHANGEDB_Session *session,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_PaybackRefreshCallback cb,
+ void *cb_cls);
+
+
+ /**
* Function called to select reserve close operations the aggregator
* triggered, ordered by serial ID (monotonically increasing).
*
@@ -2235,18 +2352,15 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*select_reserve_closed_above_serial_id)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- uint64_t serial_id,
- TALER_EXCHANGEDB_ReserveClosedCallback cb,
- void *cb_cls);
+ struct TALER_EXCHANGEDB_Session *session,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_ReserveClosedCallback cb,
+ void *cb_cls);
/**
* Function called to add a request for an emergency payback for a
- * coin. The funds are to be added back to the reserve. The
- * function should return the @a deadline by which the exchange will
- * trigger a wire transfer back to the customer's account for the
- * reserve.
+ * coin. The funds are to be added back to the reserve.
*
* @param cls closure
* @param session database connection
@@ -2256,9 +2370,8 @@ struct TALER_EXCHANGEDB_Plugin
* @param coin_blind blinding key of the coin
* @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
* @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
- * @param now timestamp to store
+ * @param timestamp the timestamp to store
* @return transaction result status
*/
enum GNUNET_DB_QueryStatus
@@ -2274,6 +2387,32 @@ struct TALER_EXCHANGEDB_Plugin
/**
+ * Function called to add a request for an emergency payback for a
+ * refreshed coin. The funds are to be added back to the original coin.
+ *
+ * @param cls closure
+ * @param session database connection
+ * @param coin public information about the refreshed coin
+ * @param coin_sig signature of the coin of type #TALER_SIGNATURE_WALLET_COIN_PAYBACK
+ * @param coin_blind blinding key of the coin
+ * @param h_blind_ev blinded envelope, as calculated by the exchange
+ * @param amount total amount to be paid back
+ * @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
+ * @param timestamp a timestamp to store
+ * @return transaction result status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_payback_refresh_request)(void *cls,
+ struct TALER_EXCHANGEDB_Session *session,
+ const struct TALER_CoinPublicInfo *coin,
+ 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 timestamp);
+
+
+ /**
* Obtain information about which reserve a coin was generated
* from given the hash of the blinded coin.
*
@@ -2323,7 +2462,7 @@ struct TALER_EXCHANGEDB_Plugin
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *denom_pub_hash,
struct TALER_MasterSignatureP *master_sig,
- uint64_t *rowid);
+ uint64_t *rowid);
/**
@@ -2341,11 +2480,11 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*select_deposits_missing_wire)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- struct GNUNET_TIME_Absolute start_date,
- struct GNUNET_TIME_Absolute end_date,
- TALER_EXCHANGEDB_WireMissingCallback cb,
- void *cb_cls);
+ struct TALER_EXCHANGEDB_Session *session,
+ struct GNUNET_TIME_Absolute start_date,
+ struct GNUNET_TIME_Absolute end_date,
+ TALER_EXCHANGEDB_WireMissingCallback cb,
+ void *cb_cls);
/**
* Insert a merchant into the KYC monitor table, namely it