commit 95f6b5cad01ef09f152fb5771c151e5d263866bf
parent c73a73e3471c37e59d63f4fd429e9f4589685003
Author: Florian Dold <dold@taler.net>
Date: Sun, 9 Aug 2026 15:39:08 +0200
wallet-core: migrate legacy exchange retry counters
Diffstat:
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/packages/taler-wallet-core/src/db-converter.test.ts b/packages/taler-wallet-core/src/db-converter.test.ts
@@ -104,6 +104,40 @@ test("converter: sqlite to IndexedDB (reverse direction)", async () => {
await dst.close();
});
+test("converter: discards the legacy exchange update retry counter", async () => {
+ // Wallets written before exchange update retries were moved to
+ // operation_retries still retain this field in the IndexedDB record. The
+ // native schema deliberately has no corresponding column.
+ const src = await makeIdbRunner();
+ await src.runReadWriteTx(async (tx) => {
+ await tx.upsertExchange({
+ baseUrl: "https://exchange.example.com/",
+ detailsPointer: undefined,
+ entryStatus: ExchangeEntryDbRecordStatus.Used,
+ updateStatus: ExchangeEntryDbUpdateStatus.Ready,
+ tosCurrentEtag: undefined,
+ tosAcceptedEtag: undefined,
+ tosAcceptedTimestamp: undefined,
+ lastUpdate: undefined,
+ nextUpdateStamp: timestampPreciseToDb(TalerPreciseTimestamp.now()),
+ lastKeysEtag: undefined,
+ nextRefreshCheckStamp: timestampPreciseToDb(TalerPreciseTimestamp.now()),
+ updateRetryCounter: 8,
+ } as any);
+ });
+
+ const dst = await makeSqliteRunner();
+ await convertWalletDb(src, dst);
+ const exchange = await dst.runReadWriteTx((tx) =>
+ tx.getExchange("https://exchange.example.com/"),
+ );
+ assert.ok(exchange);
+ assert.ok(!("updateRetryCounter" in exchange));
+
+ await src.close();
+ await dst.close();
+});
+
test("converter: reserve rows sharing a public key collapse into one", async () => {
// What an IndexedDB wallet that ever received a peer payment looks like:
// the merge reserve stored once by the exchange entry that points at it,
diff --git a/packages/taler-wallet-core/src/db-converter.ts b/packages/taler-wallet-core/src/db-converter.ts
@@ -84,6 +84,8 @@ const stripId = (rec: unknown): unknown => {
* mistaken for legacy junk without a human putting its name here.
*/
const LEGACY_FIELDS: Record<string, string[]> = {
+ // Removed when exchange update retry state moved to operation_retries.
+ exchanges: ["updateRetryCounter"],
// Removed 2024-06-13 ("remove coinAllocationId, simplify coin history").
coins: ["spendAllocation"],
// Dropped when denomination records were restructured; nothing reads it.
@@ -250,7 +252,8 @@ const COPY_PLAN: CopyStep[][] = [
step(
"exchanges",
(tx) => tx.getExchanges(),
- (tx, r) => tx.upsertExchange(r),
+ (tx, r) => tx.upsertExchange(stripLegacy("exchanges")!(r) as any),
+ stripLegacy("exchanges"),
),
],
[