commit 69159619a3e1bfb816cc91d3cc9150198934b6cf
parent 4a5e39300957413aeccf695a8d14854d3b6437de
Author: Özgür Kesim <oec@codeblau.de>
Date: Wed, 30 Apr 2025 20:06:08 +0200
[exchange] fix reserve history data gathering, passing and parsing
Diffstat:
10 files changed, 70 insertions(+), 48 deletions(-)
diff --git a/src/exchange/taler-exchange-httpd_reserves_history.c b/src/exchange/taler-exchange-httpd_reserves_history.c
@@ -149,9 +149,6 @@ compile_reserve_history (
withdraw->num_coins,
withdraw->denom_pub_hashes,
sizeof(withdraw->denom_pub_hashes[0])),
- GNUNET_JSON_pack_data_auto (
- "selected_h",
- &withdraw->selected_h),
TALER_JSON_pack_amount (
"withdraw_fee",
&withdraw_fee),
@@ -185,6 +182,9 @@ compile_reserve_history (
GNUNET_JSON_pack_uint64 (
"noreveal_index",
withdraw->noreveal_index),
+ GNUNET_JSON_pack_data_auto (
+ "selected_h",
+ &withdraw->selected_h),
GNUNET_JSON_pack_uint64 (
"max_age",
withdraw->max_age))))
diff --git a/src/exchangedb/pg_do_withdraw.c b/src/exchangedb/pg_do_withdraw.c
@@ -58,7 +58,9 @@ TEH_PG_do_withdraw (
(withdraw->age_proof_required)
? GNUNET_PQ_query_param_uint16 (&withdraw->noreveal_index)
: GNUNET_PQ_query_param_null (),
- GNUNET_PQ_query_param_auto_from_type (&withdraw->selected_h),
+ (withdraw->age_proof_required)
+ ? GNUNET_PQ_query_param_auto_from_type (&withdraw->selected_h)
+ : GNUNET_PQ_query_param_null (),
GNUNET_PQ_query_param_array_uint64 (withdraw->num_coins,
withdraw->denom_serials,
pg->conn),
diff --git a/src/exchangedb/pg_get_reserve_by_h_planchets.c b/src/exchangedb/pg_get_reserve_by_h_planchets.c
@@ -53,7 +53,7 @@ TEH_PG_get_reserve_by_h_planchets (
" reserve_pub"
",withdraw_id"
" FROM withdraw"
- " WHERE h_planchets=$1"
+ " WHERE planchets_h=$1"
" LIMIT 1;");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"reserve_by_h_planchets",
diff --git a/src/exchangedb/pg_get_reserve_history.c b/src/exchangedb/pg_get_reserve_history.c
@@ -852,7 +852,7 @@ TEH_PG_get_reserve_history (
",reserve_sig"
",max_age"
",noreveal_index"
- ",h_blind_evs"
+ ",selected_h"
",blinding_seed"
",denom_serials"
",ARRAY("
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
@@ -2167,6 +2167,11 @@ struct TALER_EXCHANGE_ReserveHistoryEntry
json_t *out_authorization_sig;
/**
+ * The running hash over all hashes of blinded planchets of the withrdawal
+ */
+ struct TALER_HashBlindedPlanchetsP planchets_h;
+
+ /**
* If age restriction was required during the protocol
*/
bool age_restricted;
@@ -2177,15 +2182,15 @@ struct TALER_EXCHANGE_ReserveHistoryEntry
uint8_t max_age;
/**
- * If age_restricted is true, the index that is not to be revealed
+ * If @e age_restricted is true, the index that is not to be revealed
* after the initial commitment in /withdraw
*/
uint8_t noreveal_index;
/**
- * The running hash over all hashes of blinded planchets of the withrdawal
+ * If @e age_restricted is true, the hash of the selected blinded planchets
*/
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP selected_h;
/**
* True, if no blinding_seed was provided. The value of
@@ -2910,7 +2915,7 @@ struct TALER_EXCHANGE_WithdrawResponse
/**
* The commitment of the withdraw request, needed for the later calls to /recoup
*/
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP planchets_h;
} ok;
@@ -2928,10 +2933,15 @@ struct TALER_EXCHANGE_WithdrawResponse
uint8_t noreveal_index;
/**
- * The commitment of the withdraw request with age restriction, needed for the
+ * The commitment of the withdraw request, needed for the
* subsequent call to /reveal-withdraw and later calls to /recoup
*/
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP planchets_h;
+
+ /**
+ * The hash of the selected batch of blinded coin envelopes.
+ */
+ struct TALER_HashBlindedPlanchetsP selected_h;
/**
* The number of elements in @e coins, each referring to
@@ -3151,7 +3161,7 @@ struct TALER_EXCHANGE_WithdrawBlindedResponse
/**
* The commitment of the withdraw request, needed for the later calls to /recoup
*/
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP planchets_h;
} ok;
diff --git a/src/lib/exchange_api_reserves_history.c b/src/lib/exchange_api_reserves_history.c
@@ -205,30 +205,33 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
struct TALER_Amount withdraw_amount;
uint8_t max_age = 0;
uint8_t noreveal_index = 0;
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP planchets_h;
+ struct TALER_HashBlindedPlanchetsP selected_h;
struct TALER_ReserveSignatureP reserve_sig;
struct TALER_BlindingMasterSeedP blinding_seed;
- const json_t *j_h_coin_evs;
const json_t *j_denom_pub_hashes;
bool no_max_age;
bool no_noreveal_index;
bool no_blinding_seed;
+ bool no_selected_h;
struct GNUNET_JSON_Specification withdraw_spec[] = {
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
&reserve_sig),
GNUNET_JSON_spec_uint16 ("num_coins",
&num_coins),
- GNUNET_JSON_spec_fixed_auto ("h_planchets",
- &h_planchets),
+ GNUNET_JSON_spec_fixed_auto ("planchets_h",
+ &planchets_h),
TALER_JSON_spec_amount_any ("amount",
&withdraw_amount),
TALER_JSON_spec_amount_any ("withdraw_fee",
&withdraw_fee),
- GNUNET_JSON_spec_array_const ("h_coin_evs",
- &j_h_coin_evs),
GNUNET_JSON_spec_array_const ("denom_pub_hashes",
&j_denom_pub_hashes),
GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_fixed_auto ("selected_h",
+ &selected_h),
+ &no_selected_h),
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_uint8 ("max_age",
&max_age),
&no_max_age),
@@ -253,20 +256,14 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
return GNUNET_SYSERR;
}
- if (no_max_age != no_noreveal_index)
+ if ((no_max_age != no_noreveal_index) ||
+ (no_max_age != no_selected_h))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
rh->details.withdraw.age_restricted = ! no_max_age;
- if ((num_coins != json_array_size (j_h_coin_evs)) ||
- (num_coins != json_array_size (j_denom_pub_hashes)))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
/* Check that the signature is a valid withdraw request */
{
struct TALER_Amount amount_without_fee;
@@ -284,7 +281,7 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
TALER_wallet_withdraw_verify (
&amount_without_fee,
&withdraw_fee,
- &h_planchets,
+ &planchets_h,
no_blinding_seed ? NULL : &blinding_seed,
no_max_age ? NULL : &uc->keys->age_mask,
no_max_age ? 0 : max_age,
@@ -301,7 +298,8 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
rh->details.withdraw.fee = withdraw_fee;
rh->details.withdraw.age_restricted = ! no_max_age;
rh->details.withdraw.max_age = max_age;
- rh->details.withdraw.h_planchets = h_planchets;
+ rh->details.withdraw.planchets_h = planchets_h;
+ rh->details.withdraw.selected_h = selected_h;
rh->details.withdraw.noreveal_index = noreveal_index;
rh->details.withdraw.no_blinding_seed = no_blinding_seed;
if (! no_blinding_seed)
diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c
@@ -180,9 +180,9 @@ struct TALER_EXCHANGE_WithdrawBlindedHandle
struct TALER_EXCHANGE_Keys *keys;
/**
- * The hash of the planchets
+ * The hash of all the planchets
*/
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP planchets_h;
/**
* Seed used for the derival of blinding factors for denominations
@@ -222,6 +222,11 @@ struct TALER_EXCHANGE_WithdrawBlindedHandle
uint8_t max_age;
/**
+ * If @e with_age_proof is true, the hash of all the selected planchets
+ */
+ struct TALER_HashBlindedPlanchetsP selected_h;
+
+ /**
* Length of the either the @e blinded.input or
* the @e blinded.with_age_proof_input array,
* depending on @e with_age_proof.
@@ -462,7 +467,7 @@ withdraw_blinded_ok (
response.details.ok.num_sigs = wbh->num_input;
response.details.ok.blinded_denom_sigs = denoms_sig;
- response.details.ok.h_planchets = wbh->h_planchets;
+ response.details.ok.planchets_h = wbh->planchets_h;
wbh->callback (
wbh->callback_cls,
&response);
@@ -493,7 +498,7 @@ withdraw_blinded_created (
struct TALER_EXCHANGE_WithdrawBlindedResponse response = {
.hr.reply = j_response,
.hr.http_status = MHD_HTTP_CREATED,
- .details.created.h_planchets = wbh->h_planchets,
+ .details.created.planchets_h = wbh->planchets_h,
.details.created.num_coins = wbh->num_input,
};
struct TALER_ExchangeSignatureP exchange_sig;
@@ -518,7 +523,7 @@ withdraw_blinded_created (
if (GNUNET_OK !=
TALER_exchange_online_withdraw_age_confirmation_verify (
- &wbh->h_planchets,
+ &wbh->planchets_h,
response.details.created.noreveal_index,
&response.details.created.exchange_pub,
&exchange_sig))
@@ -844,14 +849,14 @@ perform_withdraw_protocol (
/* Build the hash of the planchets */
GNUNET_CRYPTO_hash_context_finish (
coins_hctx,
- &wbh->h_planchets.hash);
+ &wbh->planchets_h.hash);
coins_hctx = NULL;
/* Sign the request */
TALER_wallet_withdraw_sign (
&wbh->amount,
&wbh->fee,
- &wbh->h_planchets,
+ &wbh->planchets_h,
wbh->blinding_seed,
wbh->with_age_proof ? &wbh->age_mask: NULL,
wbh->with_age_proof ? wbh->max_age : 0,
@@ -964,7 +969,7 @@ copy_results (
resp.details.ok.num_sigs = wbr->details.ok.num_sigs;
resp.details.ok.coin_details = details;
- resp.details.ok.h_planchets = wbr->details.ok.h_planchets;
+ resp.details.ok.planchets_h = wbr->details.ok.planchets_h;
memset (details,
0,
sizeof(details));
diff --git a/src/testing/testing_api_cmd_age_withdraw.c b/src/testing/testing_api_cmd_age_withdraw.c
@@ -149,7 +149,12 @@ struct AgeWithdrawState
/**
* The hash of the commitment, needed for the reveal step.
*/
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP planchets_h;
+
+ /**
+ * The hash of the selected blinded planchets
+ */
+ struct TALER_HashBlindedPlanchetsP selected_h;
/**
* Set to the KYC requirement payto hash *if* the exchange replied with a
@@ -199,8 +204,10 @@ age_withdraw_cb (
{
case MHD_HTTP_CREATED:
aws->noreveal_index = response->details.created.noreveal_index;
- aws->h_planchets = response->details.created.h_planchets;
- aws->reserve_history.details.withdraw.h_planchets = aws->h_planchets;
+ aws->planchets_h = response->details.created.planchets_h;
+ aws->selected_h = response->details.created.selected_h;
+ aws->reserve_history.details.withdraw.planchets_h = aws->planchets_h;
+ aws->reserve_history.details.withdraw.selected_h = aws->selected_h;
aws->reserve_history.details.withdraw.noreveal_index = aws->noreveal_index;
aws->kappa_seed = response->details.created.kappa_seed;
@@ -445,7 +452,7 @@ age_withdraw_traits (
&aws->denoms_pub[idx]),
TALER_TESTING_make_trait_reserve_priv (&aws->reserve_priv),
TALER_TESTING_make_trait_reserve_pub (&aws->reserve_pub),
- TALER_TESTING_make_trait_withdraw_commitment (&aws->h_planchets),
+ TALER_TESTING_make_trait_withdraw_commitment (&aws->planchets_h),
TALER_TESTING_make_trait_amounts (idx,
&out->amount),
/* FIXME[oec]: add legal requirement to response and handle it here, as well
@@ -712,7 +719,7 @@ age_reveal_withdraw_run (
TALER_TESTING_interpreter_get_context (is),
TALER_TESTING_get_exchange_url (is),
aws->num_coins,
- &aws->h_planchets,
+ &aws->planchets_h,
&revealed_seeds,
age_reveal_withdraw_cb,
awrs);
diff --git a/src/testing/testing_api_cmd_batch_withdraw.c b/src/testing/testing_api_cmd_batch_withdraw.c
@@ -162,7 +162,7 @@ struct BatchWithdrawState
/**
* The commitment of the call to withdraw, needed later for recoup.
*/
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP planchets_h;
};
@@ -205,7 +205,7 @@ batch_withdraw_cb (void *cls,
TALER_denom_ewv_copy (&cs->details.alg_values,
&wr->details.ok.coin_details[i].alg_values);
}
- ws->h_planchets = wr->details.ok.h_planchets;
+ ws->planchets_h = wr->details.ok.planchets_h;
break;
case MHD_HTTP_FORBIDDEN:
/* nothing to check */
@@ -456,7 +456,7 @@ batch_withdraw_traits (void *cls,
TALER_TESTING_make_trait_denom_sig (index,
&cs->details.denom_sig),
TALER_TESTING_make_trait_withdraw_seed (&ws->seed),
- TALER_TESTING_make_trait_withdraw_commitment (&ws->h_planchets),
+ TALER_TESTING_make_trait_withdraw_commitment (&ws->planchets_h),
TALER_TESTING_make_trait_reserve_priv (&ws->reserve_priv),
TALER_TESTING_make_trait_reserve_pub (&ws->reserve_pub),
TALER_TESTING_make_trait_amounts (index,
diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c
@@ -168,7 +168,7 @@ struct WithdrawState
/**
* The commitment for the withdraw operation, later needed for /recoup
*/
- struct TALER_HashBlindedPlanchetsP h_planchets;
+ struct TALER_HashBlindedPlanchetsP planchets_h;
/**
* Task scheduled to try later.
@@ -309,7 +309,7 @@ withdraw_cb (void *cls,
ws->bks = wr->details.ok.coin_details[0].blinding_key;
TALER_denom_ewv_copy (&ws->exchange_vals,
&wr->details.ok.coin_details[0].alg_values);
- ws->h_planchets = wr->details.ok.h_planchets;
+ ws->planchets_h = wr->details.ok.planchets_h;
if (0<ws->age)
{
/* copy the age-commitment data */
@@ -548,7 +548,7 @@ withdraw_traits (void *cls,
&ws->coin_priv),
TALER_TESTING_make_trait_withdraw_seed (&ws->seed),
TALER_TESTING_make_trait_blinding_seed (&ws->blinding_seed),
- TALER_TESTING_make_trait_withdraw_commitment (&ws->h_planchets),
+ TALER_TESTING_make_trait_withdraw_commitment (&ws->planchets_h),
TALER_TESTING_make_trait_blinding_key (0 /* only one coin */,
&ws->bks),
TALER_TESTING_make_trait_exchange_wd_value (0 /* only one coin */,