commit b82a40e73234024746e2672e36d706db41437087
parent a82c5bc795cdfb500bf00cceb6515770df02cb24
Author: Özgür Kesim <oec@codeblau.de>
Date: Wed, 7 May 2025 09:40:30 +0200
[exchangedb] fix idempotency check logic for withdraw
In case of a withdraw _without_ age-restriction, the field
noreveal_index is NULL. Therefore, in an idempotency scenario,
the returned out_noreveal_index might be NULL. We now
accept a NULL return value for that in the handler.
Diffstat:
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/exchangedb/exchange_do_withdraw.sql b/src/exchangedb/exchange_do_withdraw.sql
@@ -37,7 +37,7 @@ CREATE FUNCTION exchange_do_withdraw(
OUT out_required_age INT2, -- in years ϵ [0,1..)
OUT out_reserve_birthday INT4,
OUT out_idempotent BOOLEAN,
- OUT out_noreveal_index INT2,
+ OUT out_noreveal_index INT2, -- possibly NULL (if not age-withdraw)
OUT out_nonce_reuse BOOLEAN)
LANGUAGE plpgsql
AS $$
@@ -49,9 +49,7 @@ DECLARE
my_earliest_date DATE;
BEGIN
-- Shards: reserves by reserve_pub (SELECT)
--- reserves_out (INSERT, with CONFLICT detection) by wih
-- reserves by reserve_pub (UPDATE)
--- reserves_in by reserve_pub (SELECT)
-- First, find the reserve
SELECT current_balance
@@ -90,7 +88,7 @@ out_idempotent = FOUND;
IF out_idempotent
THEN
- -- out_idempotent, out_noreveal_index are set, report.
+ -- out_idempotent set, out_noreveal_index possibly set, report.
out_balance_ok = TRUE;
out_age_ok = TRUE;
out_required_age = -1;
diff --git a/src/exchangedb/pg_do_withdraw.c b/src/exchangedb/pg_do_withdraw.c
@@ -81,6 +81,7 @@ TEH_PG_do_withdraw (
GNUNET_PQ_query_param_end
};
bool reserve_found;
+ bool no_noreveal_index;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_bool ("out_reserve_found",
&reserve_found),
@@ -96,8 +97,10 @@ TEH_PG_do_withdraw (
reserve_birthday),
GNUNET_PQ_result_spec_bool ("out_idempotent",
idempotent),
- GNUNET_PQ_result_spec_uint16 ("out_noreveal_index",
- noreveal_index),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_uint16 ("out_noreveal_index",
+ noreveal_index),
+ &no_noreveal_index),
GNUNET_PQ_result_spec_bool ("out_nonce_reuse",
nonce_reuse),
GNUNET_PQ_result_spec_end
@@ -134,5 +137,8 @@ TEH_PG_do_withdraw (
return qs;
if (! reserve_found)
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ if ((withdraw->age_proof_required) &&
+ (idempotent && no_noreveal_index))
+ GNUNET_break (0);
return qs;
}