summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-06-20 22:30:15 +0200
committerChristian Grothoff <christian@grothoff.org>2017-06-20 22:33:20 +0200
commit053096475fdb1d6d81aa87bce36f1aceb6264038 (patch)
treebc5671743770e7560a582d2fe7dd077269327dc7
parent39db1ae5dbbd12c0f452cfa56119d9a95f9b1b22 (diff)
downloadexchange-053096475fdb1d6d81aa87bce36f1aceb6264038.tar.gz
exchange-053096475fdb1d6d81aa87bce36f1aceb6264038.tar.bz2
exchange-053096475fdb1d6d81aa87bce36f1aceb6264038.zip
fixing #5010 for /refresh/reveal
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_melt.c22
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_reveal.c674
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c333
-rw-r--r--src/exchangedb/test_exchangedb.c45
-rw-r--r--src/include/taler_exchangedb_plugin.h33
5 files changed, 451 insertions, 656 deletions
diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c
index 1c4e5e864..1b7e67918 100644
--- a/src/exchange/taler-exchange-httpd_refresh_melt.c
+++ b/src/exchange/taler-exchange-httpd_refresh_melt.c
@@ -500,7 +500,6 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
const struct TALER_TransferPublicKeyP *transfer_pubs)
{
- unsigned int i;
struct TEH_KS_StateHandle *key_state;
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dk;
struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki;
@@ -519,7 +518,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
TALER_amount_get_zero (TEH_exchange_currency_string,
&total_cost));
key_state = TEH_KS_acquire ();
- for (i=0;i<num_new_denoms;i++)
+ for (unsigned int i=0;i<num_new_denoms;i++)
{
dk = TEH_KS_denomination_key_lookup (key_state,
&denom_pubs[i],
@@ -754,14 +753,11 @@ free_commit_coins (struct TALER_EXCHANGEDB_RefreshCommitCoin **commit_coin,
unsigned int kappa,
unsigned int num_new_coins)
{
- unsigned int i;
- unsigned int j;
-
- for (i=0;i<kappa;i++)
+ for (unsigned int i=0;i<kappa;i++)
{
if (NULL == commit_coin[i])
break;
- for (j=0;j<num_new_coins;j++)
+ 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]);
}
@@ -790,8 +786,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
const json_t *coin_evs)
{
int res;
- unsigned int i;
- unsigned int j;
struct TALER_DenominationPublicKey *denom_pubs;
unsigned int num_newcoins;
struct TEH_DB_MeltDetails coin_melt_details;
@@ -804,7 +798,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
(except for the signatures on the coins). */
hash_context = GNUNET_CRYPTO_hash_context_start ();
- for (i = 0; i < TALER_CNC_KAPPA; i++)
+ for (unsigned int i = 0; i < TALER_CNC_KAPPA; i++)
{
struct GNUNET_JSON_Specification trans_spec[] = {
GNUNET_JSON_spec_fixed_auto (NULL, &transfer_pub[i]),
@@ -830,7 +824,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
num_newcoins = json_array_size (new_denoms);
denom_pubs = GNUNET_new_array (num_newcoins,
struct TALER_DenominationPublicKey);
- for (i=0;i<num_newcoins;i++)
+ for (unsigned int i=0;i<num_newcoins;i++)
{
char *buf;
size_t buf_size;
@@ -885,11 +879,11 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
memset (commit_coin,
0,
sizeof (commit_coin));
- for (i = 0; i < TALER_CNC_KAPPA; i++)
+ for (unsigned int i = 0; i < TALER_CNC_KAPPA; i++)
{
commit_coin[i] = GNUNET_new_array (num_newcoins,
struct TALER_EXCHANGEDB_RefreshCommitCoin);
- for (j = 0; j < num_newcoins; j++)
+ for (unsigned int j = 0; j < num_newcoins; j++)
{
struct TALER_EXCHANGEDB_RefreshCommitCoin *rcc = &commit_coin[i][j];
struct GNUNET_JSON_Specification coin_spec[] = {
@@ -950,7 +944,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
cleanup_denoms:
if (NULL != denom_pubs)
{
- for (j=0;j<num_newcoins;j++)
+ for (unsigned int j=0;j<num_newcoins;j++)
if (NULL != denom_pubs[j].rsa_public_key)
GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
GNUNET_free (denom_pubs);
diff --git a/src/exchange/taler-exchange-httpd_refresh_reveal.c b/src/exchange/taler-exchange-httpd_refresh_reveal.c
index 05422a85a..cfb2b68ac 100644
--- a/src/exchange/taler-exchange-httpd_refresh_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refresh_reveal.c
@@ -32,95 +32,6 @@
/**
- * How often should we retry a transaction before giving up
- * (for transactions resulting in serialization/dead locks only).
- */
-#define MAX_TRANSACTION_COMMIT_RETRIES 3
-
-/**
- * Code to begin a transaction, must be inline as we define a block
- * that ends with #COMMIT_TRANSACTION() within which we perform a number
- * of retries. Note that this code may call "return" internally, so
- * it must be called within a function where any cleanup will be done
- * by the caller. Furthermore, the function's return value must
- * match that of a #TEH_RESPONSE_reply_internal_db_error() status code.
- *
- * @param session session handle
- * @param connection connection handle
- */
-#define START_TRANSACTION(session,connection) \
-{ /* start new scope, will be ended by COMMIT_TRANSACTION() */\
- unsigned int transaction_retries = 0; \
- enum GNUNET_DB_QueryStatus transaction_commit_result; \
-transaction_start_label: /* we will use goto for retries */ \
- if (GNUNET_OK != \
- TEH_plugin->start (TEH_plugin->cls, \
- session)) \
- { \
- GNUNET_break (0); \
- return TEH_RESPONSE_reply_internal_db_error (connection, \
- TALER_EC_DB_START_FAILED); \
- }
-
-/**
- * Code to conclude a transaction, dual to #START_TRANSACTION(). Note
- * that this code may call "return" internally, so it must be called
- * within a function where any cleanup will be done by the caller.
- * Furthermore, the function's return value must match that of a
- * #TEH_RESPONSE_reply_internal_db_error() status code.
- *
- * @param session session handle
- * @param connection connection handle
- */
-#define COMMIT_TRANSACTION(session,connection) \
- transaction_commit_result = \
- TEH_plugin->commit (TEH_plugin->cls, \
- session); \
- if (GNUNET_DB_STATUS_HARD_ERROR == transaction_commit_result) \
- { \
- TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
- return TEH_RESPONSE_reply_commit_error (connection, \
- TALER_EC_DB_COMMIT_FAILED_HARD); \
- } \
- if (GNUNET_DB_STATUS_SOFT_ERROR == transaction_commit_result) \
- { \
- TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
- if (transaction_retries++ <= MAX_TRANSACTION_COMMIT_RETRIES) \
- goto transaction_start_label; \
- TALER_LOG_WARNING ("Transaction commit failed %u times in %s\n", \
- transaction_retries, \
- __FUNCTION__); \
- return TEH_RESPONSE_reply_commit_error (connection, \
- TALER_EC_DB_COMMIT_FAILED_ON_RETRY); \
- } \
-} /* end of scope opened by BEGIN_TRANSACTION */
-
-
-/**
- * Code to include to retry a transaction, must only be used in between
- * #START_TRANSACTION and #COMMIT_TRANSACTION.
- *
- * @param session session handle
- * @param connection connection handle
- */
-#define RETRY_TRANSACTION(session,connection) \
- do { \
- TEH_plugin->rollback (TEH_plugin->cls, \
- session); \
- if (transaction_retries++ <= MAX_TRANSACTION_COMMIT_RETRIES) \
- goto transaction_start_label; \
- TALER_LOG_WARNING ("Transaction commit failed %u times in %s\n", \
- transaction_retries, \
- __FUNCTION__); \
- return TEH_RESPONSE_reply_commit_error (connection, \
- TALER_EC_DB_COMMIT_FAILED_ON_RETRY); \
- } while (0)
-
-
-
-
-
-/**
* Send a response for "/refresh/reveal".
*
* @param connection the connection to send the response to
@@ -133,14 +44,15 @@ reply_refresh_reveal_success (struct MHD_Connection *connection,
unsigned int num_newcoins,
const struct TALER_DenominationSignature *sigs)
{
- int newcoin_index;
json_t *root;
json_t *obj;
json_t *list;
int ret;
list = json_array ();
- for (newcoin_index = 0; newcoin_index < num_newcoins; newcoin_index++)
+ for (unsigned int newcoin_index = 0;
+ newcoin_index < num_newcoins;
+ newcoin_index++)
{
obj = json_object ();
json_object_set_new (obj,
@@ -182,11 +94,10 @@ reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
{
json_t *info_new;
json_t *info_commit_k;
- unsigned int i;
info_new = json_array ();
info_commit_k = json_array ();
- for (i=0;i<session->num_newcoins;i++)
+ for (unsigned int i=0;i<session->num_newcoins;i++)
{
const struct TALER_EXCHANGEDB_RefreshCommitCoin *cc;
json_t *cc_json;
@@ -220,7 +131,6 @@ reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
}
-
/**
* Check if the given @a transfer_privs correspond to an honest
* commitment for the given session.
@@ -253,14 +163,13 @@ check_commitment (struct MHD_Connection *connection,
struct GNUNET_HashContext *hash_context)
{
struct TALER_TransferSecretP transfer_secret;
- unsigned int j;
TALER_link_reveal_transfer_secret (transfer_priv,
&melt->coin.coin_pub,
&transfer_secret);
/* Check that the commitments for all new coins were correct */
- for (j = 0; j < num_newcoins; j++)
+ for (unsigned int j = 0; j < num_newcoins; j++)
{
struct TALER_FreshCoinP fc;
struct TALER_CoinSpendPublicKeyP coin_pub;
@@ -301,6 +210,58 @@ check_commitment (struct MHD_Connection *connection,
/**
+ * State for a /refresh/reveal operation.
+ */
+struct RevealContext
+{
+
+ /**
+ * Hash of the refresh session.
+ */
+ const struct GNUNET_HashCode *session_hash;
+
+ /**
+ * Database session used to execute the transaction.
+ */
+ struct TALER_EXCHANGEDB_Session *session;
+
+ /**
+ * Session state from the database.
+ */
+ struct TALER_EXCHANGEDB_RefreshSession refresh_session;
+
+ /**
+ * Array of denomination public keys used for the refresh.
+ */
+ struct TALER_DenominationPublicKey *denom_pubs;
+
+ /**
+ * Envelopes with the signatures to be returned.
+ */
+ struct TALER_DenominationSignature *ev_sigs;
+
+ /**
+ * Commitment data from the DB giving data about original
+ * commitments, in particular the blinded envelopes (for
+ * index gamma).
+ */
+ struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins;
+
+ /**
+ * Transfer public key associated with the gamma value
+ * selected by the exchange.
+ */
+ struct TALER_TransferPublicKeyP gamma_tp;
+
+ /**
+ * Transfer private keys revealed to us.
+ */
+ struct TALER_TransferPrivateKeyP transfer_privs[TALER_CNC_KAPPA - 1];
+
+};
+
+
+/**
* Exchange a coin as part of a refresh operation. Obtains the
* envelope from the database and performs the signing operation.
*
@@ -311,19 +272,21 @@ check_commitment (struct MHD_Connection *connection,
* @param denom_pub denomination key for the coin to create
* @param commit_coin the coin that was committed
* @param coin_off number of the coin
- * @return NULL on error, otherwise signature over the coin
+ * @param[out] ev_sig set to signature over the coin upon success
+ * @return database transaction status
*/
-static struct TALER_DenominationSignature
+static enum GNUNET_DB_QueryStatus
refresh_exchange_coin (struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
struct TEH_KS_StateHandle *key_state,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coin,
- unsigned int coin_off)
+ unsigned int coin_off,
+ struct TALER_DenominationSignature *ev_sig)
{
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
- struct TALER_DenominationSignature ev_sig;
+ enum GNUNET_DB_QueryStatus qs;
dki = TEH_KS_denomination_key_lookup (key_state,
denom_pub,
@@ -331,105 +294,91 @@ refresh_exchange_coin (struct MHD_Connection *connection,
if (NULL == dki)
{
GNUNET_break (0);
- ev_sig.rsa_signature = NULL;
- return ev_sig;
+ ev_sig->rsa_signature = NULL;
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
- if (GNUNET_OK ==
- TEH_plugin->get_refresh_out (TEH_plugin->cls,
- session,
- session_hash,
- coin_off,
- &ev_sig))
+ qs = TEH_plugin->get_refresh_out (TEH_plugin->cls,
+ session,
+ session_hash,
+ coin_off,
+ ev_sig);
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Returning cached reply for /refresh/reveal signature\n");
- return ev_sig;
+ return qs;
}
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs)
+ return qs;
- ev_sig.rsa_signature
+ ev_sig->rsa_signature
= GNUNET_CRYPTO_rsa_sign_blinded (dki->denom_priv.rsa_private_key,
commit_coin->coin_ev,
commit_coin->coin_ev_size);
- if (NULL == ev_sig.rsa_signature)
+ if (NULL == ev_sig->rsa_signature)
{
GNUNET_break (0);
- return ev_sig;
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
- if (GNUNET_SYSERR ==
- TEH_plugin->insert_refresh_out (TEH_plugin->cls,
- session,
- session_hash,
- coin_off,
- &ev_sig))
+ qs = TEH_plugin->insert_refresh_out (TEH_plugin->cls,
+ session,
+ session_hash,
+ coin_off,
+ ev_sig);
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
- GNUNET_break (0);
- GNUNET_CRYPTO_rsa_signature_free (ev_sig.rsa_signature);
- ev_sig.rsa_signature = NULL;
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ if (NULL != ev_sig->rsa_signature)
+ {
+ GNUNET_CRYPTO_rsa_signature_free (ev_sig->rsa_signature);
+ ev_sig->rsa_signature = NULL;
+ }
}
-
- return ev_sig;
+ return qs;
}
/**
- * The client request was well-formed, now execute the DB transaction
- * of a "/refresh/reveal" operation. We use the @a ev_sigs and
- * @a commit_coins to clean up resources after this function returns
- * as we might experience retries of the database transaction.
+ * Cleanup state of the transaction stored in @a rc.
*
- * @param connection the MHD connection to handle
- * @param session database session
- * @param session_hash hash identifying the refresh session
- * @param refresh_session information about the refresh operation we are doing
- * @param denom_pubs array of "num_newcoins" denomination keys for the new coins
- * @param[out] ev_sigs where to store generated signatures for the new coins,
- * array of length "num_newcoins", memory released by the
- * caller
- * @param[out] commit_coins array of length "num_newcoins" to be used for
- * information about the new coins from the commitment.
- * @return MHD result code
+ * @param rc context to clean up
*/
-static int
-execute_refresh_reveal_transaction (struct MHD_Connection *connection,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *session_hash,
- const struct TALER_EXCHANGEDB_RefreshSession *refresh_session,
- const struct TALER_DenominationPublicKey *denom_pubs,
- struct TALER_DenominationSignature *ev_sigs,
- struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins)
+static void
+cleanup_rc (struct RevealContext *rc)
{
- unsigned int j;
- struct TEH_KS_StateHandle *key_state;
- int ret;
-
- START_TRANSACTION (session, connection);
- key_state = TEH_KS_acquire ();
- for (j=0;j<refresh_session->num_newcoins;j++)
+ if (NULL != rc->denom_pubs)
{
- if (NULL == ev_sigs[j].rsa_signature) /* could be non-NULL during retries */
- ev_sigs[j] = refresh_exchange_coin (connection,
- session,
- session_hash,
- key_state,
- &denom_pubs[j],
- &commit_coins[j],
- j);
- if (NULL == ev_sigs[j].rsa_signature)
- {
- TEH_plugin->rollback (TEH_plugin->cls,
- session);
- ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_SIGNING_ERROR);
- goto cleanup;
- }
+ for (unsigned int i=0;i<rc->refresh_session.num_newcoins;i++)
+ if (NULL != rc->denom_pubs[i].rsa_public_key)
+ GNUNET_CRYPTO_rsa_public_key_free (rc->denom_pubs[i].rsa_public_key);
+ GNUNET_free (rc->denom_pubs);
+ rc->denom_pubs = NULL;
+ }
+ if (NULL != rc->commit_coins)
+ {
+ for (unsigned int j=0;j<rc->refresh_session.num_newcoins;j++)
+ GNUNET_free_non_null (rc->commit_coins[j].coin_ev);
+ GNUNET_free (rc->commit_coins);
+ rc->commit_coins = NULL;
+ }
+ if (NULL != rc->ev_sigs)
+ {
+ for (unsigned int j=0;j<rc->refresh_session.num_newcoins;j++)
+ if (NULL != rc->ev_sigs[j].rsa_signature)
+ GNUNET_CRYPTO_rsa_signature_free (rc->ev_sigs[j].rsa_signature);
+ GNUNET_free (rc->ev_sigs);
+ rc->ev_sigs = NULL;
+ }
+ if (NULL != rc->refresh_session.melt.coin.denom_sig.rsa_signature)
+ {
+ GNUNET_CRYPTO_rsa_signature_free (rc->refresh_session.melt.coin.denom_sig.rsa_signature);
+ rc->refresh_session.melt.coin.denom_sig.rsa_signature = NULL;
+ }
+ if (NULL != rc->refresh_session.melt.coin.denom_pub.rsa_public_key)
+ {
+ GNUNET_CRYPTO_rsa_public_key_free (rc->refresh_session.melt.coin.denom_pub.rsa_public_key);
+ rc->refresh_session.melt.coin.denom_pub.rsa_public_key = NULL;
}
- COMMIT_TRANSACTION (session, connection);
- ret = reply_refresh_reveal_success (connection,
- refresh_session->num_newcoins,
- ev_sigs);
- cleanup:
- TEH_KS_release (key_state);
- return ret;
}
@@ -440,94 +389,98 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection,
* and if so, return the signed coins for corresponding to the set of
* coins that was not chosen.
*
- * @param connection the MHD connection to handle
- * @param session_hash hash identifying the refresh session
- * @param transfer_privs array with the revealed transfer keys,
- * length must be #TALER_CNC_KAPPA - 1
- * @return MHD result code
+ * 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 closure of type `struct RevealContext`
+ * @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
*/
-static int
-execute_refresh_reveal (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- struct TALER_TransferPrivateKeyP *transfer_privs)
+static enum GNUNET_DB_QueryStatus
+refresh_reveal_transaction (void *cls,
+ struct MHD_Connection *connection,
+ struct TALER_EXCHANGEDB_Session *session,
+ int *mhd_ret)
{
- int res;
- struct TALER_EXCHANGEDB_Session *session;
- struct TALER_EXCHANGEDB_RefreshSession refresh_session;
- struct TALER_DenominationPublicKey *denom_pubs;
- struct TALER_DenominationSignature *ev_sigs;
- struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins;
- unsigned int i;
- unsigned int j;
+ struct RevealContext *rc = cls;
unsigned int off;
struct GNUNET_HashContext *hash_context;
struct GNUNET_HashCode sh_check;
- int ret;
- struct TALER_TransferPublicKeyP gamma_tp;
-
- if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
+ enum GNUNET_DB_QueryStatus qs;
+
+ rc->session = session;
+ qs = TEH_plugin->get_refresh_session (TEH_plugin->cls,
+ session,
+ rc->session_hash,
+ &rc->refresh_session);
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ *mhd_ret = TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
+ "session_hash");
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ return qs;
+ if ( (GNUNET_DB_STATUS_HARD_ERROR == qs) ||
+ (rc->refresh_session.noreveal_index >= TALER_CNC_KAPPA) )
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DB_SETUP_FAILED);
+ cleanup_rc (rc);
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR);
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
-
- res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
- session,
- session_hash,
- &refresh_session);
- if (GNUNET_NO == res)
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
- "session_hash");
- if ( (GNUNET_SYSERR == res) ||
- (refresh_session.noreveal_index >= TALER_CNC_KAPPA) )
- return TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR);
- denom_pubs = GNUNET_new_array (refresh_session.num_newcoins,
- struct TALER_DenominationPublicKey);
- if (GNUNET_OK !=
- TEH_plugin->get_refresh_order (TEH_plugin->cls,
- session,
- session_hash,
- refresh_session.num_newcoins,
- denom_pubs))
+ rc->denom_pubs = GNUNET_new_array (rc->refresh_session.num_newcoins,
+ struct TALER_DenominationPublicKey);
+ qs = TEH_plugin->get_refresh_order (TEH_plugin->cls,
+ session,
+ rc->session_hash,
+ rc->refresh_session.num_newcoins,
+ rc->denom_pubs);
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
+ cleanup_rc (rc);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ return qs;
GNUNET_break (0);
- GNUNET_free (denom_pubs);
- GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
- GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR))
- ? GNUNET_NO : GNUNET_SYSERR;
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR);
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
hash_context = GNUNET_CRYPTO_hash_context_start ();
/* first, iterate over transfer public keys for hash_context */
off = 0;
- for (i=0;i<TALER_CNC_KAPPA;i++)
+ for (unsigned int i=0;i<TALER_CNC_KAPPA;i++)
{
- if (i == refresh_session.noreveal_index)
+ if (i == rc->refresh_session.noreveal_index)
{
off = 1;
/* obtain gamma_tp from db */
- if (GNUNET_OK !=
- TEH_plugin->get_refresh_transfer_public_key (TEH_plugin->cls,
- session,
- session_hash,
- &gamma_tp))
+ qs = TEH_plugin->get_refresh_transfer_public_key (TEH_plugin->cls,
+ session,
+ rc->session_hash,
+ &rc->gamma_tp);
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
- GNUNET_break (0);
- GNUNET_free (denom_pubs);
- GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
- GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR))
- ? GNUNET_NO : GNUNET_SYSERR;
+ cleanup_rc (rc);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ return qs;
+ GNUNET_break (0);
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR);
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
GNUNET_CRYPTO_hash_context_read (hash_context,
- &gamma_tp,
+ &rc->gamma_tp,
sizeof (struct TALER_TransferPublicKeyP));
}
else
@@ -535,7 +488,7 @@ execute_refresh_reveal (struct MHD_Connection *connection,
/* compute tp from private key */
struct TALER_TransferPublicKeyP tp;
- GNUNET_CRYPTO_ecdhe_key_get_public (&transfer_privs[i - off].ecdhe_priv,
+ GNUNET_CRYPTO_ecdhe_key_get_public (&rc->transfer_privs[i - off].ecdhe_priv,
&tp.ecdhe_pub);
GNUNET_CRYPTO_hash_context_read (hash_context,
&tp,
@@ -545,38 +498,17 @@ execute_refresh_reveal (struct MHD_Connection *connection,
/* next, add all of the hashes from the denomination keys to the
hash_context */
+ for (unsigned int i=0;i<rc->refresh_session.num_newcoins;i++)
{
- struct TALER_DenominationPublicKey denom_pubs[refresh_session.num_newcoins];
-
- if (GNUNET_OK !=
- TEH_plugin->get_refresh_order (TEH_plugin->cls,
- session,
- session_hash,
- refresh_session.num_newcoins,
- denom_pubs))
- {
- GNUNET_break (0);
- GNUNET_free (denom_pubs);
- GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
- GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
- GNUNET_CRYPTO_hash_context_abort (hash_context);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
- for (i=0;i<refresh_session.num_newcoins;i++)
- {
- char *buf;
- size_t buf_size;
+ char *buf;
+ size_t buf_size;
- buf_size = GNUNET_CRYPTO_rsa_public_key_encode (denom_pubs[i].rsa_public_key,
- &buf);
- GNUNET_CRYPTO_hash_context_read (hash_context,
- buf,
- buf_size);
- GNUNET_free (buf);
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[i].rsa_public_key);
- }
+ buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rc->denom_pubs[i].rsa_public_key,
+ &buf);
+ GNUNET_CRYPTO_hash_context_read (hash_context,
+ buf,
+ buf_size);
+ GNUNET_free (buf);
}
/* next, add public key of coin and amount being refreshed */
@@ -584,71 +516,67 @@ execute_refresh_reveal (struct MHD_Connection *connection,
struct TALER_AmountNBO melt_amountn;
GNUNET_CRYPTO_hash_context_read (hash_context,
- &refresh_session.melt.coin.coin_pub,
+ &rc->refresh_session.melt.coin.coin_pub,
sizeof (struct TALER_CoinSpendPublicKeyP));
TALER_amount_hton (&melt_amountn,
- &refresh_session.melt.amount_with_fee);
+ &rc->refresh_session.melt.amount_with_fee);
GNUNET_CRYPTO_hash_context_read (hash_context,
&melt_amountn,
sizeof (struct TALER_AmountNBO));
}
- commit_coins = GNUNET_new_array (refresh_session.num_newcoins,
- struct TALER_EXCHANGEDB_RefreshCommitCoin);
+ rc->commit_coins = GNUNET_new_array (rc->refresh_session.num_newcoins,
+ struct TALER_EXCHANGEDB_RefreshCommitCoin);
off = 0;
- for (i=0;i<TALER_CNC_KAPPA;i++)
+ for (unsigned int i=0;i<TALER_CNC_KAPPA;i++)
{
- if (i == refresh_session.noreveal_index)
+ int res;
+
+ if (i == rc->refresh_session.noreveal_index)
{
off = 1;
/* obtain commit_coins for the selected gamma value from DB */
- if (GNUNET_OK !=
- TEH_plugin->get_refresh_commit_coins (TEH_plugin->cls,
- session,
- session_hash,
- refresh_session.num_newcoins,
- commit_coins))
- {
- GNUNET_break (0);
- GNUNET_free (denom_pubs);
- GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
- GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
+ qs = TEH_plugin->get_refresh_commit_coins (TEH_plugin->cls,
+ session,
+ rc->session_hash,
+ rc->refresh_session.num_newcoins,
+ rc->commit_coins);
+ if (0 >= qs)
+ {
+ cleanup_rc (rc);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ return qs;
+ GNUNET_break (0);
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR);
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
/* add envelopes to hash_context */
- for (j=0;j<refresh_session.num_newcoins;j++)
+ for (unsigned int j=0;j<rc->refresh_session.num_newcoins;j++)
{
GNUNET_CRYPTO_hash_context_read (hash_context,
- commit_coins[j].coin_ev,
- commit_coins[j].coin_ev_size);
+ rc->commit_coins[j].coin_ev,
+ rc->commit_coins[j].coin_ev_size);
}
continue;
}
if (GNUNET_OK !=
(res = check_commitment (connection,
session,
- session_hash,
+ rc->session_hash,
i,
- &transfer_privs[i - off],
- &refresh_session.melt,
- refresh_session.num_newcoins,
- denom_pubs,
+ &rc->transfer_privs[i - off],
+ &rc->refresh_session.melt,
+ rc->refresh_session.num_newcoins,
+ rc->denom_pubs,
hash_context)))
{
GNUNET_break_op (0);
- for (j=0;j<refresh_session.num_newcoins;j++)
- {
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (commit_coins[j].coin_ev);
- }
- GNUNET_free (commit_coins);
- GNUNET_free (denom_pubs);
- GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
- GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
+ cleanup_rc (rc);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ *mhd_ret = (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
}
@@ -656,56 +584,53 @@ execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_CRYPTO_hash_context_finish (hash_context,
&sh_check);
if (0 != memcmp (&sh_check,
- session_hash,
+ rc->session_hash,
sizeof (struct GNUNET_HashCode)))
{
GNUNET_break_op (0);
- ret = reply_refresh_reveal_missmatch (connection,
- &refresh_session,
- commit_coins,
- denom_pubs,
- &gamma_tp);
- for (j=0;j<refresh_session.num_newcoins;j++)
+ *mhd_ret = reply_refresh_reveal_missmatch (connection,
+ &rc->refresh_session,
+ rc->commit_coins,
+ rc->denom_pubs,
+ &rc->gamma_tp);
+ cleanup_rc (rc);
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+
+ /* Client request OK, sign coins */
+ rc->ev_sigs = GNUNET_new_array (rc->refresh_session.num_newcoins,
+ struct TALER_DenominationSignature);
+ {
+ struct TEH_KS_StateHandle *key_state;
+
+ key_state = TEH_KS_acquire ();
+ for (unsigned int j=0;j<rc->refresh_session.num_newcoins;j++)
{
- GNUNET_free (commit_coins[j].coin_ev);
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
+ qs = refresh_exchange_coin (connection,
+ session,
+ rc->session_hash,
+ key_state,
+ &rc->denom_pubs[j],
+ &rc->commit_coins[j],
+ j,
+ &rc->ev_sigs[j]);
+ if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) ||
+ (NULL == rc->ev_sigs[j].rsa_signature) )
+ {
+ *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_SIGNING_ERROR);
+ qs = GNUNET_DB_STATUS_HARD_ERROR;
+ break;
+ }
}
- GNUNET_free (commit_coins);
- GNUNET_free (denom_pubs);
- GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
- GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
-
- return ret;
+ TEH_KS_release (key_state);
}
-
- /* Client request OK, start transaction */
- ev_sigs = GNUNET_new_array (refresh_session.num_newcoins,
- struct TALER_DenominationSignature);
-
- /* FIXME: might need to store revealed transfer private keys for
- the auditor for later; should pass them as arguments here! #4792*/
- res = execute_refresh_reveal_transaction (connection,
- session,
- session_hash,
- &refresh_session,
- denom_pubs,
- ev_sigs,
- commit_coins);
- for (i=0;i<refresh_session.num_newcoins;i++)
+ if (0 >= qs)
{
- if (NULL != ev_sigs[i].rsa_signature)
- GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i].rsa_signature);
- GNUNET_free (commit_coins[i].coin_ev);
+ cleanup_rc (rc);
+ return qs;
}
- for (j=0;j<refresh_session.num_newcoins;j++)
- if (NULL != denom_pubs[j].rsa_public_key)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
- GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
- GNUNET_free (ev_sigs);
- GNUNET_free (denom_pubs);
- GNUNET_free (commit_coins);
- return res;
+ return qs;
}
@@ -726,37 +651,47 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
const struct GNUNET_HashCode *session_hash,
const json_t *tp_json)
{
- struct TALER_TransferPrivateKeyP transfer_privs[TALER_CNC_KAPPA - 1];
- unsigned int i;
- int res;
+ struct RevealContext rc;
+ int mhd_ret;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"reveal request for session %s\n",
GNUNET_h2s (session_hash));
-
- res = GNUNET_OK;
- for (i = 0; i < TALER_CNC_KAPPA - 1; i++)
+ memset (&rc,
+ 0,
+ sizeof (rc));
+ rc.session_hash = session_hash;
+ for (unsigned int i = 0; i < TALER_CNC_KAPPA - 1; i++)
{
struct GNUNET_JSON_Specification tp_spec[] = {
- GNUNET_JSON_spec_fixed_auto (NULL, &transfer_privs[i]),
+ GNUNET_JSON_spec_fixed_auto (NULL, &rc.transfer_privs[i]),
GNUNET_JSON_spec_end ()
};
+ int res;
- if (GNUNET_OK != res)
- break;
res = TEH_PARSE_json_array (connection,
tp_json,
tp_spec,
- i, -1);
+ i,
+ -1);
GNUNET_break_op (GNUNET_OK == res);
+ if (GNUNET_OK != res)
+ return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
}
- if (GNUNET_OK != res)
- res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- else
- res = execute_refresh_reveal (connection,
- session_hash,
- transfer_privs);
- return res;
+ if (GNUNET_OK !=
+ TEH_DB_run_transaction (connection,
+ &mhd_ret,
+ &refresh_reveal_transaction,
+ &rc))
+ {
+ cleanup_rc (&rc);
+ return mhd_ret;
+ }
+ mhd_ret = reply_refresh_reveal_success (connection,
+ rc.refresh_session.num_newcoins,
+ rc.ev_sigs);
+ cleanup_rc (&rc);
+ return mhd_ret;
}
@@ -800,7 +735,8 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
&root);
if (GNUNET_SYSERR == res)
return MHD_NO;
- if ( (GNUNET_NO == res) || (NULL == root) )
+ if ( (GNUNET_NO == res) ||
+ (NULL == root) )
return MHD_YES;
res = TEH_PARSE_json_data (connection,
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index b11eec16d..592751f66 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -3099,6 +3099,7 @@ postgres_iterate_matching_deposits (void *cls,
* if upon succesfullying retrieving the record data info @a
* coin_info
*/
+// FIXME: #5010
static int
get_known_coin (void *cls,
struct TALER_EXCHANGEDB_Session *session,
@@ -3284,88 +3285,55 @@ postgres_insert_refund (void *cls,
* @param cls the `struct PostgresClosure` with the plugin-specific state
* @param session database handle to use
* @param session_hash hash over the melt to use to locate the session
- * @param[out] refresh_session where to store the result, can be NULL
- * to just check if the session exists
- * @return #GNUNET_YES on success,
- * #GNUNET_NO if not found,
- * #GNUNET_SYSERR on DB failure
+ * @param[out] refresh_session where to store the result
+ * @return transaction status
*/
-static int
+static enum GNUNET_DB_QueryStatus
postgres_get_refresh_session (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
struct TALER_EXCHANGEDB_RefreshSession *refresh_session)
{
- PGresult *result;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (session_hash),
GNUNET_PQ_query_param_end
};
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint16 ("num_newcoins",
+ &refresh_session->num_newcoins),
+ GNUNET_PQ_result_spec_uint16 ("noreveal_index",
+ &refresh_session->noreveal_index),
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
+ &refresh_session->melt.coin.coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
+ &refresh_session->melt.coin_sig),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &refresh_session->melt.amount_with_fee),
+ TALER_PQ_result_spec_amount ("fee_refresh",
+ &refresh_session->melt.melt_fee),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
- result = GNUNET_PQ_exec_prepared (session->conn,
- "get_refresh_session",
- params);
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- BREAK_DB_ERR (result, session->conn);
- PQclear (result);
- return GNUNET_SYSERR;
- }
- if (0 == PQntuples (result))
- {
- PQclear (result);
- return GNUNET_NO;
- }
- GNUNET_assert (1 == PQntuples (result));
- if (NULL == refresh_session)
- {
- /* We're done if the caller is only interested in whether the
- * session exists or not */
- PQclear (result);
- return GNUNET_YES;
- }
memset (refresh_session,
0,
sizeof (struct TALER_EXCHANGEDB_RefreshSession));
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint16 ("num_newcoins",
- &refresh_session->num_newcoins),
- GNUNET_PQ_result_spec_uint16 ("noreveal_index",
- &refresh_session->noreveal_index),
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
- &refresh_session->melt.coin.coin_pub),
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
- &refresh_session->melt.coin_sig),
- TALER_PQ_result_spec_amount ("amount_with_fee",
- &refresh_session->melt.amount_with_fee),
- TALER_PQ_result_spec_amount ("fee_refresh",
- &refresh_session->melt.melt_fee),
- 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);
- if (GNUNET_OK !=
- get_known_coin (cls,
- session,
- &refresh_session->melt.coin.coin_pub,
- &refresh_session->melt.coin))
+ qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+ "get_refresh_session",
+ params,
+ rs);
+ if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) &&
+ (GNUNET_OK !=
+ get_known_coin (cls,
+ session,
+ &refresh_session->melt.coin.coin_pub,
+ &refresh_session->melt.coin)) )
{
GNUNET_break (0);
- return GNUNET_SYSERR;
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
refresh_session->melt.session_hash = *session_hash;
- return GNUNET_YES;
+ return qs;
}
@@ -3501,69 +3469,49 @@ free_dpk_result (struct TALER_DenominationPublicKey *denom_pubs,
* @param session_hash hash to identify refresh session
* @param num_newcoins size of the array of the @a denom_pubs array
* @param denom_pubs where to store the deomination keys
- * @return #GNUNET_OK on success
- * #GNUNET_SYSERR on internal error
+ * @return transaction status
*/
-static int
+static enum GNUNET_DB_QueryStatus
postgres_get_refresh_order (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t num_newcoins,
struct TALER_DenominationPublicKey *denom_pubs)
-{
- unsigned int i;
-
- for (i=0;i<(unsigned int) num_newcoins;i++)
+{
+ for (unsigned i=0;i<(unsigned int) num_newcoins;i++)
{
uint16_t newcoin_off = (uint16_t) i;
- PGresult *result;
-
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (session_hash),
- GNUNET_PQ_query_param_uint16 (&newcoin_off),
- GNUNET_PQ_query_param_end
- };
-
- result = GNUNET_PQ_exec_prepared (session->conn,
- "get_refresh_order",
- params);
- }
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- BREAK_DB_ERR (result, session->conn);
- PQclear (result);
- free_dpk_result (denom_pubs, i);
- return GNUNET_SYSERR;
- }
- if (0 == PQntuples (result))
+ enum GNUNET_DB_QueryStatus qs;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (session_hash),
+ GNUNET_PQ_query_param_uint16 (&newcoin_off),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+ &denom_pubs[i].rsa_public_key),
+ GNUNET_PQ_result_spec_end
+ };
+
+ qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+ "get_refresh_order",
+ params,
+ rs);
+ switch (qs)
{
- PQclear (result);
- /* FIXME: may want to distinguish between different error cases! */
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
free_dpk_result (denom_pubs, i);
- return GNUNET_SYSERR;
- }
- GNUNET_assert (1 == PQntuples (result));
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
- &denom_pubs[i].rsa_public_key),
- GNUNET_PQ_result_spec_end
- };
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- 0))
- {
- PQclear (result);
- GNUNET_break (0);
- free_dpk_result (denom_pubs, i);
- return GNUNET_SYSERR;
- }
- PQclear (result);
+ return qs;
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+ break;
+ default:
+ GNUNET_break (0);
+ break;
}
}
- return GNUNET_OK;
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
@@ -3639,11 +3587,9 @@ postgres_free_refresh_commit_coins (void *cls,
* @param session_hash hash to identify refresh session
* @param num_newcoins size of the @a commit_coins array
* @param[out] commit_coins array of coin commitments to return
- * @return #GNUNET_OK on success
- * #GNUNET_NO if not found
- * #GNUNET_SYSERR on error
+ * @return transaction status
*/
-static int
+static enum GNUNET_DB_QueryStatus
postgres_get_refresh_commit_coins (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
@@ -3660,53 +3606,29 @@ postgres_get_refresh_commit_coins (void *cls,
};
void *c_buf;
size_t c_buf_size;
- PGresult *result;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_variable_size ("coin_ev",
+ &c_buf,
+ &c_buf_size),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
- result = GNUNET_PQ_exec_prepared (session->conn,
- "get_refresh_commit_coin",
- params);
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- BREAK_DB_ERR (result, session->conn);
- PQclear (result);
- postgres_free_refresh_commit_coins (cls,
- i,
- commit_coins);
- return GNUNET_SYSERR;
- }
- if (0 == PQntuples (result))
+ qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+ "get_refresh_commit_coin",
+ params,
+ rs);
+ if (0 >= qs)
{
- PQclear (result);
postgres_free_refresh_commit_coins (cls,
i,
commit_coins);
- return GNUNET_NO;
- }
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_variable_size ("coin_ev",
- &c_buf,
- &c_buf_size),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_YES !=
- GNUNET_PQ_extract_result (result,
- rs,
- 0))
- {
- PQclear (result);
- postgres_free_refresh_commit_coins (cls,
- i,
- commit_coins);
- return GNUNET_SYSERR;
- }
+ return qs;
}
- PQclear (result);
commit_coins[i].coin_ev = c_buf;
commit_coins[i].coin_ev_size = c_buf_size;
}
- return GNUNET_YES;
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
@@ -3748,11 +3670,9 @@ postgres_insert_refresh_transfer_public_key (void *cls,
* @param session database connection to use
* @param session_hash hash to identify refresh session
* @param[out] tp information to return
- * @return #GNUNET_SYSERR on internal error,
- * #GNUNET_NO if commitment was not found
- * #GNUNET_OK on success
+ * @return transaction status
*/
-static int
+static enum GNUNET_DB_QueryStatus
postgres_get_refresh_transfer_public_key (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
@@ -3762,40 +3682,16 @@ postgres_get_refresh_transfer_public_key (void *cls,
GNUNET_PQ_query_param_auto_from_type (session_hash),
GNUNET_PQ_query_param_end
};
- PGresult *result;
-
- result = GNUNET_PQ_exec_prepared (session->conn,
- "get_refresh_transfer_public_key",
- params);
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- BREAK_DB_ERR (result, session->conn);
- PQclear (result);
- return GNUNET_SYSERR;
- }
- if (0 == PQntuples (result))
- {
- PQclear (result);
- return GNUNET_NO;
- }
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
- tp),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_YES !=
- GNUNET_PQ_extract_result (result,
- rs,
- 0))
- {
- PQclear (result);
- return GNUNET_SYSERR;
- }
- }
- PQclear (result);
- return GNUNET_OK;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
+ tp),
+ GNUNET_PQ_result_spec_end
+ };
+
+ return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+ "get_refresh_transfer_public_key",
+ params,
+ rs);
}
@@ -3809,17 +3705,15 @@ postgres_get_refresh_transfer_public_key (void *cls,
* @param session_hash hash to identify refresh session
* @param newcoin_index coin index
* @param ev_sig coin signature
- * @return #GNUNET_OK on success, #GNUNET_NO if we have no such result
- * #GNUNET_SYSERR on error
+ * @return transaction result status
*/
-static int
+static enum GNUNET_DB_QueryStatus
postgres_get_refresh_out (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
uint16_t newcoin_index,
struct TALER_DenominationSignature *ev_sig)
{
- PGresult *result;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (session_hash),
GNUNET_PQ_query_param_uint16 (&newcoin_index),
@@ -3831,31 +3725,10 @@ postgres_get_refresh_out (void *cls,
GNUNET_PQ_result_spec_end
};
- result = GNUNET_PQ_exec_prepared (session->conn,
- "get_refresh_out",
- params);
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- BREAK_DB_ERR (result, session->conn);
- PQclear (result);
- return GNUNET_SYSERR;
- }
- if (1 != PQntuples (result))
- {
- PQclear (result);
- return GNUNET_NO;
- }
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- 0))
- {
- PQclear (result);
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- PQclear (result);
- return GNUNET_OK;
+ return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+ "get_refresh_out",
+ params,
+ rs);
}
@@ -3870,11 +3743,9 @@ postgres_get_refresh_out (void *cls,
* @param session_hash hash to identify refresh session
* @param newcoin_index coin index
* @param ev_sig coin signature
- * @return #GNUNET_OK on success
- * #GNUNET_NO on transient error
- * #GNUNET_SYSERR on error
+ * @return transaction result status
*/
-static int
+static enum GNUNET_DB_QueryStatus
postgres_insert_refresh_out (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
@@ -3888,9 +3759,9 @@ postgres_insert_refresh_out (void *cls,
GNUNET_PQ_query_param_end
};
- return execute_prepared_non_select (session,
- "insert_refresh_out",
- params);
+ return GNUNET_PQ_eval_prepared_non_select (session->conn,
+ "insert_refresh_out",
+ params);
}
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index df730a07e..673d51446 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -357,7 +357,7 @@ test_refresh_commit_coins (struct TALER_EXCHANGEDB_Session *session,
commit_coins));
ret_commit_coins = GNUNET_new_array (MELT_NEW_COINS,
struct TALER_EXCHANGEDB_RefreshCommitCoin);
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_refresh_commit_coins (plugin->cls,
session,
session_hash,
@@ -410,7 +410,7 @@ test_refresh_commit_links (struct TALER_EXCHANGEDB_Session *session,
unsigned int i;
ret = GNUNET_SYSERR;
- FAILIF (GNUNET_NO !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
plugin->get_refresh_transfer_public_key (plugin->cls,
session,
session_hash,
@@ -422,7 +422,7 @@ test_refresh_commit_links (struct TALER_EXCHANGEDB_Session *session,
session,
session_hash,
&rctp[MELT_NOREVEAL_INDEX]));
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_refresh_transfer_public_key (plugin->cls,
session,
session_hash,
@@ -572,21 +572,24 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
meltp->melt_fee = fee_refresh;
}
- FAILIF (GNUNET_OK != plugin->create_refresh_session (plugin->cls,
- session,
- &session_hash,
- &refresh_session));
- FAILIF (GNUNET_OK != plugin->get_refresh_session (plugin->cls,
- session,
- &session_hash,
- &ret_refresh_session));
+ FAILIF (GNUNET_OK !=
+ plugin->create_refresh_session (plugin->cls,
+ session,
+ &session_hash,
+ &refresh_session));
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+ plugin->get_refresh_session (plugin->cls,
+ session,
+ &session_hash,
+ &ret_refresh_session));
auditor_row_cnt = 0;
- FAILIF (GNUNET_OK != plugin->select_refreshs_above_serial_id (plugin->cls,
- session,
- 0,
- &audit_refresh_session_cb,
- NULL));
+ FAILIF (GNUNET_OK !=
+ plugin->select_refreshs_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_refresh_session_cb,
+ NULL));
FAILIF (1 != auditor_row_cnt);
FAILIF (ret_refresh_session.num_newcoins != refresh_session.num_newcoins);
FAILIF (ret_refresh_session.noreveal_index != refresh_session.noreveal_index);
@@ -633,7 +636,7 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
&fee_refund);
new_denom_pubs[cnt] = new_dkp[cnt]->pub;
}
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->insert_refresh_order (plugin->cls,
session,
&session_hash,
@@ -641,7 +644,7 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
new_denom_pubs));
ret_denom_pubs = GNUNET_new_array (MELT_NEW_COINS,
struct TALER_DenominationPublicKey);
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_refresh_order (plugin->cls,
session,
&session_hash,
@@ -672,19 +675,19 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
= GNUNET_CRYPTO_rsa_sign_fdh (new_dkp[cnt]->priv.rsa_private_key,
&hc);
GNUNET_assert (NULL != ev_sigs[cnt].rsa_signature);
- FAILIF (GNUNET_NO !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
plugin->get_refresh_out (plugin->cls,
session,
&session_hash,
cnt,
&test_sig));
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->insert_refresh_out (plugin->cls,
session,
&session_hash,
cnt,
&ev_sigs[cnt]));
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_refresh_out (plugin->cls,
session,
&session_hash,
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 0406c8d19..9fe0874bd 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1441,11 +1441,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param session database handle to use
* @param session_hash hash over the melt to use for the lookup
* @param[out] refresh_session where to store the result
- * @return #GNUNET_YES on success,
- * #GNUNET_NO if not found,
- * #GNUNET_SYSERR on DB failure
+ * @return transaction status
*/
- int
+ enum GNUNET_DB_QueryStatus
(*get_refresh_session) (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
@@ -1500,10 +1498,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param session_hash hash to identify refresh session
* @param num_newcoins size of the @a denom_pubs array
* @param[out] denom_pubs where to write @a num_newcoins denomination keys
- * @return #GNUNET_OK on success
- * #GNUNET_SYSERR on internal error
+ * @return transaction status
*/
- int
+ enum GNUNET_DB_QueryStatus
(*get_refresh_order) (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
@@ -1541,11 +1538,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param session_hash hash to identify refresh session
* @param num_coins size of the @a commit_coins array
* @param[out] commit_coins array of coin commitments to return
- * @return #GNUNET_OK on success
- * #GNUNET_NO if not found
- * #GNUNET_SYSERR on error
+ * @return transaction status
*/
- int
+ enum GNUNET_DB_QueryStatus
(*get_refresh_commit_coins) (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
@@ -1591,11 +1586,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param session database connection to use
* @param session_hash hash to identify refresh session
* @param[out] tp information to return
- * @return #GNUNET_SYSERR on internal error,
- * #GNUNET_NO if commitment was not found
- * #GNUNET_OK on success
+ * @return transaction status
*/
- int
+ enum GNUNET_DB_QueryStatus
(*get_refresh_transfer_public_key) (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
@@ -1612,10 +1605,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param session_hash hash to identify refresh session
* @param newcoin_index coin index
* @param[out] ev_sig coin signature
- * @return #GNUNET_OK on success, #GNUNET_NO if we have no such entry,
- * #GNUNET_SYSERR on error
+ * @return transaction result status
*/
- int
+ enum GNUNET_DB_QueryStatus
(*get_refresh_out) (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,
@@ -1634,10 +1626,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param session_hash hash to identify refresh session
* @param newcoin_index coin index
* @param ev_sig coin signature
- * @return #GNUNET_OK on success
- * #GNUNET_SYSERR on error
+ * @return transaction result status
*/
- int
+ enum GNUNET_DB_QueryStatus
(*insert_refresh_out) (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *session_hash,