implement rest of exchange logic for #3887 (return payback information in reserve and coin histories)

This commit is contained in:
Christian Grothoff 2017-04-03 16:40:31 +02:00
parent 5b867c4b8e
commit 29a2f9b345
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
9 changed files with 185 additions and 70 deletions

View File

@ -94,13 +94,13 @@ verify_payback_signature_ok (const struct TALER_EXCHANGE_PaybackHandle *ph,
struct TALER_ExchangePublicKeyP exchange_pub; struct TALER_ExchangePublicKeyP exchange_pub;
struct TALER_ExchangeSignatureP exchange_sig; struct TALER_ExchangeSignatureP exchange_sig;
struct TALER_Amount amount; struct TALER_Amount amount;
struct GNUNET_TIME_Absolute deadline; struct GNUNET_TIME_Absolute timestamp;
const struct TALER_EXCHANGE_Keys *key_state; const struct TALER_EXCHANGE_Keys *key_state;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub),
TALER_JSON_spec_amount ("amount", &amount), TALER_JSON_spec_amount ("amount", &amount),
GNUNET_JSON_spec_absolute_time ("payback_deadline", &deadline), GNUNET_JSON_spec_absolute_time ("timestamp", &timestamp),
GNUNET_JSON_spec_fixed_auto ("reserve_pub", &pc.reserve_pub), GNUNET_JSON_spec_fixed_auto ("reserve_pub", &pc.reserve_pub),
GNUNET_JSON_spec_end() GNUNET_JSON_spec_end()
}; };
@ -123,7 +123,7 @@ verify_payback_signature_ok (const struct TALER_EXCHANGE_PaybackHandle *ph,
} }
pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK); pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
pc.purpose.size = htonl (sizeof (pc)); pc.purpose.size = htonl (sizeof (pc));
pc.payback_deadline = GNUNET_TIME_absolute_hton (deadline); pc.timestamp = GNUNET_TIME_absolute_hton (timestamp);
TALER_amount_hton (&pc.payback_amount, TALER_amount_hton (&pc.payback_amount,
&amount); &amount);
pc.coin_pub = ph->coin_pub; pc.coin_pub = ph->coin_pub;
@ -140,7 +140,7 @@ verify_payback_signature_ok (const struct TALER_EXCHANGE_PaybackHandle *ph,
MHD_HTTP_OK, MHD_HTTP_OK,
TALER_EC_NONE, TALER_EC_NONE,
&amount, &amount,
deadline, timestamp,
&pc.reserve_pub, &pc.reserve_pub,
json); json);
return GNUNET_OK; return GNUNET_OK;

View File

@ -2335,7 +2335,7 @@ TEH_DB_execute_payback (struct MHD_Connection *connection,
struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReservePublicKeyP reserve_pub;
struct TALER_Amount amount; struct TALER_Amount amount;
struct TALER_Amount spent; struct TALER_Amount spent;
struct GNUNET_TIME_Absolute payback_deadline; struct GNUNET_TIME_Absolute now;
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{ {
@ -2406,6 +2406,8 @@ TEH_DB_execute_payback (struct MHD_Connection *connection,
} }
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl); tl);
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
/* add coin to list of wire transfers for payback */ /* add coin to list of wire transfers for payback */
ret = TEH_plugin->insert_payback_request (TEH_plugin->cls, ret = TEH_plugin->insert_payback_request (TEH_plugin->cls,
@ -2416,7 +2418,7 @@ TEH_DB_execute_payback (struct MHD_Connection *connection,
coin_blind, coin_blind,
&amount, &amount,
h_blind, h_blind,
&payback_deadline); now);
if (GNUNET_SYSERR == ret) if (GNUNET_SYSERR == ret)
{ {
TALER_LOG_WARNING ("Failed to store /payback information in database\n"); TALER_LOG_WARNING ("Failed to store /payback information in database\n");
@ -2432,7 +2434,7 @@ TEH_DB_execute_payback (struct MHD_Connection *connection,
&coin->coin_pub, &coin->coin_pub,
&reserve_pub, &reserve_pub,
&amount, &amount,
payback_deadline); now);
} }

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014, 2015, 2016, 2017 Inria & GNUnet e.V. Copyright (C) 2014-2017 Inria & GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software
@ -554,32 +554,34 @@ compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl)
case TALER_EXCHANGEDB_TT_PAYBACK: case TALER_EXCHANGEDB_TT_PAYBACK:
{ {
const struct TALER_EXCHANGEDB_Payback *payback = pos->details.payback; const struct TALER_EXCHANGEDB_Payback *payback = pos->details.payback;
struct TALER_PaybackRequestPS pr; struct TALER_PaybackConfirmationPS pc;
struct TALER_ExchangePublicKeyP epub;
struct TALER_ExchangeSignatureP esig;
type = "PAYBACK"; type = "PAYBACK";
value = payback->value; value = payback->value;
pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_PAYBACK); pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
pr.purpose.size = htonl (sizeof (pr)); pc.purpose.size = htonl (sizeof (pc));
pr.coin_pub = payback->coin_pub; pc.timestamp = GNUNET_TIME_absolute_hton (payback->timestamp);
GNUNET_CRYPTO_rsa_public_key_hash (payback->denom_pub.rsa_public_key, TALER_amount_hton (&pc.payback_amount,
&pr.h_denom_pub); &payback->value);
pr.coin_blind = payback->coin_blind; pc.coin_pub = payback->coin_pub;
pc.reserve_pub = payback->reserve_pub;
/* internal sanity check before we hand out a bogus sig... */ TEH_KS_sign (&pc.purpose,
sig = &payback->coin_sig.eddsa_signature; &epub,
if (GNUNET_OK != &esig);
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_PAYBACK, details = GNUNET_JSON_from_data_auto (&pc);
&pr.purpose, GNUNET_assert (0 ==
sig, json_array_append_new (history,
&payback->coin_pub.eddsa_pub)) json_pack ("{s:s, s:o, s:o, s:o, s:o}",
{ "type", type,
GNUNET_break (0); "amount", TALER_JSON_from_amount (&value),
json_decref (history); "exchange_sig", GNUNET_JSON_from_data_auto (&esig),
return NULL; "exchange_pub", GNUNET_JSON_from_data_auto (&epub),
"details", details)));
} }
details = GNUNET_JSON_from_data_auto (&pr); /* do not go to the default handler, we already appended! */
} continue;
break;
default: default:
GNUNET_assert (0); GNUNET_assert (0);
} }
@ -646,6 +648,11 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
int ret; int ret;
const struct TALER_EXCHANGEDB_ReserveHistory *pos; const struct TALER_EXCHANGEDB_ReserveHistory *pos;
struct TALER_WithdrawRequestPS wr; struct TALER_WithdrawRequestPS wr;
const struct TALER_EXCHANGEDB_Payback *payback;
struct TALER_PaybackConfirmationPS pc;
struct TALER_ReserveCloseConfirmationPS rcc;
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
json_history = json_array (); json_history = json_array ();
ret = 0; ret = 0;
@ -654,7 +661,7 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
switch (pos->type) switch (pos->type)
{ {
case TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE: case TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE:
if (0 == ret) if (0 == (1 & ret))
deposit_total = pos->details.bank->amount; deposit_total = pos->details.bank->amount;
else else
if (GNUNET_OK != if (GNUNET_OK !=
@ -665,7 +672,7 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
json_decref (json_history); json_decref (json_history);
return NULL; return NULL;
} }
ret = 1; ret |= 1;
GNUNET_assert (0 == GNUNET_assert (0 ==
json_array_append_new (json_history, json_array_append_new (json_history,
json_pack ("{s:s, s:O, s:O, s:o}", json_pack ("{s:s, s:O, s:O, s:o}",
@ -674,21 +681,9 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
"transfer_details", pos->details.bank->transfer_details, "transfer_details", pos->details.bank->transfer_details,
"amount", TALER_JSON_from_amount (&pos->details.bank->amount)))); "amount", TALER_JSON_from_amount (&pos->details.bank->amount))));
break; break;
case TALER_EXCHANGEDB_RO_WITHDRAW_COIN:
break;
}
}
ret = 0;
for (pos = rh; NULL != pos; pos = pos->next)
{
switch (pos->type)
{
case TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE:
break;
case TALER_EXCHANGEDB_RO_WITHDRAW_COIN: case TALER_EXCHANGEDB_RO_WITHDRAW_COIN:
value = pos->details.withdraw->amount_with_fee; value = pos->details.withdraw->amount_with_fee;
if (0 == ret) if (0 == (2 & ret))
{ {
withdraw_total = value; withdraw_total = value;
} }
@ -703,7 +698,7 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
return NULL; return NULL;
} }
} }
ret = 1; ret |= 2;
wr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); wr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
wr.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS)); wr.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
wr.reserve_pub = pos->details.withdraw->reserve_pub; wr.reserve_pub = pos->details.withdraw->reserve_pub;
@ -720,11 +715,91 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
"type", "WITHDRAW", "type", "WITHDRAW",
"signature", GNUNET_JSON_from_data_auto (&pos->details.withdraw->reserve_sig), "signature", GNUNET_JSON_from_data_auto (&pos->details.withdraw->reserve_sig),
"details", GNUNET_JSON_from_data_auto (&wr), "details", GNUNET_JSON_from_data_auto (&wr),
"amount", TALER_JSON_from_amount (&value))));
break;
case TALER_EXCHANGEDB_RO_PAYBACK_COIN:
payback = pos->details.payback;
if (0 == (1 & ret))
deposit_total = payback->value;
else
if (GNUNET_OK !=
TALER_amount_add (&deposit_total,
&deposit_total,
&payback->value))
{
json_decref (json_history);
return NULL;
}
ret |= 1;
pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
pc.purpose.size = htonl (sizeof (struct TALER_PaybackConfirmationPS));
pc.timestamp = GNUNET_TIME_absolute_hton (payback->timestamp);
TALER_amount_hton (&pc.payback_amount,
&payback->value);
pc.coin_pub = payback->coin_pub;
pc.reserve_pub = payback->reserve_pub;
TEH_KS_sign (&pc.purpose,
&pub,
&sig);
GNUNET_assert (0 ==
json_array_append_new (json_history,
json_pack ("{s:s, s:o, s:o, s:o, s:o}",
"type", "PAYBACK",
"exchange_pub", GNUNET_JSON_from_data_auto (&pub),
"exchange_sig", GNUNET_JSON_from_data_auto (&sig),
"timestamp", GNUNET_JSON_from_time_abs (payback->timestamp),
"amount", TALER_JSON_from_amount (&payback->value))));
break;
case TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK:
value = pos->details.bank->amount;
if (0 == (2 & ret))
{
withdraw_total = value;
}
else
{
if (GNUNET_OK !=
TALER_amount_add (&withdraw_total,
&withdraw_total,
&value))
{
json_decref (json_history);
return NULL;
}
}
ret |= 2;
rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED);
rcc.purpose.size = htonl (sizeof (struct TALER_ReserveCloseConfirmationPS));
rcc.timestamp = GNUNET_TIME_absolute_hton (pos->details.bank->execution_date);
TALER_amount_hton (&rcc.closing_amount,
&value);
rcc.reserve_pub = pos->details.bank->reserve_pub;
TALER_JSON_hash (pos->details.bank->sender_account_details,
&rcc.h_wire);
TEH_KS_sign (&rcc.purpose,
&pub,
&sig);
GNUNET_assert (0 ==
json_array_append_new (json_history,
json_pack ("{s:s, s:o, s:o, s:o, s:o}",
"type", "CLOSING",
"exchange_pub", GNUNET_JSON_from_data_auto (&pub),
"exchange_sig", GNUNET_JSON_from_data_auto (&sig),
"details", GNUNET_JSON_from_data_auto (&rcc),
"amount", TALER_JSON_from_amount (&value)))); "amount", TALER_JSON_from_amount (&value))));
break; break;
} }
} }
if (0 == ret) if (0 == (1 & ret))
{
GNUNET_break (0);
json_decref (json_history);
return NULL;
}
if (0 == (2 & ret))
{ {
/* did not encounter any withdraw operations, set to zero */ /* did not encounter any withdraw operations, set to zero */
TALER_amount_get_zero (deposit_total.currency, TALER_amount_get_zero (deposit_total.currency,
@ -1352,7 +1427,7 @@ TEH_RESPONSE_reply_payback_unknown (struct MHD_Connection *connection,
* @param coin_pub coin for which we are processing the payback request * @param coin_pub coin for which we are processing the payback request
* @param reserve_pub public key of the reserve that will receive the payback * @param reserve_pub public key of the reserve that will receive the payback
* @param amount the amount we will wire back * @param amount the amount we will wire back
* @param payback_deadline deadline by which the exchange promises to pay * @param timestamp when did the exchange receive the /payback request
* @return MHD result code * @return MHD result code
*/ */
int int
@ -1360,7 +1435,7 @@ TEH_RESPONSE_reply_payback_success (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
struct GNUNET_TIME_Absolute payback_deadline) struct GNUNET_TIME_Absolute timestamp)
{ {
struct TALER_PaybackConfirmationPS pc; struct TALER_PaybackConfirmationPS pc;
struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangePublicKeyP pub;
@ -1368,7 +1443,7 @@ TEH_RESPONSE_reply_payback_success (struct MHD_Connection *connection,
pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK); pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
pc.purpose.size = htonl (sizeof (struct TALER_PaybackConfirmationPS)); pc.purpose.size = htonl (sizeof (struct TALER_PaybackConfirmationPS));
pc.payback_deadline = GNUNET_TIME_absolute_hton (payback_deadline); pc.timestamp = GNUNET_TIME_absolute_hton (timestamp);
TALER_amount_hton (&pc.payback_amount, TALER_amount_hton (&pc.payback_amount,
amount); amount);
pc.coin_pub = *coin_pub; pc.coin_pub = *coin_pub;
@ -1380,7 +1455,7 @@ TEH_RESPONSE_reply_payback_success (struct MHD_Connection *connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:o, s:o, s:o, s:o, s:o}", "{s:o, s:o, s:o, s:o, s:o}",
"reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub), "reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub),
"payback_deadline", GNUNET_JSON_from_time_abs (payback_deadline), "timestamp", GNUNET_JSON_from_time_abs (timestamp),
"amount", TALER_JSON_from_amount (amount), "amount", TALER_JSON_from_amount (amount),
"exchange_sig", GNUNET_JSON_from_data_auto (&sig), "exchange_sig", GNUNET_JSON_from_data_auto (&sig),
"exchange_pub", GNUNET_JSON_from_data_auto (&pub)); "exchange_pub", GNUNET_JSON_from_data_auto (&pub));

View File

@ -579,7 +579,7 @@ TEH_RESPONSE_reply_payback_unknown (struct MHD_Connection *connection,
* @param coin_pub coin for which we are processing the payback request * @param coin_pub coin for which we are processing the payback request
* @param reserve_pub public key of the reserve that will receive the payback * @param reserve_pub public key of the reserve that will receive the payback
* @param amount the amount we will wire back * @param amount the amount we will wire back
* @param payback_deadline deadline by which the exchange promises to pay * @param timestamp when did the exchange receive the /payback request
* @return MHD result code * @return MHD result code
*/ */
int int
@ -587,7 +587,7 @@ TEH_RESPONSE_reply_payback_success (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
struct GNUNET_TIME_Absolute payback_deadline); struct GNUNET_TIME_Absolute timestamp);
#endif #endif

View File

@ -5629,7 +5629,7 @@ postgres_select_wire_out_above_serial_id (void *cls,
* @param amount total amount to be paid back * @param amount total amount to be paid back
* @param receiver_account_details who should receive the funds * @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) * @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 * @param timestamp current time (rounded)
* @return #GNUNET_OK on success, * @return #GNUNET_OK on success,
* #GNUNET_SYSERR on DB errors * #GNUNET_SYSERR on DB errors
*/ */
@ -5642,10 +5642,9 @@ postgres_insert_payback_request (void *cls,
const struct TALER_DenominationBlindingKeyP *coin_blind, const struct TALER_DenominationBlindingKeyP *coin_blind,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
const struct GNUNET_HashCode *h_blind_ev, const struct GNUNET_HashCode *h_blind_ev,
struct GNUNET_TIME_Absolute *deadline) struct GNUNET_TIME_Absolute timestamp)
{ {
PGresult *result; PGresult *result;
struct GNUNET_TIME_Absolute now;
struct GNUNET_TIME_Absolute expiry; struct GNUNET_TIME_Absolute expiry;
struct TALER_EXCHANGEDB_Reserve reserve; struct TALER_EXCHANGEDB_Reserve reserve;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
@ -5654,12 +5653,11 @@ postgres_insert_payback_request (void *cls,
GNUNET_PQ_query_param_auto_from_type (coin_sig), GNUNET_PQ_query_param_auto_from_type (coin_sig),
GNUNET_PQ_query_param_auto_from_type (coin_blind), GNUNET_PQ_query_param_auto_from_type (coin_blind),
TALER_PQ_query_param_amount (amount), TALER_PQ_query_param_amount (amount),
GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_absolute_time (&timestamp),
GNUNET_PQ_query_param_auto_from_type (h_blind_ev), GNUNET_PQ_query_param_auto_from_type (h_blind_ev),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
now = GNUNET_TIME_absolute_get ();
result = GNUNET_PQ_exec_prepared (session->conn, result = GNUNET_PQ_exec_prepared (session->conn,
"payback_insert", "payback_insert",
params); params);
@ -5689,7 +5687,7 @@ postgres_insert_payback_request (void *cls,
GNUNET_break (0); GNUNET_break (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
expiry = GNUNET_TIME_absolute_add (now, expiry = GNUNET_TIME_absolute_add (timestamp,
TALER_IDLE_RESERVE_EXPIRATION_TIME); TALER_IDLE_RESERVE_EXPIRATION_TIME);
reserve.expiry = GNUNET_TIME_absolute_max (expiry, reserve.expiry = GNUNET_TIME_absolute_max (expiry,
reserve.expiry); reserve.expiry);
@ -5700,7 +5698,6 @@ postgres_insert_payback_request (void *cls,
GNUNET_break (0); GNUNET_break (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
*deadline = reserve.expiry;
return GNUNET_OK; return GNUNET_OK;
} }

View File

@ -1511,6 +1511,7 @@ run (void *cls)
RND_BLK (&coin_sig); RND_BLK (&coin_sig);
RND_BLK (&coin_blind); RND_BLK (&coin_blind);
deadline = GNUNET_TIME_absolute_get ();
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
plugin->insert_payback_request (plugin->cls, plugin->insert_payback_request (plugin->cls,
session, session,
@ -1520,7 +1521,7 @@ run (void *cls)
&coin_blind, &coin_blind,
&value, &value,
&cbc.h_coin_envelope, &cbc.h_coin_envelope,
&deadline)); deadline));
result = 7; result = 7;
rh = plugin->get_reserve_history (plugin->cls, rh = plugin->get_reserve_history (plugin->cls,
@ -1719,7 +1720,7 @@ run (void *cls)
&coin_blind, &coin_blind,
&value, &value,
&cbc.h_coin_envelope, &cbc.h_coin_envelope,
&deadline)); deadline));
auditor_row_cnt = 0; auditor_row_cnt = 0;
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=

View File

@ -1344,7 +1344,7 @@ struct TALER_EXCHANGE_PaybackHandle;
* 0 if the exchange's reply is bogus (fails to follow the protocol) * 0 if the exchange's reply is bogus (fails to follow the protocol)
* @param ec taler-specific error code, #TALER_EC_NONE on success * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param amount amount the exchange will wire back for this coin * @param amount amount the exchange will wire back for this coin
* @param deadline by when will the exchange wire the funds? * @param timestamp what time did the exchange receive the /payback request
* @param reserve_pub public key of the reserve receiving the payback * @param reserve_pub public key of the reserve receiving the payback
* @param full_response full response from the exchange (for logging, in case of errors) * @param full_response full response from the exchange (for logging, in case of errors)
*/ */
@ -1353,7 +1353,7 @@ typedef void
unsigned int http_status, unsigned int http_status,
enum TALER_ErrorCode ec, enum TALER_ErrorCode ec,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
struct GNUNET_TIME_Absolute deadline, struct GNUNET_TIME_Absolute timestamp,
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const json_t *full_response); const json_t *full_response);

View File

@ -1956,7 +1956,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param amount total amount to be paid back * @param amount total amount to be paid back
* @param receiver_account_details who should receive the funds * @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) * @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 * @param now timestamp to store
* @return #GNUNET_OK on success, * @return #GNUNET_OK on success,
* #GNUNET_SYSERR on DB errors * #GNUNET_SYSERR on DB errors
*/ */
@ -1969,7 +1969,7 @@ struct TALER_EXCHANGEDB_Plugin
const struct TALER_DenominationBlindingKeyP *coin_blind, const struct TALER_DenominationBlindingKeyP *coin_blind,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
const struct GNUNET_HashCode *h_blind_ev, const struct GNUNET_HashCode *h_blind_ev,
struct GNUNET_TIME_Absolute *deadline); struct GNUNET_TIME_Absolute timestamp);
/** /**

View File

@ -131,6 +131,11 @@
*/ */
#define TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK 1039 #define TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK 1039
/**
* Signature where the Exchange confirms it closed a reserve.
*/
#define TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED 1040
/*********************/ /*********************/
/* Wallet signatures */ /* Wallet signatures */
@ -1175,10 +1180,11 @@ struct TALER_PaybackConfirmationPS
struct GNUNET_CRYPTO_EccSignaturePurpose purpose; struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/** /**
* By what deadline does the exchange promise to initiate * When did the exchange receive the payback request?
* the wire transfer? * Indirectly determines when the wire transfer is (likely)
* to happen.
*/ */
struct GNUNET_TIME_AbsoluteNBO payback_deadline; struct GNUNET_TIME_AbsoluteNBO timestamp;
/** /**
* How much of the coin's value will the exchange transfer? * How much of the coin's value will the exchange transfer?
@ -1198,6 +1204,40 @@ struct TALER_PaybackConfirmationPS
}; };
/**
* Response by which the exchange affirms that it has
* closed a reserve and send back the funds.
*/
struct TALER_ReserveCloseConfirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When did the exchange initiate the wire transfer.
*/
struct GNUNET_TIME_AbsoluteNBO timestamp;
/**
* How much did the exchange send?
*/
struct TALER_AmountNBO closing_amount;
/**
* Public key of the reserve that received the payback.
*/
struct TALER_ReservePublicKeyP reserve_pub;
/**
* Hash of the receiver's bank account.
*/
struct GNUNET_HashCode h_wire;
};
GNUNET_NETWORK_STRUCT_END GNUNET_NETWORK_STRUCT_END
#endif #endif