DB schema cleanup

This commit is contained in:
Florian Dold 2021-08-24 15:43:06 +02:00
parent a09359bd39
commit 4c41e70565
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
9 changed files with 96 additions and 77 deletions

View File

@ -788,6 +788,33 @@ export interface MakeSyncSignatureRequest {
newHash: string; newHash: string;
} }
/**
* Planchet for a coin during refresh.
*/
export interface RefreshPlanchetInfo {
/**
* Public key for the coin.
*/
publicKey: string;
/**
* Private key for the coin.
*/
privateKey: string;
/**
* Blinded public key.
*/
coinEv: string;
coinEvHash: string;
/**
* Blinding key used.
*/
blindingKey: string;
}
/** /**
* Strategy for loading recovery information. * Strategy for loading recovery information.
*/ */

View File

@ -30,12 +30,11 @@
import { import {
CoinRecord, CoinRecord,
DenominationRecord, DenominationRecord,
RefreshPlanchet,
WireFee, WireFee,
CoinSourceType, CoinSourceType,
} from "../../db.js"; } from "../../db.js";
import { CoinDepositPermission, RecoupRequest } from "@gnu-taler/taler-util"; import { CoinDepositPermission, RecoupRequest, RefreshPlanchetInfo } from "@gnu-taler/taler-util";
// FIXME: These types should be internal to the wallet! // FIXME: These types should be internal to the wallet!
import { import {
BenchmarkResult, BenchmarkResult,
@ -442,7 +441,7 @@ export class CryptoImplementation {
const transferPubs: string[] = []; const transferPubs: string[] = [];
const transferPrivs: string[] = []; const transferPrivs: string[] = [];
const planchetsForGammas: RefreshPlanchet[][] = []; const planchetsForGammas: RefreshPlanchetInfo[][] = [];
for (let i = 0; i < kappa; i++) { for (let i = 0; i < kappa; i++) {
const transferKeyPair = setupRefreshTransferPub( const transferKeyPair = setupRefreshTransferPub(
@ -464,7 +463,7 @@ export class CryptoImplementation {
sessionHc.update(decodeCrock(meltCoinPub)); sessionHc.update(decodeCrock(meltCoinPub));
sessionHc.update(amountToBuffer(valueWithFee)); sessionHc.update(amountToBuffer(valueWithFee));
for (let i = 0; i < kappa; i++) { for (let i = 0; i < kappa; i++) {
const planchets: RefreshPlanchet[] = []; const planchets: RefreshPlanchetInfo[] = [];
for (let j = 0; j < newCoinDenoms.length; j++) { for (let j = 0; j < newCoinDenoms.length; j++) {
const denomSel = newCoinDenoms[j]; const denomSel = newCoinDenoms[j];
for (let k = 0; k < denomSel.count; k++) { for (let k = 0; k < denomSel.count; k++) {
@ -482,7 +481,7 @@ export class CryptoImplementation {
const pubHash = hash(coinPub); const pubHash = hash(coinPub);
const denomPub = decodeCrock(denomSel.denomPub); const denomPub = decodeCrock(denomSel.denomPub);
const ev = rsaBlind(pubHash, blindingFactor, denomPub); const ev = rsaBlind(pubHash, blindingFactor, denomPub);
const planchet: RefreshPlanchet = { const planchet: RefreshPlanchetInfo = {
blindingKey: encodeCrock(blindingFactor), blindingKey: encodeCrock(blindingFactor),
coinEv: encodeCrock(ev), coinEv: encodeCrock(ev),
privateKey: encodeCrock(coinPriv), privateKey: encodeCrock(coinPriv),

View File

@ -134,8 +134,27 @@ export async function openTalerDatabase(
}); });
if (currentMainVersion !== TALER_DB_NAME) { if (currentMainVersion !== TALER_DB_NAME) {
// In the future, the migration logic will be implemented here. switch (currentMainVersion) {
throw Error(`migration from database ${currentMainVersion} not supported`); case "taler-wallet-main-v2": {
// We consider this a pre-release
// development version, no migration is done.
await metaDb
.mktx((x) => ({
metaConfig: x.metaConfig,
}))
.runReadWrite(async (tx) => {
await tx.metaConfig.put({
key: CURRENT_DB_CONFIG_KEY,
value: TALER_DB_NAME,
});
});
break;
}
default:
throw Error(
`migration from database ${currentMainVersion} not supported`,
);
}
} }
const mainDbHandle = await openDatabase( const mainDbHandle = await openDatabase(

View File

@ -46,7 +46,7 @@ import { PayCoinSelection } from "./util/coinSelection.js";
* for all previous versions must be written, which should be * for all previous versions must be written, which should be
* avoided. * avoided.
*/ */
export const TALER_DB_NAME = "taler-wallet-main-v2"; export const TALER_DB_NAME = "taler-wallet-main-v3";
/** /**
* Name of the metadata database. This database is used * Name of the metadata database. This database is used
@ -283,7 +283,7 @@ export interface ExchangeTrustRecord {
/** /**
* Status of a denomination. * Status of a denomination.
*/ */
export enum DenominationStatus { export enum DenominationVerificationStatus {
/** /**
* Verification was delayed. * Verification was delayed.
*/ */
@ -366,10 +366,8 @@ export interface DenominationRecord {
/** /**
* Did we verify the signature on the denomination? * Did we verify the signature on the denomination?
*
* FIXME: Rename to "verificationStatus"?
*/ */
status: DenominationStatus; verificationStatus: DenominationVerificationStatus;
/** /**
* Was this denomination still offered by the exchange the last time * Was this denomination still offered by the exchange the last time
@ -590,35 +588,6 @@ export interface PlanchetRecord {
isFromTip: boolean; isFromTip: boolean;
} }
/**
* Planchet for a coin during refresh.
*
* FIXME: Not used in DB?
*/
export interface RefreshPlanchet {
/**
* Public key for the coin.
*/
publicKey: string;
/**
* Private key for the coin.
*/
privateKey: string;
/**
* Blinded public key.
*/
coinEv: string;
coinEvHash: string;
/**
* Blinding key used.
*/
blindingKey: string;
}
/** /**
* Status of a coin. * Status of a coin.
*/ */
@ -1319,21 +1288,6 @@ export interface WalletBackupConfState {
lastBackupNonce?: string; lastBackupNonce?: string;
} }
/**
* FIXME: Eliminate this in favor of DenomSelectionState.
*/
export interface DenominationSelectionInfo {
totalCoinValue: AmountJson;
totalWithdrawCost: AmountJson;
selectedDenoms: {
/**
* How many times do we withdraw this denomination?
*/
count: number;
denom: DenominationRecord;
}[];
}
/** /**
* Selected denominations withn some extra info. * Selected denominations withn some extra info.
*/ */

View File

@ -31,7 +31,7 @@ import {
import { import {
WalletContractData, WalletContractData,
DenomSelectionState, DenomSelectionState,
DenominationStatus, DenominationVerificationStatus,
CoinSource, CoinSource,
CoinSourceType, CoinSourceType,
CoinStatus, CoinStatus,
@ -359,7 +359,7 @@ export async function importBackup(
stampExpireLegal: backupDenomination.stamp_expire_legal, stampExpireLegal: backupDenomination.stamp_expire_legal,
stampExpireWithdraw: backupDenomination.stamp_expire_withdraw, stampExpireWithdraw: backupDenomination.stamp_expire_withdraw,
stampStart: backupDenomination.stamp_start, stampStart: backupDenomination.stamp_start,
status: DenominationStatus.VerifiedGood, verificationStatus: DenominationVerificationStatus.VerifiedGood,
value: Amounts.parseOrThrow(backupDenomination.value), value: Amounts.parseOrThrow(backupDenomination.value),
listIssueDate: backupDenomination.list_issue_date, listIssueDate: backupDenomination.list_issue_date,
}); });

View File

@ -44,7 +44,7 @@ import { decodeCrock, encodeCrock, hash } from "../crypto/talerCrypto.js";
import { CryptoApi } from "../crypto/workers/cryptoApi.js"; import { CryptoApi } from "../crypto/workers/cryptoApi.js";
import { import {
DenominationRecord, DenominationRecord,
DenominationStatus, DenominationVerificationStatus,
ExchangeDetailsRecord, ExchangeDetailsRecord,
ExchangeRecord, ExchangeRecord,
WalletStoresV1, WalletStoresV1,
@ -95,7 +95,7 @@ function denominationRecordFromKeys(
stampExpireLegal: denomIn.stamp_expire_legal, stampExpireLegal: denomIn.stamp_expire_legal,
stampExpireWithdraw: denomIn.stamp_expire_withdraw, stampExpireWithdraw: denomIn.stamp_expire_withdraw,
stampStart: denomIn.stamp_start, stampStart: denomIn.stamp_start,
status: DenominationStatus.Unverified, verificationStatus: DenominationVerificationStatus.Unverified,
value: Amounts.parseOrThrow(denomIn.value), value: Amounts.parseOrThrow(denomIn.value),
listIssueDate, listIssueDate,
}; };

View File

@ -22,7 +22,6 @@ import {
DenominationRecord, DenominationRecord,
RefreshCoinStatus, RefreshCoinStatus,
RefreshGroupRecord, RefreshGroupRecord,
RefreshPlanchet,
WalletStoresV1, WalletStoresV1,
} from "../db.js"; } from "../db.js";
import { import {
@ -32,6 +31,7 @@ import {
fnutil, fnutil,
NotificationType, NotificationType,
RefreshGroupId, RefreshGroupId,
RefreshPlanchetInfo,
RefreshReason, RefreshReason,
stringifyTimestamp, stringifyTimestamp,
TalerErrorDetails, TalerErrorDetails,
@ -534,7 +534,7 @@ async function refreshReveal(
throw Error("refresh index error"); throw Error("refresh index error");
} }
const evs = planchets.map((x: RefreshPlanchet) => x.coinEv); const evs = planchets.map((x: RefreshPlanchetInfo) => x.coinEv);
const newDenomsFlat: string[] = []; const newDenomsFlat: string[] = [];
const linkSigs: string[] = []; const linkSigs: string[] = [];

View File

@ -16,7 +16,7 @@
import { Amounts } from "@gnu-taler/taler-util"; import { Amounts } from "@gnu-taler/taler-util";
import test from "ava"; import test from "ava";
import { DenominationRecord, DenominationStatus } from "../db.js"; import { DenominationRecord, DenominationVerificationStatus } from "../db.js";
import { selectWithdrawalDenominations } from "./withdraw.js"; import { selectWithdrawalDenominations } from "./withdraw.js";
test("withdrawal selection bug repro", (t) => { test("withdrawal selection bug repro", (t) => {
@ -70,7 +70,7 @@ test("withdrawal selection bug repro", (t) => {
stampStart: { stampStart: {
t_ms: 1585229388000, t_ms: 1585229388000,
}, },
status: DenominationStatus.Unverified, verificationStatus: DenominationVerificationStatus.Unverified,
value: { value: {
currency: "KUDOS", currency: "KUDOS",
fraction: 0, fraction: 0,
@ -121,7 +121,7 @@ test("withdrawal selection bug repro", (t) => {
stampStart: { stampStart: {
t_ms: 1585229388000, t_ms: 1585229388000,
}, },
status: DenominationStatus.Unverified, verificationStatus: DenominationVerificationStatus.Unverified,
value: { value: {
currency: "KUDOS", currency: "KUDOS",
fraction: 0, fraction: 0,
@ -172,7 +172,7 @@ test("withdrawal selection bug repro", (t) => {
stampStart: { stampStart: {
t_ms: 1585229388000, t_ms: 1585229388000,
}, },
status: DenominationStatus.Unverified, verificationStatus: DenominationVerificationStatus.Unverified,
value: { value: {
currency: "KUDOS", currency: "KUDOS",
fraction: 0, fraction: 0,
@ -223,7 +223,7 @@ test("withdrawal selection bug repro", (t) => {
stampStart: { stampStart: {
t_ms: 1585229388000, t_ms: 1585229388000,
}, },
status: DenominationStatus.Unverified, verificationStatus: DenominationVerificationStatus.Unverified,
value: { value: {
currency: "KUDOS", currency: "KUDOS",
fraction: 0, fraction: 0,
@ -274,7 +274,7 @@ test("withdrawal selection bug repro", (t) => {
stampStart: { stampStart: {
t_ms: 1585229388000, t_ms: 1585229388000,
}, },
status: DenominationStatus.Unverified, verificationStatus: DenominationVerificationStatus.Unverified,
value: { value: {
currency: "KUDOS", currency: "KUDOS",
fraction: 10000000, fraction: 10000000,
@ -325,7 +325,7 @@ test("withdrawal selection bug repro", (t) => {
stampStart: { stampStart: {
t_ms: 1585229388000, t_ms: 1585229388000,
}, },
status: DenominationStatus.Unverified, verificationStatus: DenominationVerificationStatus.Unverified,
value: { value: {
currency: "KUDOS", currency: "KUDOS",
fraction: 0, fraction: 0,

View File

@ -47,8 +47,7 @@ import {
CoinSourceType, CoinSourceType,
CoinStatus, CoinStatus,
DenominationRecord, DenominationRecord,
DenominationSelectionInfo, DenominationVerificationStatus,
DenominationStatus,
DenomSelectionState, DenomSelectionState,
ExchangeDetailsRecord, ExchangeDetailsRecord,
ExchangeRecord, ExchangeRecord,
@ -73,6 +72,21 @@ import {
*/ */
const logger = new Logger("withdraw.ts"); const logger = new Logger("withdraw.ts");
/**
* FIXME: Eliminate this in favor of DenomSelectionState.
*/
interface DenominationSelectionInfo {
totalCoinValue: AmountJson;
totalWithdrawCost: AmountJson;
selectedDenoms: {
/**
* How many times do we withdraw this denomination?
*/
count: number;
denom: DenominationRecord;
}[];
}
/** /**
* Information about what will happen when creating a reserve. * Information about what will happen when creating a reserve.
* *
@ -231,9 +245,13 @@ export function selectWithdrawalDenominations(
} }
if (logger.shouldLogTrace()) { if (logger.shouldLogTrace()) {
logger.trace(`selected withdrawal denoms for ${Amounts.stringify(totalCoinValue)}`); logger.trace(
`selected withdrawal denoms for ${Amounts.stringify(totalCoinValue)}`,
);
for (const sd of selectedDenoms) { for (const sd of selectedDenoms) {
logger.trace(`denom_pub_hash=${sd.denom.denomPubHash}, count=${sd.count}`); logger.trace(
`denom_pub_hash=${sd.denom.denomPubHash}, count=${sd.count}`,
);
} }
logger.trace("(end of withdrawal denom list)"); logger.trace("(end of withdrawal denom list)");
} }
@ -314,7 +332,9 @@ export async function getCandidateWithdrawalDenoms(
return await ws.db return await ws.db
.mktx((x) => ({ denominations: x.denominations })) .mktx((x) => ({ denominations: x.denominations }))
.runReadOnly(async (tx) => { .runReadOnly(async (tx) => {
const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl.getAll(exchangeBaseUrl); const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl.getAll(
exchangeBaseUrl,
);
return allDenoms.filter(isWithdrawableDenom); return allDenoms.filter(isWithdrawableDenom);
}); });
} }
@ -708,7 +728,7 @@ export async function updateWithdrawalDenoms(
batchIdx++, current++ batchIdx++, current++
) { ) {
const denom = denominations[current]; const denom = denominations[current];
if (denom.status === DenominationStatus.Unverified) { if (denom.verificationStatus === DenominationVerificationStatus.Unverified) {
logger.trace( logger.trace(
`Validating denomination (${current + 1}/${ `Validating denomination (${current + 1}/${
denominations.length denominations.length
@ -723,9 +743,9 @@ export async function updateWithdrawalDenoms(
logger.warn( logger.warn(
`Signature check for denomination h=${denom.denomPubHash} failed`, `Signature check for denomination h=${denom.denomPubHash} failed`,
); );
denom.status = DenominationStatus.VerifiedBad; denom.verificationStatus = DenominationVerificationStatus.VerifiedBad;
} else { } else {
denom.status = DenominationStatus.VerifiedGood; denom.verificationStatus = DenominationVerificationStatus.VerifiedGood;
} }
updatedDenominations.push(denom); updatedDenominations.push(denom);
} }