-fix purse deposit when done against non-existing reserve

This commit is contained in:
Christian Grothoff 2022-08-24 09:55:18 +02:00
parent 4edb5050d9
commit bc107b5958
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
2 changed files with 44 additions and 17 deletions

View File

@ -908,8 +908,8 @@ prepare_statements (struct PostgresClosure *pg)
" out_balance_ok AS balance_ok" " out_balance_ok AS balance_ok"
",out_conflict AS conflict" ",out_conflict AS conflict"
" FROM exchange_do_purse_deposit" " FROM exchange_do_purse_deposit"
" ($1,$2,$3,$4,$5,$6,$7,$8);", " ($1,$2,$3,$4,$5,$6,$7,$8,$9);",
8), 9),
/* Used in #postgres_update_aggregation_transient() */ /* Used in #postgres_update_aggregation_transient() */
GNUNET_PQ_make_prepare ( GNUNET_PQ_make_prepare (
"set_purse_balance", "set_purse_balance",
@ -15875,6 +15875,7 @@ postgres_do_purse_deposit (
bool *conflict) bool *conflict)
{ {
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
struct GNUNET_TIME_Timestamp reserve_expiration;
uint64_t partner_id = 0; /* FIXME #7271: WAD support... */ uint64_t partner_id = 0; /* FIXME #7271: WAD support... */
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&partner_id), GNUNET_PQ_query_param_uint64 (&partner_id),
@ -15883,6 +15884,7 @@ postgres_do_purse_deposit (
GNUNET_PQ_query_param_auto_from_type (coin_pub), GNUNET_PQ_query_param_auto_from_type (coin_pub),
GNUNET_PQ_query_param_auto_from_type (coin_sig), GNUNET_PQ_query_param_auto_from_type (coin_sig),
TALER_PQ_query_param_amount (amount_minus_fee), TALER_PQ_query_param_amount (amount_minus_fee),
GNUNET_PQ_query_param_timestamp (&reserve_expiration),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
@ -15893,6 +15895,10 @@ postgres_do_purse_deposit (
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
reserve_expiration
= GNUNET_TIME_absolute_to_timestamp (
GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
pg->legal_reserve_expiration_time));
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"call_purse_deposit", "call_purse_deposit",
params, params,

View File

@ -1427,6 +1427,7 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_deposit(
IN in_coin_sig BYTEA, IN in_coin_sig BYTEA,
IN in_amount_without_fee_val INT8, IN in_amount_without_fee_val INT8,
IN in_amount_without_fee_frac INT4, IN in_amount_without_fee_frac INT4,
IN in_reserve_expiration INT8,
OUT out_balance_ok BOOLEAN, OUT out_balance_ok BOOLEAN,
OUT out_conflict BOOLEAN) OUT out_conflict BOOLEAN)
LANGUAGE plpgsql LANGUAGE plpgsql
@ -1569,21 +1570,41 @@ THEN
WHERE purse_pub=in_purse_pub; WHERE purse_pub=in_purse_pub;
ELSE ELSE
-- This is a local reserve, update balance immediately. -- This is a local reserve, update balance immediately.
UPDATE reserves INSERT INTO reserves
SET (reserve_pub
current_balance_frac=current_balance_frac+my_amount_frac ,current_balance_frac
- CASE ,current_balance_val
WHEN current_balance_frac + my_amount_frac >= 100000000 ,expiration_date
THEN 100000000 ,gc_date)
ELSE 0 VALUES
END, (my_reserve_pub
current_balance_val=current_balance_val+my_amount_val ,my_amount_frac
+ CASE ,my_amount_val
WHEN current_balance_frac + my_amount_frac >= 100000000 ,in_reserve_expiration
THEN 1 ,in_reserve_expiration)
ELSE 0 ON CONFLICT DO NOTHING;
END
WHERE reserve_pub=my_reserve_pub; IF NOT FOUND
THEN
UPDATE reserves
SET
current_balance_frac=current_balance_frac+my_amount_frac
- CASE
WHEN current_balance_frac + my_amount_frac >= 100000000
THEN 100000000
ELSE 0
END
,current_balance_val=current_balance_val+my_amount_val
+ CASE
WHEN current_balance_frac + my_amount_frac >= 100000000
THEN 1
ELSE 0
END
,expiration_date=GREATEST(expiration_date,in_reserve_expiration)
,gc_date=GREATEST(gc_date,in_reserve_expiration)
WHERE reserve_pub=my_reserve_pub;
END IF;
-- ... and mark purse as finished. -- ... and mark purse as finished.
-- FIXME: combine with UPDATE above? -- FIXME: combine with UPDATE above?