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:
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,