diff --git a/src/exchangedb/pg_batch_reserves_in_insert.c b/src/exchangedb/pg_batch_reserves_in_insert.c index 216de96be..fd056e0ca 100644 --- a/src/exchangedb/pg_batch_reserves_in_insert.c +++ b/src/exchangedb/pg_batch_reserves_in_insert.c @@ -25,6 +25,7 @@ #include "pg_batch_reserves_in_insert.h" #include "pg_helper.h" #include "pg_start.h" +#include "pg_rollback.h" #include "pg_start_read_committed.h" #include "pg_commit.h" #include "pg_reserves_get.h" @@ -97,7 +98,6 @@ TEH_PG_batch_reserves_in_insert (void *cls, { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (&reserves->reserve_pub), /*$1*/ - TALER_PQ_query_param_amount (&reserves->balance), /*$2+3*/ GNUNET_PQ_query_param_timestamp (&expiry), /*$4*/ GNUNET_PQ_query_param_timestamp (&gc), /*$5*/ GNUNET_PQ_query_param_uint64 (&reserves->wire_reference), /*6*/ @@ -121,6 +121,7 @@ TEH_PG_batch_reserves_in_insert (void *cls, GNUNET_PQ_result_spec_end }; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reserve does not exist; creating a new one\n"); /* Note: query uses 'on conflict do nothing' */ @@ -129,21 +130,23 @@ TEH_PG_batch_reserves_in_insert (void *cls, "SELECT " "out_reserve_found AS conflicted" ",transaction_duplicate" - ",ruuid" + ",ruuid AS reserve_uuid" " FROM batch_reserves_in" - " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12);"); + " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);"); qs1 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "reserve_create", params, rs); + + if (qs1 < 0) return qs1; } - + if ((int)conflicted == 0 && (int)transaction_duplicate == 1) + TEH_PG_rollback(pg); notify_on_reserve (pg, &reserves->reserve_pub); - return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; } diff --git a/src/exchangedb/procedures.sql b/src/exchangedb/procedures.sql index 1e96301a4..ff282735c 100644 --- a/src/exchangedb/procedures.sql +++ b/src/exchangedb/procedures.sql @@ -2522,15 +2522,13 @@ END $$; CREATE OR REPLACE FUNCTION batch_reserves_in( IN in_reserve_pub BYTEA, - IN in_current_balance_val INT8, - IN in_current_balance_frac INT4, IN in_expiration_date INT8, IN in_gc_date INT8, IN in_wire_ref INT8, IN in_credit_val INT8, IN in_credit_frac INT4, IN in_exchange_account_name VARCHAR, - IN in_exectution_date INT4, + IN in_exectution_date INT8, IN in_wire_source_h_payto BYTEA, ---h_payto IN in_payto_uri VARCHAR, IN in_reserve_expiration INT8, @@ -2545,15 +2543,6 @@ DECLARE my_amount_frac INT4; BEGIN - SELECT - current_balance_val - ,current_balance_frac - INTO - my_amount_val - ,my_amount_frac - FROM reserves - WHERE reserves.reserve_pub = in_reserve_pub; - INSERT INTO reserves (reserve_pub ,current_balance_val @@ -2562,18 +2551,19 @@ BEGIN ,gc_date) VALUES (in_reserve_pub - ,in_current_balance_val - ,in_current_balance_frac + ,in_credit_val + ,in_credit_frac ,in_expiration_date ,in_gc_date) - ON CONFLICT DO NOTHING - RETURNING reserves.reserve_uuid INTO ruuid; + ON CONFLICT DO NOTHING + RETURNING reserve_uuid INTO ruuid; - --IF THE INSERT WAS NOT SUCCESSFUL, REMEMBER IT - IF NOT FOUND + IF FOUND THEN + -- We made a change, so the reserve did not previously exist. out_reserve_found = FALSE; ELSE + -- We made no change, which means the reserve existed. out_reserve_found = TRUE; END IF; @@ -2597,42 +2587,52 @@ BEGIN VALUES (in_reserve_pub ,in_wire_ref - ,in_current_balance_val + ,in_credit_val ,in_credit_frac - ,in_exchange_account_section + ,in_exchange_account_name ,in_wire_source_h_payto - ,in_execution_date); + ,in_expiration_date); --IF THE INSERTION WAS A SUCCESS IT MEANS NO DUPLICATED TRANSACTION IF FOUND THEN transaction_duplicate = FALSE; - IF out_reserve_found = TRUE + IF out_reserve_found THEN UPDATE reserves SET - in_current_balance_frac=in_current_balance_frac+my_amount_frac + current_balance_frac = current_balance_frac+in_credit_frac - CASE - WHEN in_current_balance_frac + my_amount_frac >= 100000000 + WHEN current_balance_frac + in_credit_frac >= 100000000 THEN 100000000 - ELSE 0 + ELSE 1 END - ,in_current_balance_val=in_current_balance_val+my_amount_val + ,current_balance_val = current_balance_val+in_credit_val + CASE - WHEN in_current_balance_frac + my_amount_frac >= 100000000 + WHEN current_balance_frac + in_credit_frac >= 100000000 THEN 1 ELSE 0 END - ,expiration_date=GREATEST(in_expiration_date,in_reserve_expiration) - ,gc_date=GREATEST(in_gc_date,in_reserve_expiration) + ,expiration_date=GREATEST(expiration_date,in_expiration_date) + ,gc_date=GREATEST(gc_date,in_expiration_date) WHERE reserves.reserve_pub=in_reserve_pub; + out_reserve_found = TRUE; RETURN; ELSE + out_reserve_found=FALSE; RETURN; END IF; + out_reserve_found = TRUE; ELSE transaction_duplicate = TRUE; - RETURN; + IF out_reserve_found + THEN + out_reserve_found = TRUE; + RETURN; + ELSE + out_reserve_found = FALSE; + RETURN; + END IF; END IF; END $$; diff --git a/src/exchangedb/test_exchangedb_by_j.c b/src/exchangedb/test_exchangedb_by_j.c index eb600103e..831416b4d 100644 --- a/src/exchangedb/test_exchangedb_by_j.c +++ b/src/exchangedb/test_exchangedb_by_j.c @@ -98,9 +98,9 @@ run (void *cls) goto cleanup; } - for (unsigned int i = 0; i< 8; i++) + for (unsigned int i = 0; i< 7; i++) { - static unsigned int batches[] = {1, 1, 0, 2, 4, 16, 64, 256}; + static unsigned int batches[] = {1, 1, 2, 4, 16, 64, 256}; const char *sndr = "payto://x-taler-bank/localhost:8080/1"; struct TALER_Amount value; unsigned int batch_size = batches[i]; @@ -124,6 +124,7 @@ run (void *cls) reserves[k].execution_time = ts; reserves[k].sender_account_details = sndr; reserves[k].exchange_account_name = "name"; + reserves[k].wire_reference = k; } FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=