taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit e733615bc0b754c25215409e299d0e04364e19d7
parent be2c4a1d5926fa9220ff9272cba8b637e4bed8b1
Author: Florian Dold <dold@taler.net>
Date:   Mon, 20 Jul 2026 01:21:50 +0200

wallet: say which denomination a visible-coin-count underflow came from

"coin availability inconsistent" named neither the denomination, the age
nor the exchange.

Diffstat:
Mpackages/taler-wallet-core/src/common.ts | 11++++++++++-
Mpackages/taler-wallet-core/src/refresh.ts | 11++++++++++-
2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts @@ -229,8 +229,17 @@ export async function spendCoins( } coinAvailability.freshCoinCount--; if (coin.visible) { + // Clamped rather than thrown: the visible count is a display + // figure, and refusing to spend a coin over it would be worse + // than showing a stale number. The fresh count above is the + // one that guards spendability, and that does throw. if (!coinAvailability.visibleCoinCount) { - logger.error("coin availability inconsistent"); + logger.error( + `visible coin count underflow for denom ${coin.denomPubHash}` + + ` age ${coin.maxAge} at ${coinAvailability.exchangeBaseUrl}:` + + ` a visible coin was spent but the count is` + + ` ${coinAvailability.visibleCoinCount}`, + ); } else { coinAvailability.visibleCoinCount--; } diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts @@ -1542,8 +1542,17 @@ async function applyRefreshToOldCoins( ); coinAv.freshCoinCount--; if (coin.visible) { + // Clamped rather than thrown: the visible count is a display + // figure, and refusing to spend a coin over it would be worse + // than showing a stale number. The fresh count above is the + // one that guards spendability, and that does throw. if (!coinAv.visibleCoinCount) { - logger.error("coin availability inconsistent"); + logger.error( + `visible coin count underflow for denom ${coin.denomPubHash}` + + ` age ${coin.maxAge} at ${coinAv.exchangeBaseUrl}:` + + ` a visible coin was spent but the count is` + + ` ${coinAv.visibleCoinCount}`, + ); } else { coinAv.visibleCoinCount--; }