commit cccec1b0c826bff69d9e809f4bd8f33926e2f150
parent c6d64e20bd90d81504c4e64b01b8c07cf944da9f
Author: Florian Dold <florian@dold.me>
Date: Fri, 13 Feb 2026 13:25:20 +0100
wallet-core: use index for denom families instead of manual hashing
Diffstat:
2 files changed, 43 insertions(+), 30 deletions(-)
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
@@ -81,7 +81,6 @@ import {
codecForAny,
encodeCrock,
hash,
- hashTruncate32,
j2s,
stringToBytes,
stringifyScopeInfo,
@@ -175,7 +174,7 @@ export const CURRENT_DB_CONFIG_KEY = "currentMainDbName";
* backwards-compatible way or object stores and indices
* are added.
*/
-export const WALLET_DB_MINOR_VERSION = 27;
+export const WALLET_DB_MINOR_VERSION = 28;
declare const symDbProtocolTimestamp: unique symbol;
@@ -272,10 +271,6 @@ export interface DenomFamilyParams {
feeRefund: AmountString;
}
-export function hashDenomFamilyParams(dfp: DenomFamilyParams): string {
- return encodeCrock(hashTruncate32(stringToBytes(canonicalJson(dfp) + "\0")));
-}
-
/**
* Format of the operation status code: 0x0abc_nnnn
@@ -510,11 +505,10 @@ export interface DenomFees {
export interface DenominationFamilyRecord {
denominationFamilySerial?: number;
- /**
- * Hash (32 byte truncated SHA-512) of canonicalized parameter JSON.
- */
- familyParamsHash: string;
familyParams: DenomFamilyParams;
+
+ // Reserved legacy fields:
+ // * familyParamsHash
}
/**
@@ -3230,13 +3224,23 @@ export const WalletStoresV1 = {
versionAdded: 27,
},
),
- byFamilyParamsHash: describeIndex(
- "byFamilyParamsHash",
- "familyParamsHash",
+ byFamilyParms: describeIndex(
+ "byFamilyParams",
+ [
+ "familyParams.exchangeBaseUrl",
+ "familyParams.exchangeMasterPub",
+ "familyParams.value",
+ "familyParams.feeWithdraw",
+ "familyParams.feeDeposit",
+ "familyParams.feeRefresh",
+ "familyParams.feeRefund",
+ ],
{
- versionAdded: 27,
+ versionAdded: 28,
},
),
+ // Reserved legacy index names:
+ // * byFamilyParamsHash
},
),
exchanges: describeStore(
@@ -3964,16 +3968,25 @@ async function fixup20260203DenomFamilyMigration(
continue;
}
}
- const fph = hashDenomFamilyParams(fp);
+ const familyParamsIndexKey = [
+ fp.exchangeBaseUrl,
+ fp.exchangeMasterPub,
+ fp.value,
+ fp.feeWithdraw,
+ fp.feeDeposit,
+ fp.feeRefresh,
+ fp.feeRefund,
+ ];
const dfRec =
- await tx.denominationFamilies.indexes.byFamilyParamsHash.get(fph);
+ await tx.denominationFamilies.indexes.byFamilyParms.get(
+ familyParamsIndexKey,
+ );
let denominationFamilySerial;
if (dfRec) {
denominationFamilySerial = dfRec.denominationFamilySerial;
} else {
const insRes = await tx.denominationFamilies.put({
familyParams: fp,
- familyParamsHash: fph,
});
denominationFamilySerial = insRes.key;
}
diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts
@@ -154,7 +154,6 @@ import {
WalletDbHelpers,
WalletDbReadOnlyTransaction,
WalletDbReadWriteTransaction,
- hashDenomFamilyParams,
timestampAbsoluteFromDb,
timestampOptionalPreciseFromDb,
timestampPreciseFromDb,
@@ -1814,9 +1813,7 @@ export async function updateExchangeFromUrlHandler(
let peerPaymentsDisabled = checkPeerPaymentsDisabled(keysInfo);
const denomInfos: DenominationInfo[] = [];
- // Se of all current denoms offered by exchange
const currentDenomSet = new Set<string>();
- const fpMap = new Map<DenominationInfo, string>();
for (const denomFamily of keysInfo.denominations) {
switch (denomFamily.cipher) {
case "CS":
@@ -1864,7 +1861,6 @@ export async function updateExchangeFromUrlHandler(
masterSig: denom.master_sig,
};
denomInfos.push(di);
- fpMap.set(di, hashDenomFamilyParams(fp));
currentDenomSet.add(denomPubHash);
}
}
@@ -2046,14 +2042,18 @@ export async function updateExchangeFromUrlHandler(
for (const currentDenom of denomInfos) {
// FIXME: Check if we really already need the denomination.
- const familyParamHash = fpMap.get(currentDenom);
- if (!familyParamHash) {
- logger.error("missing family param hash");
- continue;
- }
+ const familyParamsIndexKey = [
+ currentDenom.exchangeBaseUrl,
+ currentDenom.exchangeMasterPub,
+ currentDenom.value,
+ currentDenom.feeWithdraw,
+ currentDenom.feeDeposit,
+ currentDenom.feeRefresh,
+ currentDenom.feeRefund,
+ ];
let fpRec: DenominationFamilyRecord | undefined =
- await tx.denominationFamilies.indexes.byFamilyParamsHash.get(
- familyParamHash,
+ await tx.denominationFamilies.indexes.byFamilyParms.get(
+ familyParamsIndexKey,
);
let denominationFamilySerial;
if (fpRec == null) {
@@ -2068,7 +2068,6 @@ export async function updateExchangeFromUrlHandler(
};
fpRec = {
familyParams: fp,
- familyParamsHash: familyParamHash,
};
const insRes = await tx.denominationFamilies.put(fpRec);
denominationFamilySerial = insRes.key;
@@ -2144,6 +2143,7 @@ export async function updateExchangeFromUrlHandler(
logger.info(
`setting denomination ${x.denomPubHash} to offered=false`,
);
+ await tx.denominations.put(x);
}
} else {
if (!x.isOffered) {
@@ -2151,9 +2151,9 @@ export async function updateExchangeFromUrlHandler(
logger.info(
`setting denomination ${x.denomPubHash} to offered=true`,
);
+ await tx.denominations.put(x);
}
}
- await tx.denominations.put(x);
}
logger.trace("done updating denominations in database");