commit 375dbd875a7e15ab61bee32820257cf467bf7e59
parent d497589c35d3db41c4988ffd1aba83b0d5569b04
Author: Özgür Kesim <oec@codeblau.de>
Date: Thu, 1 May 2025 17:09:52 +0200
[exchange,lib] finish reserve history data handling
- added cs_r_values to JSON output
- finished history data verification (withdraw fees) in C-lib
Diffstat:
2 files changed, 87 insertions(+), 45 deletions(-)
diff --git a/src/exchange/taler-exchange-httpd_reserves_history.c b/src/exchange/taler-exchange-httpd_reserves_history.c
@@ -171,7 +171,20 @@ compile_reserve_history (
json_decref (json_history);
return NULL;
}
-#pragma message "also pack cs_r_values"
+ if (0!=
+ json_object_update_new (
+ j_entry,
+ GNUNET_JSON_PACK (
+ TALER_JSON_pack_array_of_data (
+ "cs_r_values",
+ withdraw->num_cs_r_values,
+ withdraw->cs_r_values,
+ sizeof(withdraw->cs_r_values[0])))))
+ {
+ GNUNET_break (0);
+ json_decref (json_history);
+ return NULL;
+ }
}
if (withdraw->age_proof_required)
{
diff --git a/src/lib/exchange_api_reserves_history.c b/src/lib/exchange_api_reserves_history.c
@@ -203,13 +203,15 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
uint16_t num_coins;
struct TALER_Amount withdraw_fee;
struct TALER_Amount withdraw_amount;
+ struct TALER_Amount amount_without_fee;
uint8_t max_age = 0;
uint8_t noreveal_index = 0;
struct TALER_HashBlindedPlanchetsP planchets_h;
struct TALER_HashBlindedPlanchetsP selected_h;
struct TALER_ReserveSignatureP reserve_sig;
struct TALER_BlindingMasterSeedP blinding_seed;
- const json_t *j_denom_pub_hashes;
+ struct TALER_DenominationHashP *denom_pub_hashes;
+ size_t num_denom_pub_hashes;
bool no_max_age;
bool no_noreveal_index;
bool no_blinding_seed;
@@ -225,8 +227,9 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
&withdraw_amount),
TALER_JSON_spec_amount_any ("withdraw_fee",
&withdraw_fee),
- GNUNET_JSON_spec_array_const ("denom_pub_hashes",
- &j_denom_pub_hashes),
+ TALER_JSON_spec_array_of_denom_pub_h ("denom_pub_hashes",
+ &num_denom_pub_hashes,
+ &denom_pub_hashes),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("selected_h",
&selected_h),
@@ -264,38 +267,40 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
}
rh->details.withdraw.age_restricted = ! no_max_age;
- /* Check that the signature is a valid withdraw request */
+ if (num_coins != num_denom_pub_hashes)
{
- struct TALER_Amount amount_without_fee;
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (withdraw_spec);
+ return GNUNET_SYSERR;
+ }
- if (0>TALER_amount_subtract (
- &amount_without_fee,
- &withdraw_amount,
- &withdraw_fee))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
+ /* Check that the signature is a valid withdraw request */
+ if (0>TALER_amount_subtract (
+ &amount_without_fee,
+ &withdraw_amount,
+ &withdraw_fee))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
- if (GNUNET_OK !=
- TALER_wallet_withdraw_verify (
- &amount_without_fee,
- &withdraw_fee,
- &planchets_h,
- no_blinding_seed ? NULL : &blinding_seed,
- no_max_age ? NULL : &uc->keys->age_mask,
- no_max_age ? 0 : max_age,
- uc->reserve_pub,
- &reserve_sig))
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (withdraw_spec);
- return GNUNET_SYSERR;
- }
+ if (GNUNET_OK !=
+ TALER_wallet_withdraw_verify (
+ &amount_without_fee,
+ &withdraw_fee,
+ &planchets_h,
+ no_blinding_seed ? NULL : &blinding_seed,
+ no_max_age ? NULL : &uc->keys->age_mask,
+ no_max_age ? 0 : max_age,
+ uc->reserve_pub,
+ &reserve_sig))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (withdraw_spec);
+ return GNUNET_SYSERR;
}
rh->details.withdraw.num_coins = num_coins;
- rh->details.withdraw.fee = withdraw_fee;
rh->details.withdraw.age_restricted = ! no_max_age;
rh->details.withdraw.max_age = max_age;
rh->details.withdraw.planchets_h = planchets_h;
@@ -305,30 +310,56 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
if (! no_blinding_seed)
rh->details.withdraw.blinding_seed = blinding_seed;
-
-#pragma message "finish parsing and verification of withdraw history entry"
-#if 0
/* check that withdraw fee matches expectations! */
{
const struct TALER_EXCHANGE_Keys *key_state;
- const struct TALER_EXCHANGE_DenomPublicKey *dki;
+ struct TALER_Amount fee_acc;
+ struct TALER_Amount amount_acc;
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_set_zero (withdraw_amount.currency,
+ &fee_acc));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_set_zero (withdraw_amount.currency,
+ &amount_acc));
key_state = uc->keys;
- dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
- &h_denom_pub);
+
+ /* accumulate the withdraw fees */
+ for (size_t i=0; i < num_coins; i++)
+ {
+ const struct TALER_EXCHANGE_DenomPublicKey *dki;
+ dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
+ &denom_pub_hashes[i]);
+ if (NULL == dki)
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (withdraw_spec);
+ return GNUNET_SYSERR;
+ }
+ TALER_amount_add (&fee_acc,
+ &fee_acc,
+ &dki->fees.withdraw);
+ TALER_amount_add (&amount_acc,
+ &amount_acc,
+ &dki->value);
+ }
+
if ( (GNUNET_YES !=
- TALER_amount_cmp_currency (&amount_with_fee,
- &dki->fees.withdraw)) ||
+ TALER_amount_cmp_currency (&fee_acc,
+ &withdraw_fee)) ||
(0 !=
- TALER_amount_cmp (&amount_with_fee,
- &dki->fees.withdraw)) )
+ TALER_amount_cmp (&amount_acc,
+ &amount_without_fee)) )
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (withdraw_spec);
return GNUNET_SYSERR;
}
- rh->details.withdraw.fee = amount_with_fee;
+ rh->details.withdraw.fee = withdraw_fee;
}
+
+ #pragma message "is out_authorization_sig still needed? Not set anywhere"
rh->details.withdraw.out_authorization_sig
= json_object_get (transaction,
"signature");
@@ -337,8 +368,8 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
"uuid" array to remember the hashes of all
signatures, and compare the hashes to find
duplicates. */
- GNUNET_CRYPTO_hash (&sig,
- sizeof (sig),
+ GNUNET_CRYPTO_hash (&reserve_sig,
+ sizeof (reserve_sig),
&uc->uuids[uc->uuid_off]);
for (unsigned int i = 0; i<uc->uuid_off; i++)
{
@@ -362,8 +393,6 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
GNUNET_JSON_parse_free (withdraw_spec);
return GNUNET_SYSERR;
}
-#endif
-
return GNUNET_OK;
}