starting some initial work on #5010, very incomplete

This commit is contained in:
Christian Grothoff 2017-05-25 02:06:03 +02:00
parent 6bb2631ab4
commit 6029ed7db1
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
3 changed files with 285 additions and 264 deletions

View File

@ -30,6 +30,17 @@
#include "plugin_exchangedb_common.c" #include "plugin_exchangedb_common.c"
/**
* Error code returned by Postgres for deadlock.
*/
#define PQ_DIAG_SQLSTATE_DEADLOCK "40P01"
/**
* Error code returned by Postgres on serialization failure.
*/
#define PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE "40001"
/** /**
* Log a query error. * Log a query error.
* *
@ -37,7 +48,7 @@
* @param conn SQL connection that was used * @param conn SQL connection that was used
*/ */
#define QUERY_ERR(result,conn) \ #define QUERY_ERR(result,conn) \
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
"Query failed at %s:%u: %s/%s/%s/%s/%s\n", \ "Query failed at %s:%u: %s/%s/%s/%s/%s\n", \
__FILE__, __LINE__, \ __FILE__, __LINE__, \
PQresultErrorField (result, PG_DIAG_MESSAGE_PRIMARY), \ PQresultErrorField (result, PG_DIAG_MESSAGE_PRIMARY), \
@ -111,6 +122,7 @@
} while (0) } while (0)
/** /**
* Handle for a database session (per-thread, for transactions). * Handle for a database session (per-thread, for transactions).
*/ */
@ -120,6 +132,25 @@ struct TALER_EXCHANGEDB_Session
* Postgres connection handle. * Postgres connection handle.
*/ */
PGconn *conn; PGconn *conn;
/**
* Transaction state. Set to #GNUNET_OK by #postgres_start().
* Set to #GNUNET_NO if any part of the transaction failed in a
* transient way (i.e. #PG_DIAG_SQLSTATE_DEADLOCK or
* #PG_DIAG_SQLSTATE_SERIALIZATION_FAILURE). Set to
* #GNUNET_SYSERR if any part of the transaction failed in a
* hard way or if we are not within a transaction scope.
*
* If #GNUNET_NO, #postgres_commit() will always just do a
* rollback and return #GNUNET_NO as well (to retry).
*
* If #GNUNET_SYSERR, #postgres_commit() will always just do a
* rollback and return #GNUNET_SYSERR as well.
*
* If #GNUNET_OK, #postgres_commit() will try to commit and
* return the result from the commit operation.
*/
int state;
}; };
@ -1700,6 +1731,7 @@ postgres_get_session (void *cls)
return NULL; return NULL;
} }
session = GNUNET_new (struct TALER_EXCHANGEDB_Session); session = GNUNET_new (struct TALER_EXCHANGEDB_Session);
session->state = GNUNET_SYSERR;
session->conn = db_conn; session->conn = db_conn;
if (0 != pthread_setspecific (pc->db_conn_threadlocal, if (0 != pthread_setspecific (pc->db_conn_threadlocal,
session)) session))
@ -1737,10 +1769,11 @@ postgres_start (void *cls,
PQerrorMessage (session->conn)); PQerrorMessage (session->conn));
GNUNET_break (0); GNUNET_break (0);
PQclear (result); PQclear (result);
session->state = GNUNET_SYSERR;
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
PQclear (result); PQclear (result);
session->state = GNUNET_OK;
return GNUNET_OK; return GNUNET_OK;
} }
@ -1763,24 +1796,24 @@ postgres_rollback (void *cls,
GNUNET_break (PGRES_COMMAND_OK == GNUNET_break (PGRES_COMMAND_OK ==
PQresultStatus (result)); PQresultStatus (result));
PQclear (result); PQclear (result);
session->state = GNUNET_SYSERR;
} }
/** /**
* Commit the current transaction of a database connection. * Check the @a result's error code to see what happened.
* Also logs errors.
* *
* @param cls the `struct PostgresClosure` with the plugin-specific state * @param session session used
* @param session the database connection * @param result result to check
* @return #GNUNET_OK on success * @return #GNUNET_OK if the request/transaction succeeded
* #GNUNET_NO if it failed but could succeed if retried
* #GNUNET_SYSERR on hard errors
*/ */
static int static int
postgres_commit (void *cls, evaluate_pq_result (struct TALER_EXCHANGEDB_Session *session,
struct TALER_EXCHANGEDB_Session *session) PGresult *result)
{ {
PGresult *result;
result = PQexec (session->conn,
"COMMIT");
if (PGRES_COMMAND_OK != if (PGRES_COMMAND_OK !=
PQresultStatus (result)) PQresultStatus (result))
{ {
@ -1792,31 +1825,140 @@ postgres_commit (void *cls,
{ {
/* very unexpected... */ /* very unexpected... */
GNUNET_break (0); GNUNET_break (0);
PQclear (result);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
/* 40P01: deadlock, 40001: serialization failure */
if ( (0 == strcmp (sqlstate, if ( (0 == strcmp (sqlstate,
"40P01")) || PQ_DIAG_SQLSTATE_DEADLOCK)) ||
(0 == strcmp (sqlstate, (0 == strcmp (sqlstate,
"40001")) ) PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE)) )
{ {
/* These two can be retried and have a fair chance of working /* These two can be retried and have a fair chance of working
the next time */ the next time */
PQclear (result); QUERY_ERR (result, session->conn);
return GNUNET_NO; return GNUNET_NO;
} }
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, BREAK_DB_ERR(result, session->conn);
"Database commit failure: %s\n",
sqlstate);
PQclear (result);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
PQclear (result);
return GNUNET_OK; return GNUNET_OK;
} }
/**
* Commit the current transaction of a database connection.
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
* @param session the database connection
* @return #GNUNET_SYSERR on hard error,
* #GNUNET_NO if commit failed but retry may work,
* #GNUNET_OK on success
*/
static int
postgres_commit (void *cls,
struct TALER_EXCHANGEDB_Session *session)
{
PGresult *result;
int ret;
int state;
state = session->state;
if (GNUNET_OK != state)
{
postgres_rollback (cls,
session);
return state;
}
result = PQexec (session->conn,
"COMMIT");
ret = evaluate_pq_result (session,
result);
GNUNET_break (GNUNET_SYSERR != ret);
PQclear (result);
return ret;
}
/**
* Update the @a session state based on the latest @a result from
* the database. Checks the status code of @a result and possibly
* sets the state to failed (#GNUNET_SYSERR) or transiently failed
* (#GNUNET_NO).
*
* @param session the session in which the transaction is running
* @param statement name of the statement we were executing (for logging)
* @param result the result we got from Postgres
* @return current session state, i.e.
* #GNUNET_OK on success
* #GNUNET_NO if the transaction had a transient failure
* #GNUNET_SYSERR if the transaction had a hard failure
*/
static int
update_session_from_result (struct TALER_EXCHANGEDB_Session *session,
const char *statement,
PGresult *result)
{
int ret;
if (GNUNET_OK != session->state)
{
GNUNET_break (0);
return GNUNET_SYSERR; /* we already failed, why do we keep going? */
}
ret = evaluate_pq_result (session,
result);
if (GNUNET_OK == ret)
return ret;
GNUNET_log ((GNUNET_NO == ret)
? GNUNET_ERROR_TYPE_INFO
: GNUNET_ERROR_TYPE_ERROR,
"Statement `%s' failed: %s/%s/%s/%s/%s",
statement,
PQresultErrorField (result, PG_DIAG_MESSAGE_PRIMARY),
PQresultErrorField (result, PG_DIAG_MESSAGE_DETAIL),
PQresultErrorMessage (result),
PQresStatus (PQresultStatus (result)),
PQerrorMessage (session->conn));
session->state = ret;
return ret;
}
/**
* Execute a named prepared @a statement that is NOT a SELECT statement
* in @a session using the given @a params. Returns the resulting session
* state.
*
* @param session session to execute the statement in
* @param statement name of the statement
* @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
* @return #GNUNET_OK on success
* #GNUNET_NO if the transaction had a transient failure
* #GNUNET_SYSERR if the transaction had a hard failure
*/
static int
execute_prepared_non_select (struct TALER_EXCHANGEDB_Session *session,
const char *statement,
const struct GNUNET_PQ_QueryParam *params)
{
PGresult *result;
int ret;
if (GNUNET_OK != session->state)
{
GNUNET_break (0);
return GNUNET_SYSERR; /* we already failed, why keep going? */
}
result = GNUNET_PQ_exec_prepared (session->conn,
statement,
params);
ret = update_session_from_result (session,
statement,
result);
PQclear (result);
return ret;
}
/** /**
* Insert a denomination key's public information into the database for * Insert a denomination key's public information into the database for
* reference by auditors and other consistency checks. * reference by auditors and other consistency checks.
@ -1833,8 +1975,6 @@ postgres_insert_denomination_info (void *cls,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue) const struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue)
{ {
PGresult *result;
int ret;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&issue->properties.denom_hash), GNUNET_PQ_query_param_auto_from_type (&issue->properties.denom_hash),
GNUNET_PQ_query_param_rsa_public_key (denom_pub->rsa_public_key), GNUNET_PQ_query_param_rsa_public_key (denom_pub->rsa_public_key),
@ -1866,20 +2006,9 @@ postgres_insert_denomination_info (void *cls,
TALER_amount_cmp_currency_nbo (&issue->properties.value, TALER_amount_cmp_currency_nbo (&issue->properties.value,
&issue->properties.fee_refund)); &issue->properties.fee_refund));
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"denomination_insert", "denomination_insert",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
ret = GNUNET_SYSERR;
BREAK_DB_ERR (result, session->conn);
}
else
{
ret = GNUNET_OK;
}
PQclear (result);
return ret;
} }
@ -1909,7 +2038,8 @@ postgres_get_denomination_info (void *cls,
params); params);
if (PGRES_TUPLES_OK != PQresultStatus (result)) if (PGRES_TUPLES_OK != PQresultStatus (result))
{ {
QUERY_ERR (result, session->conn); QUERY_ERR (result,
session->conn);
PQclear (result); PQclear (result);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
@ -2046,8 +2176,6 @@ reserves_update (void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
const struct TALER_EXCHANGEDB_Reserve *reserve) const struct TALER_EXCHANGEDB_Reserve *reserve)
{ {
PGresult *result;
int ret;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_absolute_time (&reserve->expiry), GNUNET_PQ_query_param_absolute_time (&reserve->expiry),
TALER_PQ_query_param_amount (&reserve->balance), TALER_PQ_query_param_amount (&reserve->balance),
@ -2055,22 +2183,9 @@ reserves_update (void *cls,
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"reserve_update", "reserve_update",
params); params);
/* FIXME: properly distinguish between hard and soft (retry-able) failures here! */
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
QUERY_ERR (result,
session->conn);
ret = GNUNET_SYSERR;
}
else
{
ret = GNUNET_OK;
}
PQclear (result);
return ret;
} }
@ -2881,7 +2996,9 @@ postgres_have_deposit (void *cls,
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param rowid identifies the deposit row to modify * @param rowid identifies the deposit row to modify
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on error
*/ */
static int static int
postgres_mark_deposit_tiny (void *cls, postgres_mark_deposit_tiny (void *cls,
@ -2892,20 +3009,10 @@ postgres_mark_deposit_tiny (void *cls,
GNUNET_PQ_query_param_uint64 (&rowid), GNUNET_PQ_query_param_uint64 (&rowid),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
PGresult *result;
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"mark_deposit_tiny", "mark_deposit_tiny",
params); params);
if (PGRES_COMMAND_OK !=
PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result);
return GNUNET_OK;
} }
@ -2986,7 +3093,9 @@ postgres_test_deposit_done (void *cls,
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param rowid identifies the deposit row to modify * @param rowid identifies the deposit row to modify
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success,
* #GNUNET_NO on transient error,
* #GNUNET_SYSERR on error
*/ */
static int static int
postgres_mark_deposit_done (void *cls, postgres_mark_deposit_done (void *cls,
@ -2997,20 +3106,10 @@ postgres_mark_deposit_done (void *cls,
GNUNET_PQ_query_param_uint64 (&rowid), GNUNET_PQ_query_param_uint64 (&rowid),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
PGresult *result;
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"mark_deposit_done", "mark_deposit_done",
params); params);
if (PGRES_COMMAND_OK !=
PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result);
return GNUNET_OK;
} }
@ -3289,14 +3388,15 @@ get_known_coin (void *cls,
* @param cls plugin closure * @param cls plugin closure
* @param session the shared database session * @param session the shared database session
* @param coin_info the public coin info * @param coin_info the public coin info
* @return #GNUNET_SYSERR upon error; #GNUNET_OK upon success * @return #GNUNET_SYSERR upon error;
* #GNUNET_NO on transient error
* #GNUNET_OK upon success
*/ */
static int static int
insert_known_coin (void *cls, insert_known_coin (void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
const struct TALER_CoinPublicInfo *coin_info) const struct TALER_CoinPublicInfo *coin_info)
{ {
PGresult *result;
struct GNUNET_HashCode denom_pub_hash; struct GNUNET_HashCode denom_pub_hash;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&coin_info->coin_pub), GNUNET_PQ_query_param_auto_from_type (&coin_info->coin_pub),
@ -3307,17 +3407,9 @@ insert_known_coin (void *cls,
GNUNET_CRYPTO_rsa_public_key_hash (coin_info->denom_pub.rsa_public_key, GNUNET_CRYPTO_rsa_public_key_hash (coin_info->denom_pub.rsa_public_key,
&denom_pub_hash); &denom_pub_hash);
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"insert_known_coin", "insert_known_coin",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result);
return GNUNET_OK;
} }
@ -3327,14 +3419,15 @@ insert_known_coin (void *cls,
* @param cls the `struct PostgresClosure` with the plugin-specific state * @param cls the `struct PostgresClosure` with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param deposit deposit information to store * @param deposit deposit information to store
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on error
*/ */
static int static int
postgres_insert_deposit (void *cls, postgres_insert_deposit (void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
const struct TALER_EXCHANGEDB_Deposit *deposit) const struct TALER_EXCHANGEDB_Deposit *deposit)
{ {
PGresult *result;
int ret; int ret;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub), GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
@ -3362,30 +3455,19 @@ postgres_insert_deposit (void *cls,
} }
if (GNUNET_NO == ret) /* if not, insert it */ if (GNUNET_NO == ret) /* if not, insert it */
{ {
if (GNUNET_SYSERR == if (GNUNET_OK !=
insert_known_coin (cls, (ret = insert_known_coin (cls,
session, session,
&deposit->coin)) &deposit->coin)))
{ {
GNUNET_break (0); GNUNET_break (GNUNET_NO == ret);
return GNUNET_SYSERR; return ret;
} }
} }
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"insert_deposit", "insert_deposit",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
ret = GNUNET_SYSERR;
}
else
{
ret = GNUNET_OK;
}
PQclear (result);
return ret;
} }
@ -3395,15 +3477,15 @@ postgres_insert_deposit (void *cls,
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param refund refund information to store * @param refund refund information to store
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on error
*/ */
static int static int
postgres_insert_refund (void *cls, postgres_insert_refund (void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
const struct TALER_EXCHANGEDB_Refund *refund) const struct TALER_EXCHANGEDB_Refund *refund)
{ {
PGresult *result;
int ret;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&refund->coin.coin_pub), GNUNET_PQ_query_param_auto_from_type (&refund->coin.coin_pub),
GNUNET_PQ_query_param_auto_from_type (&refund->merchant_pub), GNUNET_PQ_query_param_auto_from_type (&refund->merchant_pub),
@ -3413,23 +3495,13 @@ postgres_insert_refund (void *cls,
TALER_PQ_query_param_amount (&refund->refund_amount), TALER_PQ_query_param_amount (&refund->refund_amount),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
GNUNET_assert (GNUNET_YES == GNUNET_assert (GNUNET_YES ==
TALER_amount_cmp_currency (&refund->refund_amount, TALER_amount_cmp_currency (&refund->refund_amount,
&refund->refund_fee)); &refund->refund_fee));
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"insert_refund", "insert_refund",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
ret = GNUNET_SYSERR;
BREAK_DB_ERR (result, session->conn);
}
else
{
ret = GNUNET_OK;
}
PQclear (result);
return ret;
} }
@ -3532,6 +3604,7 @@ postgres_get_refresh_session (void *cls,
* @param session_hash hash over the melt to use to locate the session * @param session_hash hash over the melt to use to locate the session
* @param refresh_session session data to store * @param refresh_session session data to store
* @return #GNUNET_YES on success, * @return #GNUNET_YES on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on DB failure * #GNUNET_SYSERR on DB failure
*/ */
static int static int
@ -3540,7 +3613,6 @@ postgres_create_refresh_session (void *cls,
const struct GNUNET_HashCode *session_hash, const struct GNUNET_HashCode *session_hash,
const struct TALER_EXCHANGEDB_RefreshSession *refresh_session) const struct TALER_EXCHANGEDB_RefreshSession *refresh_session)
{ {
PGresult *result;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (session_hash), GNUNET_PQ_query_param_auto_from_type (session_hash),
GNUNET_PQ_query_param_auto_from_type (&refresh_session->melt.coin.coin_pub), GNUNET_PQ_query_param_auto_from_type (&refresh_session->melt.coin.coin_pub),
@ -3564,27 +3636,19 @@ postgres_create_refresh_session (void *cls,
} }
if (GNUNET_NO == ret) /* if not, insert it */ if (GNUNET_NO == ret) /* if not, insert it */
{ {
if (GNUNET_SYSERR == if (GNUNET_OK !=
insert_known_coin (cls, (ret = insert_known_coin (cls,
session, session,
&refresh_session->melt.coin)) &refresh_session->melt.coin)))
{ {
GNUNET_break (0); GNUNET_break (GNUNET_NO == ret);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
} }
/* insert session */
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"insert_refresh_session", "insert_refresh_session",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result);
return GNUNET_OK;
} }
@ -3809,9 +3873,7 @@ postgres_free_refresh_commit_coins (void *cls,
unsigned int commit_coins_len, unsigned int commit_coins_len,
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins) struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins)
{ {
unsigned int i; for (unsigned int i=0;i<commit_coins_len;i++)
for (i=0;i<commit_coins_len;i++)
{ {
GNUNET_free (commit_coins[i].coin_ev); GNUNET_free (commit_coins[i].coin_ev);
commit_coins[i].coin_ev = NULL; commit_coins[i].coin_ev = NULL;
@ -3840,9 +3902,7 @@ postgres_get_refresh_commit_coins (void *cls,
uint16_t num_newcoins, uint16_t num_newcoins,
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins) struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins)
{ {
unsigned int i; for (unsigned int i=0;i<(unsigned int) num_newcoins;i++)
for (i=0;i<(unsigned int) num_newcoins;i++)
{ {
uint16_t newcoin_off = (uint16_t) i; uint16_t newcoin_off = (uint16_t) i;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
@ -3910,7 +3970,9 @@ postgres_get_refresh_commit_coins (void *cls,
* @param session database connection to use * @param session database connection to use
* @param session_hash hash to identify refresh session * @param session_hash hash to identify refresh session
* @param tp transfer public key to store * @param tp transfer public key to store
* @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success * @return #GNUNET_SYSERR on internal error,
* #GNUNET_NO on transient errors
* #GNUNET_OK on success
*/ */
static int static int
postgres_insert_refresh_transfer_public_key (void *cls, postgres_insert_refresh_transfer_public_key (void *cls,
@ -3924,25 +3986,9 @@ postgres_insert_refresh_transfer_public_key (void *cls,
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
PGresult *result; return execute_prepared_non_select (session,
result = GNUNET_PQ_exec_prepared (session->conn,
"insert_transfer_public_key", "insert_transfer_public_key",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
PQclear (result);
return GNUNET_SYSERR;
}
if (0 != strcmp ("1", PQcmdTuples (result)))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
PQclear (result);
return GNUNET_OK;
} }
@ -4077,6 +4123,7 @@ postgres_get_refresh_out (void *cls,
* @param newcoin_index coin index * @param newcoin_index coin index
* @param ev_sig coin signature * @param ev_sig coin signature
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on error * #GNUNET_SYSERR on error
*/ */
static int static int
@ -4086,7 +4133,6 @@ postgres_insert_refresh_out (void *cls,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct TALER_DenominationSignature *ev_sig) const struct TALER_DenominationSignature *ev_sig)
{ {
PGresult *result;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (session_hash), GNUNET_PQ_query_param_auto_from_type (session_hash),
GNUNET_PQ_query_param_uint16 (&newcoin_index), GNUNET_PQ_query_param_uint16 (&newcoin_index),
@ -4094,17 +4140,9 @@ postgres_insert_refresh_out (void *cls,
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"insert_refresh_out", "insert_refresh_out",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result);
return GNUNET_OK;
} }
@ -4123,7 +4161,6 @@ postgres_get_link_data_list (void *cls,
const struct GNUNET_HashCode *session_hash) const struct GNUNET_HashCode *session_hash)
{ {
struct TALER_EXCHANGEDB_LinkDataList *ldl; struct TALER_EXCHANGEDB_LinkDataList *ldl;
int i;
int nrows; int nrows;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (session_hash), GNUNET_PQ_query_param_auto_from_type (session_hash),
@ -4148,7 +4185,7 @@ postgres_get_link_data_list (void *cls,
return NULL; return NULL;
} }
for (i = nrows-1; i >= 0; i--) for (int i = nrows-1; i >= 0; i--)
{ {
struct GNUNET_CRYPTO_RsaPublicKey *denom_pub; struct GNUNET_CRYPTO_RsaPublicKey *denom_pub;
struct GNUNET_CRYPTO_RsaSignature *sig; struct GNUNET_CRYPTO_RsaSignature *sig;
@ -4215,7 +4252,6 @@ postgres_get_transfer (void *cls,
}; };
PGresult *result; PGresult *result;
int nrows; int nrows;
int i;
result = GNUNET_PQ_exec_prepared (session->conn, result = GNUNET_PQ_exec_prepared (session->conn,
"get_transfer", "get_transfer",
@ -4234,7 +4270,7 @@ postgres_get_transfer (void *cls,
PQclear (result); PQclear (result);
return GNUNET_NO; return GNUNET_NO;
} }
for (i=0;i<nrows;i++) for (int i=0;i<nrows;i++)
{ {
struct GNUNET_HashCode session_hash; struct GNUNET_HashCode session_hash;
struct TALER_TransferPublicKeyP transfer_pub; struct TALER_TransferPublicKeyP transfer_pub;
@ -4286,7 +4322,6 @@ postgres_get_coin_transactions (void *cls,
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
int nrows; int nrows;
int i;
PGresult *result; PGresult *result;
struct TALER_EXCHANGEDB_TransactionList *tl; struct TALER_EXCHANGEDB_TransactionList *tl;
@ -4300,7 +4335,7 @@ postgres_get_coin_transactions (void *cls,
goto cleanup; goto cleanup;
} }
nrows = PQntuples (result); nrows = PQntuples (result);
for (i = 0; i < nrows; i++) for (int i = 0; i < nrows; i++)
{ {
struct TALER_EXCHANGEDB_Deposit *deposit; struct TALER_EXCHANGEDB_Deposit *deposit;
@ -4366,7 +4401,6 @@ postgres_get_coin_transactions (void *cls,
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
int nrows; int nrows;
int i;
PGresult *result; PGresult *result;
struct TALER_EXCHANGEDB_TransactionList *tl; struct TALER_EXCHANGEDB_TransactionList *tl;
@ -4381,7 +4415,7 @@ postgres_get_coin_transactions (void *cls,
goto cleanup; goto cleanup;
} }
nrows = PQntuples (result); nrows = PQntuples (result);
for (i=0;i<nrows;i++) for (int i=0;i<nrows;i++)
{ {
struct TALER_EXCHANGEDB_RefreshMelt *melt; struct TALER_EXCHANGEDB_RefreshMelt *melt;
@ -4437,7 +4471,6 @@ postgres_get_coin_transactions (void *cls,
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
int nrows; int nrows;
int i;
PGresult *result; PGresult *result;
struct TALER_EXCHANGEDB_TransactionList *tl; struct TALER_EXCHANGEDB_TransactionList *tl;
@ -4452,7 +4485,7 @@ postgres_get_coin_transactions (void *cls,
goto cleanup; goto cleanup;
} }
nrows = PQntuples (result); nrows = PQntuples (result);
for (i=0;i<nrows;i++) for (int i=0;i<nrows;i++)
{ {
struct TALER_EXCHANGEDB_Refund *refund; struct TALER_EXCHANGEDB_Refund *refund;
@ -4512,7 +4545,6 @@ postgres_get_coin_transactions (void *cls,
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
int nrows; int nrows;
int i;
PGresult *result; PGresult *result;
struct TALER_EXCHANGEDB_TransactionList *tl; struct TALER_EXCHANGEDB_TransactionList *tl;
@ -4527,7 +4559,7 @@ postgres_get_coin_transactions (void *cls,
goto cleanup; goto cleanup;
} }
nrows = PQntuples (result); nrows = PQntuples (result);
for (i=0;i<nrows;i++) for (int i=0;i<nrows;i++)
{ {
struct TALER_EXCHANGEDB_Payback *payback; struct TALER_EXCHANGEDB_Payback *payback;
@ -4606,7 +4638,6 @@ postgres_lookup_wire_transfer (void *cls,
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
int nrows; int nrows;
int i;
/* check if the melt record exists and get it */ /* check if the melt record exists and get it */
result = GNUNET_PQ_exec_prepared (session->conn, result = GNUNET_PQ_exec_prepared (session->conn,
@ -4626,7 +4657,7 @@ postgres_lookup_wire_transfer (void *cls,
PQclear (result); PQclear (result);
return GNUNET_NO; return GNUNET_NO;
} }
for (i=0;i<nrows;i++) for (int i=0;i<nrows;i++)
{ {
uint64_t rowid; uint64_t rowid;
struct GNUNET_HashCode h_proposal_data; struct GNUNET_HashCode h_proposal_data;
@ -4852,7 +4883,9 @@ postgres_wire_lookup_deposit_wtid (void *cls,
* @param session database connection * @param session database connection
* @param wtid the raw wire transfer identifier we used * @param wtid the raw wire transfer identifier we used
* @param deposit_serial_id row in the deposits table for which this is aggregation data * @param deposit_serial_id row in the deposits table for which this is aggregation data
* @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors * @return #GNUNET_OK on success,
* #GNUNET_NO on transient errors
* #GNUNET_SYSERR on DB errors
*/ */
static int static int
postgres_insert_aggregation_tracking (void *cls, postgres_insert_aggregation_tracking (void *cls,
@ -4866,25 +4899,10 @@ postgres_insert_aggregation_tracking (void *cls,
GNUNET_PQ_query_param_auto_from_type (wtid), GNUNET_PQ_query_param_auto_from_type (wtid),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
PGresult *result;
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"insert_aggregation_tracking", "insert_aggregation_tracking",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
PQclear (result);
return GNUNET_SYSERR;
}
if (0 != strcmp ("1", PQcmdTuples (result)))
{
GNUNET_break (0);
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result);
return GNUNET_OK;
} }
@ -4973,7 +4991,8 @@ postgres_get_wire_fee (void *cls,
* @param end_date when does the fee end being valid * @param end_date when does the fee end being valid
* @param wire_fee how high is the wire transfer fee * @param wire_fee how high is the wire transfer fee
* @param master_sig signature over the above by the exchange master key * @param master_sig signature over the above by the exchange master key
* @return #GNUNET_OK on success, #GNUNET_NO if the record exists, * @return #GNUNET_OK on success or if the record exists,
* #GNUNET_NO on transient errors
* #GNUNET_SYSERR on failure * #GNUNET_SYSERR on failure
*/ */
static int static int
@ -4993,7 +5012,6 @@ postgres_insert_wire_fee (void *cls,
GNUNET_PQ_query_param_auto_from_type (master_sig), GNUNET_PQ_query_param_auto_from_type (master_sig),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
PGresult *result;
struct TALER_Amount wf; struct TALER_Amount wf;
struct TALER_MasterSignatureP sig; struct TALER_MasterSignatureP sig;
struct GNUNET_TIME_Absolute sd; struct GNUNET_TIME_Absolute sd;
@ -5029,26 +5047,12 @@ postgres_insert_wire_fee (void *cls,
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
/* equal record already exists */ /* equal record already exists */
return GNUNET_NO; return GNUNET_OK;
} }
result = GNUNET_PQ_exec_prepared (session->conn, return execute_prepared_non_select (session,
"insert_wire_fee", "insert_wire_fee",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
BREAK_DB_ERR (result, session->conn);
PQclear (result);
return GNUNET_SYSERR;
}
if (0 != strcmp ("1", PQcmdTuples (result)))
{
GNUNET_break (0);
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result);
return GNUNET_OK;
} }
@ -5424,6 +5428,7 @@ postgres_start_deferred_wire_out (void *cls,
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
PQclear (result); PQclear (result);
session->state = GNUNET_OK;
return GNUNET_OK; return GNUNET_OK;
} }
@ -6377,6 +6382,7 @@ postgres_select_reserve_closed_above_serial_id (void *cls,
* @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry) * @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
* @param timestamp current time (rounded) * @param timestamp current time (rounded)
* @return #GNUNET_OK on success, * @return #GNUNET_OK on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on DB errors * #GNUNET_SYSERR on DB errors
*/ */
static int static int
@ -6418,13 +6424,13 @@ postgres_insert_payback_request (void *cls,
} }
if (GNUNET_NO == ret) /* if not, insert it */ if (GNUNET_NO == ret) /* if not, insert it */
{ {
if (GNUNET_SYSERR == if (GNUNET_OK !=
insert_known_coin (cls, (ret = insert_known_coin (cls,
session, session,
coin)) coin)))
{ {
GNUNET_break (0); GNUNET_break (GNUNET_NO == ret);
return GNUNET_SYSERR; return ret;
} }
} }

View File

@ -1168,7 +1168,7 @@ test_wire_fees (struct TALER_EXCHANGEDB_Session *session)
GNUNET_break (0); GNUNET_break (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (GNUNET_NO != if (GNUNET_OK !=
plugin->insert_wire_fee (plugin->cls, plugin->insert_wire_fee (plugin->cls,
session, session,
"wire-method", "wire-method",

View File

@ -1308,7 +1308,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param deposit deposit information to store * @param deposit deposit information to store
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on error
*/ */
int int
(*insert_deposit) (void *cls, (*insert_deposit) (void *cls,
@ -1322,7 +1324,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param refund refund information to store * @param refund refund information to store
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on error
*/ */
int int
(*insert_refund) (void *cls, (*insert_refund) (void *cls,
@ -1338,7 +1342,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param deposit_rowid identifies the deposit row to modify * @param deposit_rowid identifies the deposit row to modify
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on error
*/ */
int int
(*mark_deposit_tiny) (void *cls, (*mark_deposit_tiny) (void *cls,
@ -1370,7 +1376,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to the database * @param session connection to the database
* @param deposit_rowid identifies the deposit row to modify * @param deposit_rowid identifies the deposit row to modify
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on error
*/ */
int int
(*mark_deposit_done) (void *cls, (*mark_deposit_done) (void *cls,
@ -1460,6 +1468,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param session_hash hash over the melt to use to locate the session * @param session_hash hash over the melt to use to locate the session
* @param refresh_session session data to store * @param refresh_session session data to store
* @return #GNUNET_YES on success, * @return #GNUNET_YES on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on DB failure * #GNUNET_SYSERR on DB failure
*/ */
int int
@ -1570,7 +1579,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param session database connection to use * @param session database connection to use
* @param session_hash hash to identify refresh session * @param session_hash hash to identify refresh session
* @param tp public key to store * @param tp public key to store
* @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success * @return #GNUNET_SYSERR on internal error
* #GNUNET_NO on transient errors
* #GNUNET_OK on success
*/ */
int int
(*insert_refresh_transfer_public_key) (void *cls, (*insert_refresh_transfer_public_key) (void *cls,
@ -1769,7 +1780,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param session database connection * @param session database connection
* @param wtid the raw wire transfer identifier we used * @param wtid the raw wire transfer identifier we used
* @param deposit_serial_id row in the deposits table for which this is aggregation data * @param deposit_serial_id row in the deposits table for which this is aggregation data
* @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors * @return #GNUNET_OK on success
* #GNUNET_NO on transient errors
* #GNUNET_SYSERR on DB errors
*/ */
int int
(*insert_aggregation_tracking)(void *cls, (*insert_aggregation_tracking)(void *cls,
@ -1788,7 +1801,8 @@ struct TALER_EXCHANGEDB_Plugin
* @param end_date when does the fee end being valid * @param end_date when does the fee end being valid
* @param wire_fee how high is the wire transfer fee * @param wire_fee how high is the wire transfer fee
* @param master_sig signature over the above by the exchange master key * @param master_sig signature over the above by the exchange master key
* @return #GNUNET_OK on success, #GNUNET_NO if the record exists, * @return #GNUNET_OK on success or if the record exists,
* #GNUNET_NO on transient errors,
* #GNUNET_SYSERR on failure * #GNUNET_SYSERR on failure
*/ */
int int
@ -2160,6 +2174,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry) * @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
* @param now timestamp to store * @param now timestamp to store
* @return #GNUNET_OK on success, * @return #GNUNET_OK on success,
* #GNUNET_NO on transient error
* #GNUNET_SYSERR on DB errors * #GNUNET_SYSERR on DB errors
*/ */
int int