summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-06-22 11:49:40 +0200
committerChristian Grothoff <christian@grothoff.org>2017-06-22 11:49:40 +0200
commitfbff951e7d0a8965c44e37716067d5ddc13c975a (patch)
treeb940610f8540ce960525d0afe47a17bc067ca3e8
parent87e16541af26380c50733cf4b3271c98f8efbda3 (diff)
downloadexchange-fbff951e7d0a8965c44e37716067d5ddc13c975a.tar.gz
exchange-fbff951e7d0a8965c44e37716067d5ddc13c975a.tar.bz2
exchange-fbff951e7d0a8965c44e37716067d5ddc13c975a.zip
address #5010 for /refresh/melt
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_melt.c344
-rw-r--r--src/exchangedb/perf_taler_exchangedb_interpreter.c34
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c70
-rw-r--r--src/exchangedb/test_exchangedb.c6
-rw-r--r--src/include/taler_exchangedb_plugin.h24
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);
}
@@ -156,6 +156,17 @@ 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.
*/
struct TALER_DenominationPublicKey *denom_pubs;
@@ -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;i<rmc->num_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))
@@ -580,87 +550,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.
*
* @param commit_coin array to release
@@ -679,6 +568,7 @@ free_commit_coins (struct TALER_EXCHANGEDB_RefreshCommitCoin **commit_coin,
for (unsigned int j=0;j<num_new_coins;j++)
GNUNET_free_non_null (commit_coin[i][j].coin_ev);
GNUNET_free (commit_coin[i]);
+ commit_coin[i] = NULL;
}
}
@@ -695,27 +585,42 @@ cleanup_rmc (struct RefreshMeltContext *rmc)
TALER_CNC_KAPPA,
rmc->num_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;j<rmc->num_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;i<TALER_CNC_KAPPA;i++)
RND_BLK (&rctp[i]);
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->insert_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,