taler-typescript-core

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

commit 6acdbc3f0fb4537a5307defc83047578d0a411ea
parent 9c479e2a0d6fcdee72084af56d82efa1e73ef73a
Author: Florian Dold <florian@dold.me>
Date:   Sat, 18 Jul 2026 17:45:39 +0200

fix wrong DB enum values

Diffstat:
Mpackages/taler-wallet-core/src/db-common.ts | 18+++++++++---------
Mpackages/taler-wallet-core/src/db-indexeddb.ts | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-wallet-core/src/wallet.ts | 6+++++-
3 files changed, 87 insertions(+), 10 deletions(-)

diff --git a/packages/taler-wallet-core/src/db-common.ts b/packages/taler-wallet-core/src/db-common.ts @@ -215,14 +215,14 @@ export enum WithdrawalGroupStatus { * Exchange wants KYC info from the user. */ PendingKyc = 0x0100_0005, - SuspendedKyc = 0x0110_005, + SuspendedKyc = 0x0110_0005, /** * Exchange wants KYC info from the user. * KYC link is ready. */ PendingBalanceKyc = 0x0100_0006, - SuspendedBalanceKyc = 0x0110_006, + SuspendedBalanceKyc = 0x0110_0006, /** * Exchange wants KYC info from the user. @@ -230,7 +230,7 @@ export enum WithdrawalGroupStatus { * KYC link is not ready yet, the KYC process is still initializing. */ PendingBalanceKycInit = 0x0100_0007, - SuspendedBalanceKycInit = 0x0110_007, + SuspendedBalanceKycInit = 0x0110_0007, /** * Proposed to the user, has can choose to accept/refuse. @@ -304,7 +304,7 @@ export enum ExchangeEntryDbUpdateStatus { export enum PlanchetStatus { Pending = 0x0100_0000, KycRequired = 0x0100_0001, - WithdrawalDone = 0x0500_000, + WithdrawalDone = 0x0500_0000, AbortedReplaced = 0x0503_0001, } @@ -322,7 +322,7 @@ export enum RefreshCoinStatus { * The refresh for this coin has been frozen, because of a permanent error. * More info in lastErrorPerCoin. */ - Failed = 0x0501_000, + Failed = 0x0501_0000, } export enum RefreshOperationStatus { @@ -335,8 +335,8 @@ export enum RefreshOperationStatus { Suspended = 0x0110_0000, SuspendedRedenominate = 0x0110_0001, - Finished = 0x0500_000, - Failed = 0x0501_000, + Finished = 0x0500_0000, + Failed = 0x0501_0000, } /** @@ -515,8 +515,8 @@ export enum RecoupOperationStatus { Pending = 0x0100_0000, Suspended = 0x0110_0000, - Finished = 0x0500_000, - Failed = 0x0501_000, + Finished = 0x0500_0000, + Failed = 0x0501_0000, } export enum DepositOperationStatus { PendingDeposit = 0x0100_0000, diff --git a/packages/taler-wallet-core/src/db-indexeddb.ts b/packages/taler-wallet-core/src/db-indexeddb.ts @@ -3090,8 +3090,81 @@ export const walletDbFixups: FixupDescription[] = [ fn: fixup20260213RefreshBlunder, name: "fixup20260213RefreshBlunder", }, + // Several status enum members were persisted with a dropped hex + // digit, putting them outside their status range. Rewrite the raw records + // to the corrected values (transactionsMeta is rebuilt separately via the + // MATERIALIZED_TRANSACTIONS_VERSION bump). + { + fn: fixup20260718StatusEnumDigits, + name: "fixup20260718StatusEnumDigits", + }, ]; +async function fixup20260718StatusEnumDigits( + tx: WalletIndexedDbTransaction, +): Promise<void> { + // These OLD (mis-typed, 7-hex-digit) values are what was actually persisted + // before, so we match on the raw numbers on purpose: the + // enum members now resolve to the CORRECTED values and would not match old + // records. + const WG_FIX = new Map<number, number>([ + [0x0110005, 0x0110_0005], // WithdrawalGroupStatus.SuspendedKyc + [0x0110006, 0x0110_0006], // WithdrawalGroupStatus.SuspendedBalanceKyc + [0x0110007, 0x0110_0007], // WithdrawalGroupStatus.SuspendedBalanceKycInit + ]); + await tx.withdrawalGroups.iter().forEachAsync(async (rec) => { + const nv = WG_FIX.get(rec.status); + if (nv !== undefined) { + rec.status = nv as WithdrawalGroupStatus; + await tx.withdrawalGroups.put(rec); + } + }); + + // PlanchetStatus.WithdrawalDone + await tx.planchets.iter().forEachAsync(async (rec) => { + if ((rec.planchetStatus as number) === 0x0500000) { + rec.planchetStatus = 0x0500_0000 as PlanchetStatus; + await tx.planchets.put(rec); + } + }); + + // RefreshOperationStatus.{Finished,Failed} and RefreshCoinStatus.Failed + const RO_FIX = new Map<number, number>([ + [0x0500000, 0x0500_0000], // Finished + [0x0501000, 0x0501_0000], // Failed + ]); + await tx.refreshGroups.iter().forEachAsync(async (rec) => { + let changed = false; + const nv = RO_FIX.get(rec.operationStatus); + if (nv !== undefined) { + rec.operationStatus = nv as RefreshOperationStatus; + changed = true; + } + for (let i = 0; i < rec.statusPerCoin.length; i++) { + if ((rec.statusPerCoin[i] as number) === 0x0501000) { + rec.statusPerCoin[i] = 0x0501_0000 as RefreshCoinStatus; + changed = true; + } + } + if (changed) { + await tx.refreshGroups.put(rec); + } + }); + + // RecoupOperationStatus.{Finished,Failed} + const RC_FIX = new Map<number, number>([ + [0x0500000, 0x0500_0000], // Finished + [0x0501000, 0x0501_0000], // Failed + ]); + await tx.recoupGroups.iter().forEachAsync(async (rec) => { + const nv = RC_FIX.get(rec.operationStatus); + if (nv !== undefined) { + rec.operationStatus = nv as RecoupOperationStatus; + await tx.recoupGroups.put(rec); + } + }); +} + async function fixup20260213RefreshBlunder( tx: WalletIndexedDbTransaction, ): Promise<void> { diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts @@ -566,8 +566,12 @@ type CancelFn = () => void; /** * Incremented each time we want to re-materialize transactions. + * + * Bumped to 4 for BUG-084: after the status-enum digit fixup + * (fixup20260718StatusEnumDigits) rewrites the raw records, transactionsMeta + * and its byStatus index must be rebuilt from the corrected values. */ -const MATERIALIZED_TRANSACTIONS_VERSION = 3; +const MATERIALIZED_TRANSACTIONS_VERSION = 4; async function migrateMaterializedTransactions( wex: WalletExecutionContext,