summaryrefslogtreecommitdiff
path: root/src/exchangedb
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-06-23 14:13:54 +0200
committerChristian Grothoff <christian@grothoff.org>2017-06-23 14:13:54 +0200
commitff8633910d90d7c5299016bce7a8ea49e12510a7 (patch)
tree77030f63722592396c226433ad00cdd410f0a105 /src/exchangedb
parentd4884c0c605db10934f7bb378072a21ecb523d12 (diff)
downloadexchange-ff8633910d90d7c5299016bce7a8ea49e12510a7.tar.gz
exchange-ff8633910d90d7c5299016bce7a8ea49e12510a7.tar.bz2
exchange-ff8633910d90d7c5299016bce7a8ea49e12510a7.zip
adapt /admin/add/incoming to #5010
Diffstat (limited to 'src/exchangedb')
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c105
-rw-r--r--src/exchangedb/test_exchangedb.c12
2 files changed, 34 insertions, 83 deletions
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 2a47f2503..6758a308a 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -1952,11 +1952,9 @@ reserves_update (void *cls,
* @param sender_account_details account information for the sender
* @param wire_reference unique reference identifying the wire transfer (binary blob)
* @param wire_reference_size number of bytes in @a wire_reference
- * @return #GNUNET_OK upon success; #GNUNET_NO if the given
- * @a details are already known for this @a reserve_pub,
- * #GNUNET_SYSERR upon failures (DB error, incompatible currency)
+ * @return transaction status code
*/
-static int
+static enum GNUNET_DB_QueryStatus
postgres_reserves_in_insert (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct TALER_ReservePublicKeyP *reserve_pub,
@@ -1967,18 +1965,11 @@ postgres_reserves_in_insert (void *cls,
size_t wire_reference_size)
{
struct PostgresClosure *pg = cls;
- PGresult *result;
enum GNUNET_DB_QueryStatus reserve_exists;
+ enum GNUNET_DB_QueryStatus qs;
struct TALER_EXCHANGEDB_Reserve reserve;
struct GNUNET_TIME_Absolute expiry;
- if (GNUNET_OK !=
- postgres_start (cls,
- session))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
reserve.pub = *reserve_pub;
reserve_exists = postgres_reserve_get (cls,
session,
@@ -1986,7 +1977,7 @@ postgres_reserves_in_insert (void *cls,
if (0 > reserve_exists)
{
GNUNET_break (0);
- goto rollback;
+ return reserve_exists;
}
if ( (0 == reserve.balance.value) &&
(0 == reserve.balance.fraction) )
@@ -2030,22 +2021,22 @@ postgres_reserves_in_insert (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Reserve does not exist; creating a new one\n");
- result = GNUNET_PQ_exec_prepared (session->conn,
- "reserve_create",
- params);
- if (PGRES_COMMAND_OK != PQresultStatus(result))
+ qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+ "reserve_create",
+ params);
+ if (0 > qs)
+ return qs;
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
- QUERY_ERR (result, session->conn);
- PQclear (result);
- goto rollback;
+ /* Maybe DB did not detect serializiability error already,
+ but clearly there must be one. Still odd. */
+ GNUNET_break (0);
+ return GNUNET_DB_STATUS_SOFT_ERROR;
}
- PQclear (result);
}
/* Create new incoming transaction, SQL "primary key" logic
is used to guard against duplicates. If a duplicate is
- detected, we rollback (which really shouldn't undo
- anything) and return #GNUNET_NO to indicate that this failure
- is kind-of harmless (already executed). */
+ detected, we just "succeed" with no changes. */
{
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&reserve.pub),
@@ -2057,34 +2048,12 @@ postgres_reserves_in_insert (void *cls,
GNUNET_PQ_query_param_end
};
- result = GNUNET_PQ_exec_prepared (session->conn,
- "reserves_in_add_transaction",
- params);
- }
- if (PGRES_COMMAND_OK != PQresultStatus(result))
- {
- const char *efield;
-
- efield = PQresultErrorField (result,
- PG_DIAG_SQLSTATE);
- if ( (PGRES_FATAL_ERROR == PQresultStatus(result)) &&
- (NULL != strstr ("23505", /* unique violation */
- efield)) )
- {
- /* This means we had the same reserve/justification/details
- before */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Uniqueness violation, deposit details already known\n");
- PQclear (result);
- postgres_rollback (cls,
- session);
- return GNUNET_NO;
- }
- QUERY_ERR (result, session->conn);
- PQclear (result);
- goto rollback;
+ qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+ "reserves_in_add_transaction",
+ params);
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
+ return qs;
}
- PQclear (result);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == reserve_exists)
{
@@ -2094,7 +2063,6 @@ postgres_reserves_in_insert (void *cls,
back for duplicate transactions; like this, we should virtually
never actually have to rollback anything. */
struct TALER_EXCHANGEDB_Reserve updated_reserve;
- enum GNUNET_DB_QueryStatus qs;
updated_reserve.pub = reserve.pub;
if (GNUNET_OK !=
@@ -2105,38 +2073,15 @@ postgres_reserves_in_insert (void *cls,
/* currency overflow or incompatible currency */
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Attempt to deposit incompatible amount into reserve\n");
- goto rollback;
+ return GNUNET_DB_STATUS_HARD_ERROR;
}
updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry,
reserve.expiry);
- qs = reserves_update (cls,
- session,
- &updated_reserve);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- goto rollback; /* FIXME: #5010 */
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
- {
- postgres_rollback (cls,
- session);
- return GNUNET_SYSERR;
- }
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
- postgres_commit (cls,
- session))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to commit transaction adding amount to reserve\n");
- return GNUNET_SYSERR;
+ return reserves_update (cls,
+ session,
+ &updated_reserve);
}
- return GNUNET_OK;
-
- rollback:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Transaction failed, doing rollback\n");
- postgres_rollback (cls,
- session);
- return GNUNET_SYSERR;
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index f79839246..701c20c79 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -162,7 +162,6 @@ check_reserve (struct TALER_EXCHANGEDB_Session *session,
struct TALER_EXCHANGEDB_Reserve reserve;
reserve.pub = *pub;
-
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->reserve_get (plugin->cls,
session,
@@ -1485,6 +1484,10 @@ run (void *cls)
goto drop;
}
+ FAILIF (GNUNET_OK !=
+ plugin->start (plugin->cls,
+ session));
+
/* test DB is empty */
FAILIF (GNUNET_NO !=
plugin->select_payback_above_serial_id (plugin->cls,
@@ -1520,7 +1523,7 @@ run (void *cls)
session,
&rr,
&rr_size));
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->reserves_in_insert (plugin->cls,
session,
&reserve_pub,
@@ -1543,7 +1546,7 @@ run (void *cls)
value.value,
value.fraction,
value.currency));
- FAILIF (GNUNET_OK !=
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->reserves_in_insert (plugin->cls,
session,
&reserve_pub,
@@ -1810,6 +1813,9 @@ run (void *cls)
session,
&deposit_cb,
&deposit));
+ FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
+ plugin->commit (plugin->cls,
+ session));
FAILIF (GNUNET_OK !=
plugin->start (plugin->cls,
session));