address #5010 for /payback
This commit is contained in:
parent
92e6744ac0
commit
51ee20102f
@ -1622,147 +1622,4 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute a "/payback". The validity of the coin and signature have
|
||||
* already been checked. The database must now check that the coin is
|
||||
* not (double) spent, and execute the transaction (record details,
|
||||
* generate success or failure response).
|
||||
*
|
||||
* @param connection the MHD connection to handle
|
||||
* @param coin information about the coin
|
||||
* @param value how much are coins of the @a coin's denomination worth?
|
||||
* @param h_blind blinded coin to use for the lookup
|
||||
* @param coin_blind blinding factor used (for later verification by the auditor)
|
||||
* @param coin_sig signature of the coin (to be stored)
|
||||
* @return MHD result code
|
||||
*/
|
||||
int
|
||||
TEH_DB_execute_payback (struct MHD_Connection *connection,
|
||||
const struct TALER_CoinPublicInfo *coin,
|
||||
const struct TALER_Amount *value,
|
||||
const struct GNUNET_HashCode *h_blind,
|
||||
const struct TALER_DenominationBlindingKeyP *coin_blind,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||
{
|
||||
int ret;
|
||||
struct TALER_EXCHANGEDB_Session *session;
|
||||
struct TALER_EXCHANGEDB_TransactionList *tl;
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
struct TALER_Amount amount;
|
||||
struct TALER_Amount spent;
|
||||
struct GNUNET_TIME_Absolute now;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_DB_SETUP_FAILED);
|
||||
}
|
||||
|
||||
START_TRANSACTION (session, connection);
|
||||
|
||||
/* Check whether a payback is allowed, and if so, to which
|
||||
reserve / account the money should go */
|
||||
ret = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
|
||||
session,
|
||||
h_blind,
|
||||
&reserve_pub);
|
||||
if (GNUNET_SYSERR == ret)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TEH_plugin->rollback (TEH_plugin->cls,
|
||||
session);
|
||||
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_DB_FETCH_FAILED);
|
||||
}
|
||||
if (GNUNET_NO == ret)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TEH_plugin->rollback (TEH_plugin->cls,
|
||||
session);
|
||||
return TEH_RESPONSE_reply_payback_unknown (connection,
|
||||
TALER_EC_PAYBACK_WITHDRAW_NOT_FOUND);
|
||||
}
|
||||
|
||||
/* Calculate remaining balance. */
|
||||
qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
|
||||
session,
|
||||
&coin->coin_pub,
|
||||
&tl);
|
||||
(void) qs; /* FIXME #5010 */
|
||||
TALER_amount_get_zero (value->currency,
|
||||
&spent);
|
||||
if (GNUNET_OK !=
|
||||
TEH_DB_calculate_transaction_list_totals (tl,
|
||||
&spent,
|
||||
&spent))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TEH_plugin->rollback (TEH_plugin->cls,
|
||||
session);
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_HISTORY_DB_ERROR);
|
||||
}
|
||||
if (GNUNET_SYSERR ==
|
||||
TALER_amount_subtract (&amount,
|
||||
value,
|
||||
&spent))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TEH_plugin->rollback (TEH_plugin->cls,
|
||||
session);
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE);
|
||||
}
|
||||
if ( (0 == amount.fraction) &&
|
||||
(0 == amount.value) )
|
||||
{
|
||||
TEH_plugin->rollback (TEH_plugin->cls,
|
||||
session);
|
||||
ret = TEH_RESPONSE_reply_coin_insufficient_funds (connection,
|
||||
TALER_EC_PAYBACK_COIN_BALANCE_ZERO,
|
||||
tl);
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
return ret;
|
||||
}
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
now = GNUNET_TIME_absolute_get ();
|
||||
(void) GNUNET_TIME_round_abs (&now);
|
||||
|
||||
/* add coin to list of wire transfers for payback */
|
||||
ret = TEH_plugin->insert_payback_request (TEH_plugin->cls,
|
||||
session,
|
||||
&reserve_pub,
|
||||
coin,
|
||||
coin_sig,
|
||||
coin_blind,
|
||||
&amount,
|
||||
h_blind,
|
||||
now);
|
||||
if (GNUNET_SYSERR == ret)
|
||||
{
|
||||
TALER_LOG_WARNING ("Failed to store /payback information in database\n");
|
||||
TEH_plugin->rollback (TEH_plugin->cls,
|
||||
session);
|
||||
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_DB_PUT_FAILED);
|
||||
}
|
||||
|
||||
COMMIT_TRANSACTION(session, connection);
|
||||
|
||||
return TEH_RESPONSE_reply_payback_success (connection,
|
||||
&coin->coin_pub,
|
||||
&reserve_pub,
|
||||
&amount,
|
||||
now);
|
||||
}
|
||||
|
||||
|
||||
/* end of taler-exchange-httpd_db.c */
|
||||
|
@ -34,6 +34,253 @@
|
||||
#include "taler-exchange-httpd_validation.h"
|
||||
|
||||
|
||||
/**
|
||||
* A wallet asked for /payback, but we do not know anything about the
|
||||
* original withdraw operation specified. Generates a 404 reply.
|
||||
*
|
||||
* @param connection connection to the client
|
||||
* @param ec Taler error code
|
||||
* @return MHD result code
|
||||
*/
|
||||
static int
|
||||
reply_payback_unknown (struct MHD_Connection *connection,
|
||||
enum TALER_ErrorCode ec)
|
||||
{
|
||||
return TEH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
"{s:s, s:I}",
|
||||
"error", "blinded coin unknown",
|
||||
"code", (json_int_t) ec);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A wallet asked for /payback, return the successful response.
|
||||
*
|
||||
* @param connection connection to the client
|
||||
* @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 amount the amount we will wire back
|
||||
* @param timestamp when did the exchange receive the /payback request
|
||||
* @return MHD result code
|
||||
*/
|
||||
static int
|
||||
reply_payback_success (struct MHD_Connection *connection,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
const struct TALER_Amount *amount,
|
||||
struct GNUNET_TIME_Absolute timestamp)
|
||||
{
|
||||
struct TALER_PaybackConfirmationPS pc;
|
||||
struct TALER_ExchangePublicKeyP pub;
|
||||
struct TALER_ExchangeSignatureP sig;
|
||||
|
||||
pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
|
||||
pc.purpose.size = htonl (sizeof (struct TALER_PaybackConfirmationPS));
|
||||
pc.timestamp = GNUNET_TIME_absolute_hton (timestamp);
|
||||
TALER_amount_hton (&pc.payback_amount,
|
||||
amount);
|
||||
pc.coin_pub = *coin_pub;
|
||||
pc.reserve_pub = *reserve_pub;
|
||||
TEH_KS_sign (&pc.purpose,
|
||||
&pub,
|
||||
&sig);
|
||||
return TEH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_OK,
|
||||
"{s:o, s:o, s:o, s:o, s:o}",
|
||||
"reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub),
|
||||
"timestamp", GNUNET_JSON_from_time_abs (timestamp),
|
||||
"amount", TALER_JSON_from_amount (amount),
|
||||
"exchange_sig", GNUNET_JSON_from_data_auto (&sig),
|
||||
"exchange_pub", GNUNET_JSON_from_data_auto (&pub));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closure for #payback_transaction.
|
||||
*/
|
||||
struct PaybackContext
|
||||
{
|
||||
/**
|
||||
* Hash of the blinded coin.
|
||||
*/
|
||||
struct GNUNET_HashCode h_blind;
|
||||
|
||||
/**
|
||||
* Full value of the coin.
|
||||
*/
|
||||
struct TALER_Amount value;
|
||||
|
||||
/**
|
||||
* Details about the coin.
|
||||
*/
|
||||
const struct TALER_CoinPublicInfo *coin;
|
||||
|
||||
/**
|
||||
* Key used to blind the coin.
|
||||
*/
|
||||
const struct TALER_DenominationBlindingKeyP *coin_bks;
|
||||
|
||||
/**
|
||||
* Signature of the coin requesting payback.
|
||||
*/
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig;
|
||||
|
||||
/**
|
||||
* Set by #payback_transaction() to the reserve that will
|
||||
* receive the payback.
|
||||
*/
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
|
||||
/**
|
||||
* Set by #payback_transaction() to the amount that will be paid back
|
||||
*/
|
||||
struct TALER_Amount amount;
|
||||
|
||||
/**
|
||||
* Set by #payback_transaction to the timestamp when the payback
|
||||
* was accepted.
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute now;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Execute a "/payback". The validity of the coin and signature have
|
||||
* already been checked. The database must now check that the coin is
|
||||
* not (double) spent, and execute the transaction.
|
||||
*
|
||||
* IF it returns a non-error code, the transaction logic MUST
|
||||
* NOT queue a MHD response. IF it returns an hard error, the
|
||||
* transaction logic MUST queue a MHD response and set @a mhd_ret. IF
|
||||
* it returns the soft error code, the function MAY be called again to
|
||||
* retry and MUST not queue a MHD response.
|
||||
*
|
||||
* @param cls the `struct PaybackContext *`
|
||||
* @param connection MHD request which triggered the transaction
|
||||
* @param session database session to use
|
||||
* @param[out] mhd_ret set to MHD response status for @a connection,
|
||||
* if transaction failed (!)
|
||||
* @return transaction status code
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
payback_transaction (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
int *mhd_ret)
|
||||
{
|
||||
struct PaybackContext *pc = cls;
|
||||
struct TALER_EXCHANGEDB_TransactionList *tl;
|
||||
struct TALER_Amount spent;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
/* Check whether a payback is allowed, and if so, to which
|
||||
reserve / account the money should go */
|
||||
qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
|
||||
session,
|
||||
&pc->h_blind,
|
||||
&pc->reserve_pub);
|
||||
if (0 > qs)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_DB_FETCH_FAILED);
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
*mhd_ret = reply_payback_unknown (connection,
|
||||
TALER_EC_PAYBACK_WITHDRAW_NOT_FOUND);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
|
||||
/* Calculate remaining balance. */
|
||||
qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
|
||||
session,
|
||||
&pc->coin->coin_pub,
|
||||
&tl);
|
||||
if (0 > qs)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_DB_FETCH_FAILED);
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
TALER_amount_get_zero (pc->value.currency,
|
||||
&spent);
|
||||
if (GNUNET_OK !=
|
||||
TEH_DB_calculate_transaction_list_totals (tl,
|
||||
&spent,
|
||||
&spent))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_HISTORY_DB_ERROR);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
if (GNUNET_SYSERR ==
|
||||
TALER_amount_subtract (&pc->amount,
|
||||
&pc->value,
|
||||
&spent))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
if ( (0 == pc->amount.fraction) &&
|
||||
(0 == pc->amount.value) )
|
||||
{
|
||||
TEH_plugin->rollback (TEH_plugin->cls,
|
||||
session);
|
||||
*mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds (connection,
|
||||
TALER_EC_PAYBACK_COIN_BALANCE_ZERO,
|
||||
tl);
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
pc->now = GNUNET_TIME_absolute_get ();
|
||||
(void) GNUNET_TIME_round_abs (&pc->now);
|
||||
|
||||
/* add coin to list of wire transfers for payback */
|
||||
qs = TEH_plugin->insert_payback_request (TEH_plugin->cls,
|
||||
session,
|
||||
&pc->reserve_pub,
|
||||
pc->coin,
|
||||
pc->coin_sig,
|
||||
pc->coin_bks,
|
||||
&pc->amount,
|
||||
&pc->h_blind,
|
||||
pc->now);
|
||||
if (0 > qs)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
{
|
||||
TALER_LOG_WARNING ("Failed to store /payback information in database\n");
|
||||
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_PAYBACK_DB_PUT_FAILED);
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We have parsed the JSON information about the payback request. Do
|
||||
* some basic sanity checks (especially that the signature on the
|
||||
@ -53,14 +300,14 @@ verify_and_execute_payback (struct MHD_Connection *connection,
|
||||
const struct TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||
{
|
||||
struct PaybackContext pc;
|
||||
struct TEH_KS_StateHandle *key_state;
|
||||
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||
struct TALER_PaybackRequestPS pr;
|
||||
struct TALER_Amount value;
|
||||
struct GNUNET_HashCode h_blind;
|
||||
struct GNUNET_HashCode c_hash;
|
||||
char *coin_ev;
|
||||
size_t coin_ev_size;
|
||||
int mhd_ret;
|
||||
|
||||
/* check denomination exists and is in payback mode */
|
||||
key_state = TEH_KS_acquire ();
|
||||
@ -75,7 +322,7 @@ verify_and_execute_payback (struct MHD_Connection *connection,
|
||||
TALER_EC_PAYBACK_DENOMINATION_KEY_UNKNOWN,
|
||||
"denom_pub");
|
||||
}
|
||||
TALER_amount_ntoh (&value,
|
||||
TALER_amount_ntoh (&pc.value,
|
||||
&dki->issue.properties.value);
|
||||
|
||||
/* check denomination signature */
|
||||
@ -127,15 +374,24 @@ verify_and_execute_payback (struct MHD_Connection *connection,
|
||||
}
|
||||
GNUNET_CRYPTO_hash (coin_ev,
|
||||
coin_ev_size,
|
||||
&h_blind);
|
||||
&pc.h_blind);
|
||||
GNUNET_free (coin_ev);
|
||||
|
||||
return TEH_DB_execute_payback (connection,
|
||||
coin,
|
||||
&value,
|
||||
&h_blind,
|
||||
coin_bks,
|
||||
coin_sig);
|
||||
pc.coin_sig = coin_sig;
|
||||
pc.coin_bks = coin_bks;
|
||||
pc.coin = coin;
|
||||
if (GNUNET_OK !=
|
||||
TEH_DB_run_transaction (connection,
|
||||
&mhd_ret,
|
||||
&payback_transaction,
|
||||
&pc))
|
||||
return mhd_ret;
|
||||
|
||||
return reply_payback_success (connection,
|
||||
&coin->coin_pub,
|
||||
&pc.reserve_pub,
|
||||
&pc.amount,
|
||||
pc.now);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1294,67 +1294,4 @@ TEH_RESPONSE_reply_track_transfer_details (struct MHD_Connection *connection,
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A wallet asked for /payback, but we do not know anything about the
|
||||
* original withdraw operation specified. Generates a 404 reply.
|
||||
*
|
||||
* @param connection connection to the client
|
||||
* @param ec Taler error code
|
||||
* @return MHD result code
|
||||
*/
|
||||
int
|
||||
TEH_RESPONSE_reply_payback_unknown (struct MHD_Connection *connection,
|
||||
enum TALER_ErrorCode ec)
|
||||
{
|
||||
return TEH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
"{s:s, s:I}",
|
||||
"error", "blinded coin unknown",
|
||||
"code", (json_int_t) ec);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A wallet asked for /payback, return the successful response.
|
||||
*
|
||||
* @param connection connection to the client
|
||||
* @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 amount the amount we will wire back
|
||||
* @param timestamp when did the exchange receive the /payback request
|
||||
* @return MHD result code
|
||||
*/
|
||||
int
|
||||
TEH_RESPONSE_reply_payback_success (struct MHD_Connection *connection,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
const struct TALER_Amount *amount,
|
||||
struct GNUNET_TIME_Absolute timestamp)
|
||||
{
|
||||
struct TALER_PaybackConfirmationPS pc;
|
||||
struct TALER_ExchangePublicKeyP pub;
|
||||
struct TALER_ExchangeSignatureP sig;
|
||||
|
||||
pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
|
||||
pc.purpose.size = htonl (sizeof (struct TALER_PaybackConfirmationPS));
|
||||
pc.timestamp = GNUNET_TIME_absolute_hton (timestamp);
|
||||
TALER_amount_hton (&pc.payback_amount,
|
||||
amount);
|
||||
pc.coin_pub = *coin_pub;
|
||||
pc.reserve_pub = *reserve_pub;
|
||||
TEH_KS_sign (&pc.purpose,
|
||||
&pub,
|
||||
&sig);
|
||||
return TEH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_OK,
|
||||
"{s:o, s:o, s:o, s:o, s:o}",
|
||||
"reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub),
|
||||
"timestamp", GNUNET_JSON_from_time_abs (timestamp),
|
||||
"amount", TALER_JSON_from_amount (amount),
|
||||
"exchange_sig", GNUNET_JSON_from_data_auto (&sig),
|
||||
"exchange_pub", GNUNET_JSON_from_data_auto (&pub));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* end of taler-exchange-httpd_responses.c */
|
||||
|
@ -488,37 +488,6 @@ TEH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
|
||||
const struct TEH_RESPONSE_LinkSessionInfo *sessions);
|
||||
|
||||
|
||||
/**
|
||||
* A wallet asked for /payback, but we do not know anything about the
|
||||
* original withdraw operation specified. Generates a 404 reply.
|
||||
*
|
||||
* @param connection connection to the client
|
||||
* @param ec Taler error code
|
||||
* @return MHD result code
|
||||
*/
|
||||
int
|
||||
TEH_RESPONSE_reply_payback_unknown (struct MHD_Connection *connection,
|
||||
enum TALER_ErrorCode ec);
|
||||
|
||||
|
||||
/**
|
||||
* A wallet asked for /payback, return the successful response.
|
||||
*
|
||||
* @param connection connection to the client
|
||||
* @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 amount the amount we will wire back
|
||||
* @param timestamp when did the exchange receive the /payback request
|
||||
* @return MHD result code
|
||||
*/
|
||||
int
|
||||
TEH_RESPONSE_reply_payback_success (struct MHD_Connection *connection,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
|
||||
const struct TALER_Amount *amount,
|
||||
struct GNUNET_TIME_Absolute timestamp);
|
||||
|
||||
|
||||
/**
|
||||
* Compile the transaction history of a coin into a JSON object.
|
||||
|
@ -6161,11 +6161,9 @@ postgres_select_reserve_closed_above_serial_id (void *cls,
|
||||
* @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 current time (rounded)
|
||||
* @return #GNUNET_OK on success,
|
||||
* #GNUNET_NO on transient error
|
||||
* #GNUNET_SYSERR on DB errors
|
||||
* @return transaction result status
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
postgres_insert_payback_request (void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
@ -6193,6 +6191,7 @@ postgres_insert_payback_request (void *cls,
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
/* check if the coin is already known */
|
||||
// FIXME: #5010!
|
||||
ret = get_known_coin (cls,
|
||||
session,
|
||||
&coin->coin_pub,
|
||||
@ -6210,31 +6209,29 @@ postgres_insert_payback_request (void *cls,
|
||||
if (0 > qs)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
return ret;
|
||||
return qs;
|
||||
}
|
||||
}
|
||||
|
||||
/* now store actual payback information */
|
||||
if (GNUNET_OK !=
|
||||
(ret = execute_prepared_non_select (session,
|
||||
"payback_insert",
|
||||
params)))
|
||||
qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
|
||||
"payback_insert",
|
||||
params);
|
||||
if (0 > qs)
|
||||
{
|
||||
GNUNET_break (GNUNET_NO == ret);
|
||||
return ret;
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
return qs;
|
||||
}
|
||||
|
||||
/* Update reserve balance */
|
||||
reserve.pub = *reserve_pub;
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
postgres_reserve_get (cls,
|
||||
session,
|
||||
&reserve))
|
||||
qs = postgres_reserve_get (cls,
|
||||
session,
|
||||
&reserve);
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||
{
|
||||
/* FIXME: #5010 */
|
||||
/* Should have been checked before we got here... */
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
return qs;
|
||||
}
|
||||
if (GNUNET_SYSERR ==
|
||||
TALER_amount_add (&reserve.balance,
|
||||
@ -6242,7 +6239,7 @@ postgres_insert_payback_request (void *cls,
|
||||
amount))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
expiry = GNUNET_TIME_absolute_add (timestamp,
|
||||
pg->idle_reserve_expiration_time);
|
||||
@ -6253,10 +6250,10 @@ postgres_insert_payback_request (void *cls,
|
||||
&reserve);
|
||||
if (0 >= qs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||
return qs;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
return qs;
|
||||
}
|
||||
|
||||
|
||||
@ -6268,11 +6265,9 @@ postgres_insert_payback_request (void *cls,
|
||||
* @param session a session
|
||||
* @param h_blind_ev hash of the blinded coin
|
||||
* @param[out] reserve_pub set to information about the reserve (on success only)
|
||||
* @return #GNUNET_OK on success,
|
||||
* #GNUNET_NO if there are no entries,
|
||||
* #GNUNET_SYSERR on DB errors
|
||||
* @return transaction status code
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
postgres_get_reserve_by_h_blind (void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
const struct GNUNET_HashCode *h_blind_ev,
|
||||
@ -6282,47 +6277,16 @@ postgres_get_reserve_by_h_blind (void *cls,
|
||||
GNUNET_PQ_query_param_auto_from_type (h_blind_ev),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
PGresult *result;
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||
reserve_pub),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
|
||||
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||
"reserve_by_h_blind",
|
||||
params);
|
||||
if (PGRES_TUPLES_OK !=
|
||||
PQresultStatus (result))
|
||||
{
|
||||
BREAK_DB_ERR (result, session->conn);
|
||||
PQclear (result);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
int nrows;
|
||||
|
||||
nrows = PQntuples (result);
|
||||
if (0 == nrows)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"reserve_by_h_blind() returned 0 matching rows\n");
|
||||
PQclear (result);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
{
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||
reserve_pub),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_PQ_extract_result (result,
|
||||
rs,
|
||||
0))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
PQclear (result);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
PQclear (result);
|
||||
return GNUNET_OK;
|
||||
return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
|
||||
"reserve_by_h_blind",
|
||||
params,
|
||||
rs);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1598,7 +1598,7 @@ run (void *cls)
|
||||
value.fraction,
|
||||
value.currency));
|
||||
|
||||
FAILIF (GNUNET_YES !=
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->get_reserve_by_h_blind (plugin->cls,
|
||||
session,
|
||||
&cbc.h_coin_envelope,
|
||||
@ -1632,7 +1632,7 @@ run (void *cls)
|
||||
deposit.coin.denom_pub = dkp->pub;
|
||||
deposit.coin.denom_sig = cbc.sig;
|
||||
deadline = GNUNET_TIME_absolute_get ();
|
||||
FAILIF (GNUNET_OK !=
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->insert_payback_request (plugin->cls,
|
||||
session,
|
||||
&reserve_pub,
|
||||
@ -1913,7 +1913,7 @@ run (void *cls)
|
||||
|
||||
RND_BLK (&coin_sig);
|
||||
RND_BLK (&coin_blind);
|
||||
FAILIF (GNUNET_OK !=
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->insert_payback_request (plugin->cls,
|
||||
session,
|
||||
&reserve_pub,
|
||||
|
@ -2169,11 +2169,9 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @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
|
||||
* @return #GNUNET_OK on success,
|
||||
* #GNUNET_NO on transient error
|
||||
* #GNUNET_SYSERR on DB errors
|
||||
* @return transaction result status
|
||||
*/
|
||||
int
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*insert_payback_request)(void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
@ -2193,11 +2191,9 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @param session a session
|
||||
* @param h_blind_ev hash of the blinded coin
|
||||
* @param[out] reserve_pub set to information about the reserve (on success only)
|
||||
* @return #GNUNET_OK on success,
|
||||
* #GNUNET_NO if there are no entries,
|
||||
* #GNUNET_SYSERR on DB errors
|
||||
* @return transaction status code
|
||||
*/
|
||||
int
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*get_reserve_by_h_blind)(void *cls,
|
||||
struct TALER_EXCHANGEDB_Session *session,
|
||||
const struct GNUNET_HashCode *h_blind_ev,
|
||||
|
Loading…
Reference in New Issue
Block a user