From fbff951e7d0a8965c44e37716067d5ddc13c975a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 22 Jun 2017 11:49:40 +0200 Subject: [PATCH] address #5010 for /refresh/melt --- .../taler-exchange-httpd_refresh_melt.c | 344 ++++++++---------- .../perf_taler_exchangedb_interpreter.c | 34 +- src/exchangedb/plugin_exchangedb_postgres.c | 70 ++-- src/exchangedb/test_exchangedb.c | 6 +- src/include/taler_exchangedb_plugin.h | 24 +- 5 files changed, 205 insertions(+), 273 deletions(-) diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c index 71f5a9999..edcd84946 100644 --- a/src/exchange/taler-exchange-httpd_refresh_melt.c +++ b/src/exchange/taler-exchange-httpd_refresh_melt.c @@ -83,8 +83,8 @@ reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection, const struct TALER_CoinSpendPublicKeyP *coin_pub, struct TALER_Amount coin_value, struct TALER_EXCHANGEDB_TransactionList *tl, - struct TALER_Amount requested, - struct TALER_Amount residual) + const struct TALER_Amount *requested, + const struct TALER_Amount *residual) { json_t *history; @@ -104,9 +104,9 @@ reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection, "original_value", TALER_JSON_from_amount (&coin_value), "residual_value", - TALER_JSON_from_amount (&residual), + TALER_JSON_from_amount (residual), "requested_value", - TALER_JSON_from_amount (&requested), + TALER_JSON_from_amount (requested), "history", history); } @@ -155,6 +155,17 @@ reply_refresh_melt_success (struct MHD_Connection *connection, struct RefreshMeltContext { + /** + * Key state that can be used to lookup keys. + */ + struct TEH_KS_StateHandle *key_state; + + /** + * Information about the denomination key of the coin being + * melted. + */ + struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; + /** * Array of denominations of the fresh coins. */ @@ -205,51 +216,39 @@ struct RefreshMeltContext * * @param connection the connection to send errors to * @param session the database connection - * @param key_state the exchange's key state - * @param session_hash hash identifying the refresh session - * @param coin_details details about the coin being melted - * @param[out] meltp on success, set to melt details - * @return #GNUNET_OK on success, - * #GNUNET_NO if an error message was generated, - * #GNUNET_SYSERR on internal errors (no response generated) + * @param[in,out] rmc melt context + * @param[out] mhd_ret status code to return to MHD on hard error + * @return transaction status code */ -static int +static enum GNUNET_DB_QueryStatus refresh_check_melt (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_Session *session, - const struct TEH_KS_StateHandle *key_state, - const struct GNUNET_HashCode *session_hash, - const struct TEH_DB_MeltDetails *coin_details, - struct TALER_EXCHANGEDB_RefreshMelt *meltp) + struct RefreshMeltContext *rmc, + int *mhd_ret) { - struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dk; - struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki; struct TALER_EXCHANGEDB_TransactionList *tl; + struct TALER_EXCHANGEDB_RefreshMelt *meltp = &rmc->refresh_session.melt; struct TALER_Amount coin_value; struct TALER_Amount coin_residual; struct TALER_Amount spent; - int res; enum GNUNET_DB_QueryStatus qs; - dk = TEH_KS_denomination_key_lookup (key_state, - &coin_details->coin_info.denom_pub, - TEH_KS_DKU_DEPOSIT); - if (NULL == dk) - return (MHD_YES == - TEH_RESPONSE_reply_internal_error (connection, - TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND, - "denomination key no longer available while executing transaction")) - ? GNUNET_NO : GNUNET_SYSERR; - dki = &dk->issue; TALER_amount_ntoh (&coin_value, - &dki->properties.value); + &rmc->dki->issue.properties.value); /* fee for THIS transaction; the melt amount includes the fee! */ - spent = coin_details->melt_amount_with_fee; + spent = rmc->coin_melt_details.melt_amount_with_fee; /* add historic transaction costs of this coin */ qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls, session, - &coin_details->coin_info.coin_pub, + &rmc->coin_melt_details.coin_info.coin_pub, &tl); - (void) qs; /* FIXME #5010 */ + if (0 > qs) + { + if (GNUNET_DB_STATUS_HARD_ERROR == qs) + *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_DB_FETCH_ERROR); + return qs; + } if (GNUNET_OK != TEH_DB_calculate_transaction_list_totals (tl, &spent, @@ -258,10 +257,9 @@ refresh_check_melt (struct MHD_Connection *connection, GNUNET_break (0); TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); - return (MHD_YES == - TEH_RESPONSE_reply_internal_db_error (connection, - TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED)) - ? GNUNET_NO : GNUNET_SYSERR; + *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED); + return GNUNET_DB_STATUS_HARD_ERROR; } /* Refuse to refresh when the coin's value is insufficient for the cost of all transactions. */ @@ -271,43 +269,41 @@ refresh_check_melt (struct MHD_Connection *connection, GNUNET_assert (GNUNET_SYSERR != TALER_amount_subtract (&coin_residual, &spent, - &coin_details->melt_amount_with_fee)); - res = (MHD_YES == - reply_refresh_melt_insufficient_funds (connection, - &coin_details->coin_info.coin_pub, - coin_value, - tl, - coin_details->melt_amount_with_fee, - coin_residual)) - ? GNUNET_NO : GNUNET_SYSERR; + &rmc->coin_melt_details.melt_amount_with_fee)); + *mhd_ret = reply_refresh_melt_insufficient_funds (connection, + &rmc->coin_melt_details.coin_info.coin_pub, + coin_value, + tl, + &rmc->coin_melt_details.melt_amount_with_fee, + &coin_residual); TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); - return res; + return GNUNET_DB_STATUS_HARD_ERROR; } TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); - meltp->coin = coin_details->coin_info; - meltp->coin_sig = coin_details->melt_sig; - meltp->session_hash = *session_hash; - meltp->amount_with_fee = coin_details->melt_amount_with_fee; - meltp->melt_fee = coin_details->melt_fee; - return GNUNET_OK; + meltp->coin = rmc->coin_melt_details.coin_info; + meltp->coin_sig = rmc->coin_melt_details.melt_sig; + meltp->session_hash = rmc->session_hash; + meltp->amount_with_fee = rmc->coin_melt_details.melt_amount_with_fee; + meltp->melt_fee = rmc->coin_melt_details.melt_fee; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } /** * Execute a "/refresh/melt". We have been given a list of valid - * coins and a request to melt them into the given - * @a refresh_session_pub. Check that the coins all have the - * required value left and if so, store that they have been - * melted and confirm the melting operation to the client. + * coins and a request to melt them into the given @a + * refresh_session_pub. Check that the coins all have the required + * value left and if so, store that they have been melted and confirm + * the melting operation to the client. * - * 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. + * 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 our `struct RefreshMeltContext` * @param connection MHD request which triggered the transaction @@ -323,9 +319,7 @@ refresh_melt_transaction (void *cls, int *mhd_ret) { struct RefreshMeltContext *rmc = cls; - struct TEH_KS_StateHandle *key_state; enum GNUNET_DB_QueryStatus qs; - int res; qs = TEH_plugin->get_refresh_session (TEH_plugin->cls, session, @@ -352,20 +346,12 @@ refresh_melt_transaction (void *cls, = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, TALER_CNC_KAPPA); - key_state = TEH_KS_acquire (); - if (GNUNET_OK != - (res = refresh_check_melt (connection, - session, - key_state, - &rmc->session_hash, - &rmc->coin_melt_details, - &rmc->refresh_session.melt))) - { - TEH_KS_release (key_state); - *mhd_ret = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - return GNUNET_DB_STATUS_HARD_ERROR; - } - TEH_KS_release (key_state); + qs = refresh_check_melt (connection, + session, + rmc, + mhd_ret); + if (0 > qs) + return qs; if ( (0 >= (qs = TEH_plugin->create_refresh_session (TEH_plugin->cls, @@ -403,9 +389,10 @@ refresh_melt_transaction (void *cls, /** - * Handle a "/refresh/melt" request after the main JSON parsing has happened. - * We now need to validate the coins being melted and the session signature - * and then hand things of to execute the melt operation. + * Handle a "/refresh/melt" request after the main JSON parsing has + * happened. We now need to validate the coins being melted and the + * session signature and then hand things of to execute the melt + * operation. * * @param connection the MHD connection to handle * @param[out] mhd_ret set on failure to return value for MHD @@ -417,7 +404,6 @@ refresh_melt_prepare (struct MHD_Connection *connection, int *mhd_ret, struct RefreshMeltContext *rmc) { - struct TEH_KS_StateHandle *key_state; struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dk; struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki; struct TALER_Amount cost; @@ -434,16 +420,14 @@ refresh_melt_prepare (struct MHD_Connection *connection, GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (TEH_exchange_currency_string, &total_cost)); - key_state = TEH_KS_acquire (); for (unsigned int i=0;inum_newcoins;i++) { - dk = TEH_KS_denomination_key_lookup (key_state, + dk = TEH_KS_denomination_key_lookup (rmc->key_state, &rmc->denom_pubs[i], TEH_KS_DKU_WITHDRAW); if (NULL == dk) { GNUNET_break_op (0); - TEH_KS_release (key_state); *mhd_ret = TEH_RESPONSE_reply_arg_invalid (connection, TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND, "new_denoms"); @@ -464,7 +448,6 @@ refresh_melt_prepare (struct MHD_Connection *connection, &total_cost)) ) { GNUNET_break_op (0); - TEH_KS_release (key_state); *mhd_ret = TEH_RESPONSE_reply_internal_error (connection, TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW, "cost calculation failure"); @@ -472,18 +455,7 @@ refresh_melt_prepare (struct MHD_Connection *connection, } } - dk = TEH_KS_denomination_key_lookup (key_state, - &rmc->coin_melt_details.coin_info.denom_pub, - TEH_KS_DKU_DEPOSIT); - if (NULL == dk) - { - GNUNET_break (0); - *mhd_ret = TEH_RESPONSE_reply_arg_unknown (connection, - TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND, - "denom_pub"); - return GNUNET_SYSERR; - } - dki = &dk->issue; + dki = &rmc->dki->issue; TALER_amount_ntoh (&fee_melt, &dki->properties.fee_refresh); if (GNUNET_OK != @@ -492,13 +464,11 @@ refresh_melt_prepare (struct MHD_Connection *connection, &fee_melt)) { GNUNET_break_op (0); - TEH_KS_release (key_state); *mhd_ret = TEH_RESPONSE_reply_external_error (connection, TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION, "Melt contribution below melting fee"); return GNUNET_SYSERR; } - TEH_KS_release (key_state); if (0 != TALER_amount_cmp (&total_cost, &total_melt)) @@ -579,87 +549,6 @@ get_coin_public_info (struct MHD_Connection *connection, } -/** - * Verify that the signature shows that this coin is to be melted into - * the given @a session_hash melting session, and that this is a valid - * coin (we know the denomination key and the signature on it is - * valid). Essentially, this does all of the per-coin checks that can - * be done before the transaction starts. - * - * @param connection the connection to send error responses to - * @param session_hash hash over refresh session the coin is melted into - * @param[in,out] melt_detail details about the coin's melting permission, - * the `melt_fee` is updated - * @return #GNUNET_YES if coin public info in JSON was valid - * #GNUNET_NO JSON was invalid, response was generated - * #GNUNET_SYSERR on internal error - */ -static int -verify_coin_public_info (struct MHD_Connection *connection, - const struct GNUNET_HashCode *session_hash, - struct TEH_DB_MeltDetails *melt_detail) -{ - struct TALER_RefreshMeltCoinAffirmationPS body; - struct TEH_KS_StateHandle *key_state; - struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; - struct TALER_Amount fee_refresh; - - /* FIXME: we lookup the dki twice during /refresh/melt. - This should be avoided. */ - key_state = TEH_KS_acquire (); - dki = TEH_KS_denomination_key_lookup (key_state, - &melt_detail->coin_info.denom_pub, - TEH_KS_DKU_DEPOSIT); - if (NULL == dki) - { - TEH_KS_release (key_state); - TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n"); - return TEH_RESPONSE_reply_arg_unknown (connection, - TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND, - "denom_pub"); - } - TALER_amount_ntoh (&fee_refresh, - &dki->issue.properties.fee_refresh); - melt_detail->melt_fee = fee_refresh; - body.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS)); - body.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT); - body.session_hash = *session_hash; - TALER_amount_hton (&body.amount_with_fee, - &melt_detail->melt_amount_with_fee); - TALER_amount_hton (&body.melt_fee, - &fee_refresh); - body.coin_pub = melt_detail->coin_info.coin_pub; - if (TALER_amount_cmp (&fee_refresh, - &melt_detail->melt_amount_with_fee) > 0) - { - GNUNET_break_op (0); - TEH_KS_release (key_state); - return (MHD_YES == - TEH_RESPONSE_reply_external_error (connection, - TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT, - "melt amount smaller than melting fee")) - ? GNUNET_NO : GNUNET_SYSERR; - } - - TEH_KS_release (key_state); - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT, - &body.purpose, - &melt_detail->melt_sig.eddsa_signature, - &melt_detail->coin_info.coin_pub.eddsa_pub)) - { - GNUNET_break_op (0); - if (MHD_YES != - TEH_RESPONSE_reply_signature_invalid (connection, - TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID, - "confirm_sig")) - return GNUNET_SYSERR; - return GNUNET_NO; - } - return GNUNET_OK; -} - - /** * Release memory from the @a commit_coin array. * @@ -679,6 +568,7 @@ free_commit_coins (struct TALER_EXCHANGEDB_RefreshCommitCoin **commit_coin, for (unsigned int j=0;jnum_newcoins); if (NULL != rmc->coin_melt_details.coin_info.denom_pub.rsa_public_key) + { GNUNET_CRYPTO_rsa_public_key_free (rmc->coin_melt_details.coin_info.denom_pub.rsa_public_key); + rmc->coin_melt_details.coin_info.denom_pub.rsa_public_key = NULL; + } if (NULL != rmc->coin_melt_details.coin_info.denom_sig.rsa_signature) + { GNUNET_CRYPTO_rsa_signature_free (rmc->coin_melt_details.coin_info.denom_sig.rsa_signature); + rmc->coin_melt_details.coin_info.denom_sig.rsa_signature = NULL; + } if (NULL != rmc->denom_pubs) { for (unsigned int j=0;jnum_newcoins;j++) if (NULL != rmc->denom_pubs[j].rsa_public_key) GNUNET_CRYPTO_rsa_public_key_free (rmc->denom_pubs[j].rsa_public_key); GNUNET_free (rmc->denom_pubs); + rmc->denom_pubs = NULL; } if (NULL != rmc->hash_context) + { GNUNET_CRYPTO_hash_context_abort (rmc->hash_context); + rmc->hash_context = NULL; + } + if (NULL != rmc->key_state) + { + TEH_KS_release (rmc->key_state); + rmc->key_state = NULL; + } } /** - * Handle a "/refresh/melt" request after the first parsing has happened. - * We now need to validate the coins being melted and the session signature - * and then hand things of to execute the melt operation. This function - * parses the JSON arrays and then passes processing on to - * #handle_refresh_melt_binary(). + * Handle a "/refresh/melt" request after the first parsing has + * happened. We now need to validate the coins being melted and the + * session signature and then hand things of to execute the melt + * operation. This function parses the JSON arrays and then passes + * processing on to #handle_refresh_melt_binary(). * * @param connection the MHD connection to handle * @param new_denoms array of denomination keys @@ -741,7 +646,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection, /* For the signature check, we hash most of the inputs together (except for the signatures on the coins). */ rmc.hash_context = GNUNET_CRYPTO_hash_context_start (); - for (unsigned int i = 0; i < TALER_CNC_KAPPA; i++) { struct GNUNET_JSON_Specification trans_spec[] = { @@ -765,7 +669,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection, sizeof (struct TALER_TransferPublicKeyP)); } - rmc.num_newcoins = json_array_size (new_denoms); rmc.denom_pubs = GNUNET_new_array (rmc.num_newcoins, struct TALER_DenominationPublicKey); @@ -797,9 +700,10 @@ handle_refresh_melt_json (struct MHD_Connection *connection, buf_size); GNUNET_free (buf); } - + + /* decode JSON data on coin to melt and check that this is a + valid coin */ { - /* decode JSON data on coin to melt */ struct TALER_AmountNBO melt_amount; res = get_coin_public_info (connection, @@ -861,18 +765,60 @@ handle_refresh_melt_json (struct MHD_Connection *connection, GNUNET_CRYPTO_hash_context_finish (rmc.hash_context, &rmc.session_hash); rmc.hash_context = NULL; - /* verify signature on coins to melt */ - res = verify_coin_public_info (connection, - &rmc.session_hash, - &rmc.coin_melt_details); - if (GNUNET_OK != res) + + rmc.key_state = TEH_KS_acquire (); + rmc.dki = TEH_KS_denomination_key_lookup (rmc.key_state, + &rmc.coin_melt_details.coin_info.denom_pub, + TEH_KS_DKU_DEPOSIT); + if (NULL == rmc.dki) { - GNUNET_break_op (0); - mhd_ret = (GNUNET_NO == res) ? MHD_YES : MHD_NO; - cleanup_rmc (&rmc); - return mhd_ret; + TEH_KS_release (rmc.key_state); + TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n"); + return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND, + "denom_pub"); } + /* verify signature of coin for melt operation */ + { + struct TALER_RefreshMeltCoinAffirmationPS body; + struct TALER_Amount fee_refresh; + + TALER_amount_ntoh (&fee_refresh, + &rmc.dki->issue.properties.fee_refresh); + rmc.coin_melt_details.melt_fee = fee_refresh; + body.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS)); + body.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT); + body.session_hash = rmc.session_hash; + TALER_amount_hton (&body.amount_with_fee, + &rmc.coin_melt_details.melt_amount_with_fee); + TALER_amount_hton (&body.melt_fee, + &fee_refresh); + body.coin_pub = rmc.coin_melt_details.coin_info.coin_pub; + if (TALER_amount_cmp (&fee_refresh, + &rmc.coin_melt_details.melt_amount_with_fee) > 0) + { + GNUNET_break_op (0); + cleanup_rmc (&rmc); + return TEH_RESPONSE_reply_external_error (connection, + TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT, + "melt amount smaller than melting fee"); + } + + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT, + &body.purpose, + &rmc.coin_melt_details.melt_sig.eddsa_signature, + &rmc.coin_melt_details.coin_info.coin_pub.eddsa_pub)) + { + GNUNET_break_op (0); + cleanup_rmc (&rmc); + return TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID, + "confirm_sig"); + } + } + /* prepare commit */ if (GNUNET_OK != refresh_melt_prepare (connection, diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c b/src/exchangedb/perf_taler_exchangedb_interpreter.c index 3f52e90e2..7a5915807 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.c +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c @@ -1553,10 +1553,11 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) refresh_session = PERF_TALER_EXCHANGEDB_refresh_session_init (); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, hash); - state->plugin->create_refresh_session (state->session, - state->session, - hash, - refresh_session); + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + state->plugin->create_refresh_session (state->session, + state->session, + hash, + refresh_session)); state->cmd[state->i].exposed.data.session_hash = hash; PERF_TALER_EXCHANGEDB_refresh_session_free (refresh_session); GNUNET_free (refresh_session); @@ -1589,11 +1590,12 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) denom_index = state->cmd[state->i].details.insert_refresh_order.index_denom; session_hash = state->cmd[hash_index].exposed.data.session_hash; denom = state->cmd[denom_index].exposed.data.dki; - state->plugin->insert_refresh_order (state->plugin->cls, - state->session, - session_hash, - 1, - &denom->denom_pub); + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + state->plugin->insert_refresh_order (state->plugin->cls, + state->session, + session_hash, + 1, + &denom->denom_pub)); } break; @@ -1616,18 +1618,18 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) case PERF_TALER_EXCHANGEDB_CMD_INSERT_REFRESH_COMMIT_COIN: { - int ret; + enum GNUNET_DB_QueryStatus qs; unsigned int hash_index; struct TALER_EXCHANGEDB_RefreshCommitCoin *refresh_commit; hash_index = state->cmd[state->i].details.insert_refresh_commit_coin.index_hash; refresh_commit = PERF_TALER_EXCHANGEDB_refresh_commit_coin_init (); - ret = state->plugin->insert_refresh_commit_coins (state->plugin->cls, - state->session, - state->cmd[hash_index].exposed.data.session_hash, - 1, - refresh_commit); - GNUNET_assert (GNUNET_OK == ret); + qs = state->plugin->insert_refresh_commit_coins (state->plugin->cls, + state->session, + state->cmd[hash_index].exposed.data.session_hash, + 1, + refresh_commit); + GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs); } break; diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 592751f66..9df7fc4f3 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -3344,11 +3344,9 @@ postgres_get_refresh_session (void *cls, * @param session database handle to use * @param session_hash hash over the melt to use to locate the session * @param refresh_session session data to store - * @return #GNUNET_YES on success, - * #GNUNET_NO on transient error - * #GNUNET_SYSERR on DB failure + * @return query status for the transaction */ -static int +static enum GNUNET_DB_QueryStatus postgres_create_refresh_session (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, @@ -3366,7 +3364,7 @@ postgres_create_refresh_session (void *cls, int ret; enum GNUNET_DB_QueryStatus qs; - /* check if the coin is already known */ + /* check if the coin is already known (FIXME: #5010) */ ret = get_known_coin (cls, session, &refresh_session->melt.coin.coin_pub, @@ -3384,13 +3382,13 @@ postgres_create_refresh_session (void *cls, if (0 > qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - return GNUNET_SYSERR; + return qs; } } - - return execute_prepared_non_select (session, - "insert_refresh_session", - params); + + return GNUNET_PQ_eval_prepared_non_select (session->conn, + "insert_refresh_session", + params); } @@ -3403,11 +3401,9 @@ postgres_create_refresh_session (void *cls, * @param session_hash hash to identify refresh session * @param num_newcoins number of coins to generate, size of the @a denom_pubs array * @param denom_pubs array denominations of the coins to create - * @return #GNUNET_OK on success - * #GNUNET_NO on transient error - * #GNUNET_SYSERR on internal error + * @return query status for the transaction */ -static int +static enum GNUNET_DB_QueryStatus postgres_insert_refresh_order (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, @@ -3426,18 +3422,18 @@ postgres_insert_refresh_order (void *cls, GNUNET_PQ_query_param_auto_from_type (&denom_pub_hash), GNUNET_PQ_query_param_end }; - int ret; + enum GNUNET_DB_QueryStatus qs; GNUNET_CRYPTO_rsa_public_key_hash (denom_pubs[i].rsa_public_key, &denom_pub_hash); - ret = execute_prepared_non_select (session, - "insert_refresh_order", - params); - if (GNUNET_OK != ret) - return ret; + qs = GNUNET_PQ_eval_prepared_non_select (session->conn, + "insert_refresh_order", + params); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + return qs; } } - return GNUNET_OK; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -3524,11 +3520,9 @@ postgres_get_refresh_order (void *cls, * @param session_hash hash to identify refresh session * @param num_newcoins coin index size of the @a commit_coins array * @param commit_coins array of coin commitments to store - * @return #GNUNET_OK on success - * #GNUNET_NO on transient error - * #GNUNET_SYSERR on error + * @return query transaction status */ -static int +static enum GNUNET_DB_QueryStatus postgres_insert_refresh_commit_coins (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, @@ -3544,15 +3538,15 @@ postgres_insert_refresh_commit_coins (void *cls, commit_coins[coin_off].coin_ev_size), GNUNET_PQ_query_param_end }; - int ret; + enum GNUNET_DB_QueryStatus qs; - ret = execute_prepared_non_select (session, - "insert_refresh_commit_coin", - params); - if (GNUNET_OK != ret) - return ret; + qs = GNUNET_PQ_eval_prepared_non_select (session->conn, + "insert_refresh_commit_coin", + params); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + return qs; } - return GNUNET_OK; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } @@ -3640,11 +3634,9 @@ postgres_get_refresh_commit_coins (void *cls, * @param session database connection to use * @param session_hash hash to identify refresh session * @param tp transfer public key to store - * @return #GNUNET_SYSERR on internal error, - * #GNUNET_NO on transient errors - * #GNUNET_OK on success + * @return transaction status */ -static int +static enum GNUNET_DB_QueryStatus postgres_insert_refresh_transfer_public_key (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, @@ -3656,9 +3648,9 @@ postgres_insert_refresh_transfer_public_key (void *cls, GNUNET_PQ_query_param_end }; - return execute_prepared_non_select (session, - "insert_transfer_public_key", - params); + return GNUNET_PQ_eval_prepared_non_select (session->conn, + "insert_transfer_public_key", + params); } diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 673d51446..1b3797dd3 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -349,7 +349,7 @@ test_refresh_commit_coins (struct TALER_EXCHANGEDB_Session *session, ccoin->coin_ev, ccoin->coin_ev_size); } - FAILIF (GNUNET_OK != + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->insert_refresh_commit_coins (plugin->cls, session, session_hash, @@ -417,7 +417,7 @@ test_refresh_commit_links (struct TALER_EXCHANGEDB_Session *session, &tp)); for (i=0;iinsert_refresh_transfer_public_key (plugin->cls, session, session_hash, @@ -572,7 +572,7 @@ test_melting (struct TALER_EXCHANGEDB_Session *session) meltp->melt_fee = fee_refresh; } - FAILIF (GNUNET_OK != + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->create_refresh_session (plugin->cls, session, &session_hash, diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 9fe0874bd..b586f2766 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -1457,11 +1457,9 @@ struct TALER_EXCHANGEDB_Plugin * @param session database handle to use * @param session_hash hash over the melt to use to locate the session * @param refresh_session session data to store - * @return #GNUNET_YES on success, - * #GNUNET_NO on transient error - * #GNUNET_SYSERR on DB failure + * @return query status for the transaction */ - int + enum GNUNET_DB_QueryStatus (*create_refresh_session) (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, @@ -1477,11 +1475,9 @@ struct TALER_EXCHANGEDB_Plugin * @param session_hash hash to identify refresh session * @param num_newcoins number of coins to generate, size of the @a denom_pubs array * @param denom_pubs array denominations of the coins to create - * @return #GNUNET_OK on success - * #GNUNET_NO on transient error - * #GNUNET_SYSERR on internal error + * @return query status for the transaction */ - int + enum GNUNET_DB_QueryStatus (*insert_refresh_order) (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, @@ -1517,11 +1513,9 @@ struct TALER_EXCHANGEDB_Plugin * @param session_hash hash to identify refresh session * @param num_newcoins coin index size of the @a commit_coins array * @param commit_coin array of coin commitments to store - * @return #GNUNET_OK on success - * #GNUNET_NO on transient error - * #GNUNET_SYSERR on error + * @return query status for the transaction */ - int + enum GNUNET_DB_QueryStatus (*insert_refresh_commit_coins) (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash, @@ -1568,11 +1562,9 @@ struct TALER_EXCHANGEDB_Plugin * @param session database connection to use * @param session_hash hash to identify refresh session * @param tp public key to store - * @return #GNUNET_SYSERR on internal error - * #GNUNET_NO on transient errors - * #GNUNET_OK on success + * @return query status for the transaction */ - int + enum GNUNET_DB_QueryStatus (*insert_refresh_transfer_public_key) (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct GNUNET_HashCode *session_hash,