commit cc93bf0a7c79e6bf62a28a4e81d67956393b5b8b
parent 475ac2e513e2b7a1b576592749038ee4ec61d3e8
Author: Florian Dold <florian@dold.me>
Date: Mon, 15 Sep 2025 14:21:17 +0200
wallet-core: fixup for missing exchanges in pay-merchant transactions
Some old wallets did not set this field properly.
Diffstat:
1 file changed, 48 insertions(+), 0 deletions(-)
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
@@ -66,6 +66,7 @@ import {
TokenIssuePublicKey,
TokenUseSig,
TransactionIdStr,
+ TransactionType,
UnblindedDenominationSignature,
WireInfo,
WithdrawalExchangeAccountDetails,
@@ -90,6 +91,7 @@ import {
describeStoreV2,
openDatabase,
} from "./query.js";
+import { constructTransactionIdentifier } from "./transactions.js";
/**
* This file contains the database schema of the Taler wallet together
@@ -3601,9 +3603,55 @@ export const walletDbFixups: FixupDescription[] = [
fn: fixup20250908TopsBlunder,
name: "fixup20250908TopsBlunder",
},
+ // Removing this would cause old transactions
+ // to show up under multip,e exchanges
+ {
+ fn: fixup20250915TransactionsScope,
+ name: "fixup20250915TransactionsScope",
+ },
];
/**
+ * Some old payment transactions didn't correctly
+ * set the involved exchanges.
+ *
+ * This fixup sets the exchanges of a payment transaction
+ * based on the coin selection.
+ */
+async function fixup20250915TransactionsScope(
+ tx: WalletDbAllStoresReadWriteTransaction,
+): Promise<void> {
+ await tx.purchases.iter().forEachAsync(async (rec) => {
+ if (
+ (rec.exchanges?.length ?? 0) == 0 &&
+ rec.payInfo?.payCoinSelection != null
+ ) {
+ const pcs = rec.payInfo.payCoinSelection.coinPubs;
+ const exchSet: Set<string> = new Set();
+ for (const pc in pcs) {
+ const coin = await tx.coins.get(pc);
+ if (!coin) {
+ continue;
+ }
+ exchSet.add(coin.exchangeBaseUrl);
+ }
+ rec.exchanges = [...exchSet];
+ rec.exchanges.sort();
+ if (rec.exchanges.length == 0) {
+ // FIXME: Here we might want to do a SPURLOSE exception.
+ logger.warn(
+ `unable to fix up transaction ${constructTransactionIdentifier({
+ tag: TransactionType.Payment,
+ proposalId: rec.proposalId,
+ })}, could not reconstruct exchanges`,
+ );
+ }
+ await tx.purchases.put(rec);
+ }
+ });
+}
+
+/**
* TOPS accidentally revoked keys.
* Make sure to re-request keys and re-do denom selection
* for withdrawal groups with zero selected denominations.