commit 78c6b7a6f792f9d1eb1544dc15949283e7852e3c
parent 5ef82cb7e4b9b645027ff7e74c39f7af0826d90f
Author: Florian Dold <florian@dold.me>
Date: Mon, 15 Sep 2025 15:48:38 +0200
wallet-core: improve datenspuren fixup, rematerialize transactions after fixup
Diffstat:
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
@@ -91,7 +91,7 @@ import {
describeStoreV2,
openDatabase,
} from "./query.js";
-import { constructTransactionIdentifier } from "./transactions.js";
+import { rematerializeTransactions } from "./transactions.js";
/**
* This file contains the database schema of the Taler wallet together
@@ -3622,6 +3622,7 @@ async function fixup20250915TransactionsScope(
tx: WalletDbAllStoresReadWriteTransaction,
): Promise<void> {
await tx.purchases.iter().forEachAsync(async (rec) => {
+ let hadFix = false;
if (
(rec.exchanges?.length ?? 0) == 0 &&
rec.payInfo?.payCoinSelection != null
@@ -3638,14 +3639,16 @@ async function fixup20250915TransactionsScope(
rec.exchanges = [...exchSet];
rec.exchanges.sort();
if (rec.exchanges.length == 0) {
- // FIXME: Here we might want to do a SPURLOSE exception.
+ // For old SPURLOS transactions, set exchange manually
+ // when we can't infer it.
+ if (rec.timestamp <= 1736942400000_000 && rec.download?.currency === "SPURLOS") {
+ rec.exchanges = ["https://exchange.taler.datenspuren.de/"];
+ }
logger.warn(
- `unable to fix up transaction ${constructTransactionIdentifier({
- tag: TransactionType.Payment,
- proposalId: rec.proposalId,
- })}, could not reconstruct exchanges`,
+ `unable to fix up pay transaction ${rec.proposalId}, could not reconstruct exchanges`,
);
}
+ hadFix = true;
await tx.purchases.put(rec);
}
});
@@ -3702,8 +3705,9 @@ async function fixup20250908TopsBlunder(
export async function applyFixups(
db: DbAccess<typeof WalletStoresV1>,
-): Promise<void> {
+): Promise<number> {
logger.trace("applying fixups");
+ let count = 0;
await db.runAllStoresReadWriteTx({}, async (tx) => {
for (const fixupInstruction of walletDbFixups) {
logger.trace(`checking fixup ${fixupInstruction.name}`);
@@ -3716,8 +3720,10 @@ export async function applyFixups(
await tx.fixups.put({
fixupName: fixupInstruction.name,
});
+ count++;
}
});
+ return count;
}
/**
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
@@ -2983,7 +2983,21 @@ export class InternalWalletState {
const myDb = await openTalerDatabase(this.idbFactory, myVersionChange);
this._indexedDbHandle = myDb;
const dbAccess = this.createDbAccessHandle(CancellationToken.CONTINUE);
- await applyFixups(dbAccess);
+ const count = await applyFixups(dbAccess);
+ if (count > 0) {
+ const oc = {
+ observe(evt: any) {},
+ };
+ const wex = getNormalWalletExecutionContext(
+ this,
+ CancellationToken.CONTINUE,
+ undefined,
+ oc,
+ );
+ await dbAccess.runAllStoresReadWriteTx({}, async (tx) => {
+ await rematerializeTransactions(wex, tx);
+ });
+ }
} catch (e) {
logger.error("error writing to database during initialization");
throw TalerError.fromDetail(TalerErrorCode.WALLET_DB_UNAVAILABLE, {