commit 375c75212cc6e04f3c9c024b7e08c09b4bdb505d
parent 9060502019fccb872af1d62347b84cc2cbc02e81
Author: Florian Dold <dold@taler.net>
Date: Sun, 19 Jul 2026 22:20:28 +0200
wallet: remove runLegacyWalletDbTx and its raw-handle siblings
The remaining callers wanted the fixups store. They now reach it through
wex.db.
Diffstat:
2 files changed, 34 insertions(+), 68 deletions(-)
diff --git a/packages/taler-wallet-core/src/requests.ts b/packages/taler-wallet-core/src/requests.ts
@@ -681,13 +681,13 @@ async function recoverStoredBackup(
});
} else {
await importDb(wex.db.idbHandle(), bd);
- await wex.runLegacyWalletDbTx(async (tx) => {
- await rematerializeTransactions(wex, tx.wtx);
- // Clear fixups. Okay since they are idempotent.
- const fixups = await tx.fixups.getAll();
- for (const f of fixups) {
- await tx.fixups.delete(f.fixupName);
- }
+ // Same order as handleImportDb, and for the same reason: clearing the
+ // log only schedules the repairs, so they have to be re-run here, and
+ // the transaction view has to be built from repaired records.
+ await clearFixupLog(wex);
+ await applyFixups(wex.db);
+ await wex.runWalletDbTx(async (tx) => {
+ await rematerializeTransactions(wex, tx);
});
}
logger.info(`import done`);
@@ -1616,6 +1616,23 @@ async function handleExportDbToFile(
};
}
+/**
+ * Mark every fixup as not applied.
+ *
+ * Goes through the IndexedDB handle rather than the DAL on purpose: the
+ * fixup log is part of that backend. The native sqlite schema has no
+ * equivalent -- it starts clean and evolves through schemaMigrations -- so
+ * there is nothing here for the DAL to abstract over.
+ */
+async function clearFixupLog(wex: WalletExecutionContext): Promise<void> {
+ await wex.db.runAllStoresReadWriteTx({}, async (tx) => {
+ const fixups = await tx.fixups.getAll();
+ for (const f of fixups) {
+ await tx.fixups.delete(f.fixupName);
+ }
+ });
+}
+
async function handleImportDb(
wex: WalletExecutionContext,
req: ImportDbRequest,
@@ -1626,12 +1643,7 @@ async function handleImportDb(
// Clear the fixup log: the records that just arrived may predate any of
// the fixups, whatever this database had applied before the import. They
// are idempotent, so re-running them is safe.
- await wex.runLegacyWalletDbTx(async (tx) => {
- const fixups = await tx.fixups.getAll();
- for (const f of fixups) {
- await tx.fixups.delete(f.fixupName);
- }
- });
+ await clearFixupLog(wex);
// Then actually re-run them. Clearing the log alone only schedules the
// repairs for the next time the database is opened, which for a running
@@ -1755,9 +1767,13 @@ export async function handleTestingRunFixup(
if (fixup.name != req.id) {
continue;
}
- await wex.runLegacyWalletDbTx(async (tx) => {
+ // fixup.fn takes the raw IndexedDB transaction: fixups repair that
+ // backend's records and are not expressible through the DAL.
+ await wex.db.runAllStoresReadWriteTx({}, async (tx) => {
await fixup.fn(tx);
- await rematerializeTransactions(wex, tx.wtx);
+ });
+ await wex.runWalletDbTx(async (tx) => {
+ await rematerializeTransactions(wex, tx);
});
return {};
}
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
@@ -133,13 +133,6 @@ const logger = new Logger("wallet.ts");
export interface WalletExecutionContext {
/**
* Start a database transaction.
- * Uses the legacy transaction that only works with IndexedDB.
- */
- runLegacyWalletDbTx<T>(
- f: (tx: LegacyWalletTxHandle) => Promise<T>,
- ): Promise<T>;
- /**
- * Start a database transaction.
* Uses the database abstraction layer.
*/
runWalletDbTx<T>(f: (tx: WalletDbTransaction) => Promise<T>): Promise<T>;
@@ -227,16 +220,13 @@ export async function migrateMaterializedTransactions(
export async function getDenomInfo(
wex: WalletExecutionContext,
- tx: WalletDbTransaction | LegacyWalletTxHandle,
+ tx: WalletDbTransaction,
exchangeBaseUrl: string,
denomPubHash: string,
): Promise<DenominationInfo | undefined> {
const key = `${exchangeBaseUrl}:${denomPubHash}`;
return wex.ws.denomInfoCache.getOrPut(key, async () => {
- const d =
- "getDenomination" in tx
- ? await tx.getDenomination(exchangeBaseUrl, denomPubHash)
- : await tx.wtx.getDenomination(exchangeBaseUrl, denomPubHash);
+ const d = await tx.getDenomination(exchangeBaseUrl, denomPubHash);
if (d != null) {
return WalletDenomination.toDenomInfo(d);
} else {
@@ -317,9 +307,6 @@ export function getObservedWalletExecutionContext(
async runWalletDbTx(f) {
return await runWalletDbTx(wex, f);
},
- async runLegacyWalletDbTx(f) {
- return await runLegacyWalletDbTx(wex, f);
- },
ws,
cancellationToken,
cts,
@@ -404,10 +391,6 @@ async function handleTxRetries<T>(
throw Error("not reached");
}
-export type LegacyWalletTxHandle = WalletIndexedDbTransaction & {
- wtx: WalletDbTransaction;
-};
-
async function runWalletDbTx<T>(
wex: WalletExecutionContext,
f: (tx: WalletDbTransaction) => Promise<T>,
@@ -464,19 +447,6 @@ async function runWalletDbTx<T>(
});
}
-async function runLegacyWalletDbTx<T>(
- wex: WalletExecutionContext,
- f: (tx: LegacyWalletTxHandle) => Promise<T>,
-): Promise<T> {
- return await handleTxRetries(wex, async () => {
- return await wex.db.runAllStoresReadWriteTx({}, async (tx) => {
- const wtx = new IdbWalletTransaction(tx);
- (tx as any).wtx = wtx;
- return await f(tx as LegacyWalletTxHandle);
- });
- });
-}
-
export function getNormalWalletExecutionContext(
ws: InternalWalletState,
cancellationToken: CancellationToken,
@@ -488,9 +458,6 @@ export function getNormalWalletExecutionContext(
async runWalletDbTx(f) {
return await runWalletDbTx(wex, f);
},
- async runLegacyWalletDbTx(f) {
- return await runLegacyWalletDbTx(wex, f);
- },
ws,
cancellationToken,
cts,
@@ -822,7 +789,7 @@ export class InternalWalletState {
* Run f in a transaction outside any WalletExecutionContext.
*
* Dispatches to the native backend when one is configured, which
- * runStandaloneLegacyWalletDbTx cannot do: that one hands out the raw
+ * the older legacy helper could not do: that one handed out the raw
* IndexedDB handle. Background work (the task shepherd) must go through
* here, or it reads a different database than the one the wallet writes.
*/
@@ -848,23 +815,6 @@ export class InternalWalletState {
);
}
- async runStandaloneLegacyWalletDbTx<T>(
- f: (tx: WalletIndexedDbTransaction, wtx: WalletDbTransaction) => Promise<T>,
- ): Promise<T> {
- if (!this._dbAccessHandle) {
- this._dbAccessHandle = this.createDbAccessHandle(
- CancellationToken.CONTINUE,
- );
- }
- return await this._dbAccessHandle.runAllStoresReadWriteTx(
- {},
- async (mytx) => {
- const tx = new IdbWalletTransaction(mytx);
- return await f(mytx, tx);
- },
- );
- }
-
/**
* When set to false, all tasks that require network will be stopped and
* retried until connection is restored.