exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 0b6b2f3a05fb8fc77182748ed2693ae9fe50070c
parent 33679d241f5f0d25af328a28d6796a41d6c35e4e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri,  9 Oct 2026 22:11:30 +0200

flush coin-history cache between transactions to avoid looking at a stale one

Diffstat:
Msrc/auditor/taler-helper-auditor-coins.c | 44++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+), 0 deletions(-)

diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c @@ -169,6 +169,18 @@ struct CoinHistory static struct CoinHistory coin_histories[MAX_COIN_HISTORIES]; /** + * Indices of the entries of #coin_histories that are in use. Used to + * flush the cache at the end of a pass without touching the entire + * (huge) #coin_histories array. + */ +static unsigned int *used_histories; + +/** + * Length of the #used_histories array. + */ +static unsigned int num_used_histories; + +/** * Should we run checks that only work for exchange-internal audits? */ static int internal_checks; @@ -213,12 +225,43 @@ cache_history (const struct TALER_CoinSpendPublicKeyP *coin_pub, if (NULL != coin_histories[i].tl) TALER_EXCHANGEDB_free_coin_transaction_list (coin_histories[i].tl); + else + GNUNET_array_append (used_histories, + num_used_histories, + i); coin_histories[i].coin_pub = *coin_pub; coin_histories[i].tl = tl; } /** + * Drop all cached coin histories. + * + * Must be called at the end of each pass: within a pass the history we + * fetched is complete (we read it from a consistent snapshot), but the + * exchange keeps adding transactions to coins we already saw. Keeping + * the entry across passes would make us skip the over-spending check + * for every coin the process has already looked at. + */ +static void +flush_coin_histories (void) +{ + for (unsigned int j = 0; j < num_used_histories; j++) + { + struct CoinHistory *ch = &coin_histories[used_histories[j]]; + + TALER_EXCHANGEDB_free_coin_transaction_list (ch->tl); + memset (ch, + 0, + sizeof (*ch)); + } + GNUNET_array_grow (used_histories, + num_used_histories, + 0); +} + + +/** * Obtain a coin's history from our in-memory cache. * * @param coin_pub public key of the coin to cache @@ -2979,6 +3022,7 @@ analyze_coins (void *cls) coins_purse_refunds_serial_id)); qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; cleanup: + flush_coin_histories (); GNUNET_CONTAINER_multihashmap_iterate (cc.denom_summaries, &cleanup_denomination, &cc);