DB cleanup

This commit is contained in:
Florian Dold 2020-09-08 20:29:47 +05:30
parent 043a5f89fe
commit 6c0be1cc95
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
12 changed files with 38 additions and 252 deletions

View File

@ -29,7 +29,7 @@
import { import {
CoinRecord, CoinRecord,
DenominationRecord, DenominationRecord,
RefreshPlanchetRecord, RefreshPlanchet,
RefreshSessionRecord, RefreshSessionRecord,
TipPlanchet, TipPlanchet,
WireFee, WireFee,
@ -385,7 +385,7 @@ export class CryptoImplementation {
const transferPubs: string[] = []; const transferPubs: string[] = [];
const transferPrivs: string[] = []; const transferPrivs: string[] = [];
const planchetsForGammas: RefreshPlanchetRecord[][] = []; const planchetsForGammas: RefreshPlanchet[][] = [];
for (let i = 0; i < kappa; i++) { for (let i = 0; i < kappa; i++) {
const transferKeyPair = createEcdheKeyPair(); const transferKeyPair = createEcdheKeyPair();
@ -405,7 +405,7 @@ export class CryptoImplementation {
sessionHc.update(amountToBuffer(valueWithFee)); sessionHc.update(amountToBuffer(valueWithFee));
for (let i = 0; i < kappa; i++) { for (let i = 0; i < kappa; i++) {
const planchets: RefreshPlanchetRecord[] = []; const planchets: RefreshPlanchet[] = [];
for (let j = 0; j < newCoinDenoms.selectedDenoms.length; j++) { for (let j = 0; j < newCoinDenoms.selectedDenoms.length; j++) {
const denomSel = newCoinDenoms.selectedDenoms[j]; const denomSel = newCoinDenoms.selectedDenoms[j];
for (let k = 0; k < denomSel.count; k++) { for (let k = 0; k < denomSel.count; k++) {
@ -423,7 +423,7 @@ export class CryptoImplementation {
const pubHash = hash(coinPub); const pubHash = hash(coinPub);
const denomPub = decodeCrock(denomSel.denom.denomPub); const denomPub = decodeCrock(denomSel.denom.denomPub);
const ev = rsaBlind(pubHash, blindingFactor, denomPub); const ev = rsaBlind(pubHash, blindingFactor, denomPub);
const planchet: RefreshPlanchetRecord = { const planchet: RefreshPlanchet = {
blindingKey: encodeCrock(blindingFactor), blindingKey: encodeCrock(blindingFactor),
coinEv: encodeCrock(ev), coinEv: encodeCrock(ev),
privateKey: encodeCrock(coinPriv), privateKey: encodeCrock(coinPriv),

View File

@ -29,9 +29,6 @@ import {
DenominationStatus, DenominationStatus,
WireFee, WireFee,
ExchangeUpdateReason, ExchangeUpdateReason,
ExchangeUpdatedEventRecord,
initRetryInfo,
updateRetryInfoTimeout,
} from "../types/dbTypes"; } from "../types/dbTypes";
import { canonicalizeBaseUrl } from "../util/helpers"; import { canonicalizeBaseUrl } from "../util/helpers";
import * as Amounts from "../util/amounts"; import * as Amounts from "../util/amounts";
@ -64,6 +61,7 @@ import { URL } from "../util/url";
import { reconcileReserveHistory } from "../util/reserveHistoryUtil"; import { reconcileReserveHistory } from "../util/reserveHistoryUtil";
import { checkDbInvariant } from "../util/invariants"; import { checkDbInvariant } from "../util/invariants";
import { NotificationType } from "../types/notifications"; import { NotificationType } from "../types/notifications";
import { updateRetryInfoTimeout, initRetryInfo } from "../util/retries";
const logger = new Logger("exchanges.ts"); const logger = new Logger("exchanges.ts");
@ -292,7 +290,7 @@ async function updateExchangeFinalize(
return; return;
} }
await ws.db.runWithWriteTransaction( await ws.db.runWithWriteTransaction(
[Stores.exchanges, Stores.exchangeUpdatedEvents], [Stores.exchanges],
async (tx) => { async (tx) => {
const r = await tx.get(Stores.exchanges, exchangeBaseUrl); const r = await tx.get(Stores.exchanges, exchangeBaseUrl);
if (!r) { if (!r) {
@ -307,11 +305,6 @@ async function updateExchangeFinalize(
// as now new denominations might be available. // as now new denominations might be available.
r.nextRefreshCheck = undefined; r.nextRefreshCheck = undefined;
await tx.put(Stores.exchanges, r); await tx.put(Stores.exchanges, r);
const updateEvent: ExchangeUpdatedEventRecord = {
exchangeBaseUrl: exchange.baseUrl,
timestamp: getTimestampNow(),
};
await tx.put(Stores.exchangeUpdatedEvents, updateEvent);
}, },
); );
} }
@ -557,7 +550,7 @@ export async function getExchangeTrust(
); );
if (currencyRecord) { if (currencyRecord) {
for (const trustedExchange of currencyRecord.exchanges) { for (const trustedExchange of currencyRecord.exchanges) {
if (trustedExchange.exchangePub === exchangeDetails.masterPublicKey) { if (trustedExchange.exchangeMasterPub === exchangeDetails.masterPublicKey) {
isTrusted = true; isTrusted = true;
break; break;
} }

View File

@ -27,15 +27,11 @@
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto"; import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto";
import { import {
CoinStatus, CoinStatus,
initRetryInfo,
ProposalRecord, ProposalRecord,
ProposalStatus, ProposalStatus,
PurchaseRecord, PurchaseRecord,
Stores, Stores,
updateRetryInfoTimeout,
PayEventRecord,
WalletContractData, WalletContractData,
getRetryDuration,
CoinRecord, CoinRecord,
DenominationRecord, DenominationRecord,
} from "../types/dbTypes"; } from "../types/dbTypes";
@ -80,6 +76,7 @@ import {
} from "../util/http"; } from "../util/http";
import { TalerErrorCode } from "../TalerErrorCode"; import { TalerErrorCode } from "../TalerErrorCode";
import { URL } from "../util/url"; import { URL } from "../util/url";
import { initRetryInfo, updateRetryInfoTimeout, getRetryDuration } from "../util/retries";
/** /**
* Logger. * Logger.
@ -833,7 +830,7 @@ async function storeFirstPaySuccess(
): Promise<void> { ): Promise<void> {
const now = getTimestampNow(); const now = getTimestampNow();
await ws.db.runWithWriteTransaction( await ws.db.runWithWriteTransaction(
[Stores.purchases, Stores.payEvents], [Stores.purchases],
async (tx) => { async (tx) => {
const purchase = await tx.get(Stores.purchases, proposalId); const purchase = await tx.get(Stores.purchases, proposalId);
@ -864,13 +861,6 @@ async function storeFirstPaySuccess(
} }
await tx.put(Stores.purchases, purchase); await tx.put(Stores.purchases, purchase);
const payEvent: PayEventRecord = {
proposalId,
sessionId,
timestamp: now,
isReplay: !isFirst,
};
await tx.put(Stores.payEvents, payEvent);
}, },
); );
} }
@ -881,7 +871,7 @@ async function storePayReplaySuccess(
sessionId: string | undefined, sessionId: string | undefined,
): Promise<void> { ): Promise<void> {
await ws.db.runWithWriteTransaction( await ws.db.runWithWriteTransaction(
[Stores.purchases, Stores.payEvents], [Stores.purchases],
async (tx) => { async (tx) => {
const purchase = await tx.get(Stores.purchases, proposalId); const purchase = await tx.get(Stores.purchases, proposalId);

View File

@ -34,14 +34,11 @@ import {
RefreshCoinSource, RefreshCoinSource,
ReserveRecordStatus, ReserveRecordStatus,
RecoupGroupRecord, RecoupGroupRecord,
initRetryInfo,
updateRetryInfoTimeout,
} from "../types/dbTypes"; } from "../types/dbTypes";
import { codecForRecoupConfirmation } from "../types/talerTypes"; import { codecForRecoupConfirmation } from "../types/talerTypes";
import { NotificationType } from "../types/notifications"; import { NotificationType } from "../types/notifications";
import { import {
forceQueryReserve,
getReserveRequestTimeout, getReserveRequestTimeout,
processReserve, processReserve,
} from "./reserves"; } from "./reserves";
@ -56,6 +53,7 @@ import { guardOperationException } from "./errors";
import { readSuccessResponseJsonOrThrow } from "../util/http"; import { readSuccessResponseJsonOrThrow } from "../util/http";
import { URL } from "../util/url"; import { URL } from "../util/url";
import { Logger } from "../util/logging"; import { Logger } from "../util/logging";
import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries";
const logger = new Logger("operations/recoup.ts"); const logger = new Logger("operations/recoup.ts");

View File

@ -19,11 +19,9 @@ import {
DenominationRecord, DenominationRecord,
Stores, Stores,
CoinStatus, CoinStatus,
RefreshPlanchetRecord, RefreshPlanchet,
CoinRecord, CoinRecord,
RefreshSessionRecord, RefreshSessionRecord,
initRetryInfo,
updateRetryInfoTimeout,
RefreshGroupRecord, RefreshGroupRecord,
CoinSourceType, CoinSourceType,
} from "../types/dbTypes"; } from "../types/dbTypes";
@ -56,8 +54,6 @@ import {
} from "../util/time"; } from "../util/time";
import { import {
readSuccessResponseJsonOrThrow, readSuccessResponseJsonOrThrow,
HttpResponse,
throwUnexpectedRequestError,
} from "../util/http"; } from "../util/http";
import { import {
codecForExchangeMeltResponse, codecForExchangeMeltResponse,
@ -65,6 +61,7 @@ import {
} from "../types/talerTypes"; } from "../types/talerTypes";
import { URL } from "../util/url"; import { URL } from "../util/url";
import { checkDbInvariant } from "../util/invariants"; import { checkDbInvariant } from "../util/invariants";
import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries";
const logger = new Logger("refresh.ts"); const logger = new Logger("refresh.ts");
@ -326,7 +323,7 @@ async function refreshReveal(
throw Error("inconsistent database"); throw Error("inconsistent database");
} }
const evs = planchets.map((x: RefreshPlanchetRecord) => x.coinEv); const evs = planchets.map((x: RefreshPlanchet) => x.coinEv);
const linkSigs: string[] = []; const linkSigs: string[] = [];
for (let i = 0; i < refreshSession.newDenoms.length; i++) { for (let i = 0; i < refreshSession.newDenoms.length; i++) {

View File

@ -32,8 +32,6 @@ import {
} from "../types/walletTypes"; } from "../types/walletTypes";
import { import {
Stores, Stores,
updateRetryInfoTimeout,
initRetryInfo,
CoinStatus, CoinStatus,
RefundReason, RefundReason,
RefundState, RefundState,
@ -55,6 +53,7 @@ import { Logger } from "../util/logging";
import { readSuccessResponseJsonOrThrow } from "../util/http"; import { readSuccessResponseJsonOrThrow } from "../util/http";
import { TransactionHandle } from "../util/query"; import { TransactionHandle } from "../util/query";
import { URL } from "../util/url"; import { URL } from "../util/url";
import { updateRetryInfoTimeout, initRetryInfo } from "../util/retries";
const logger = new Logger("refund.ts"); const logger = new Logger("refund.ts");
@ -265,7 +264,6 @@ async function acceptRefunds(
Stores.coins, Stores.coins,
Stores.denominations, Stores.denominations,
Stores.refreshGroups, Stores.refreshGroups,
Stores.refundEvents,
], ],
async (tx) => { async (tx) => {
const p = await tx.get(Stores.purchases, proposalId); const p = await tx.get(Stores.purchases, proposalId);

View File

@ -28,14 +28,9 @@ import {
CurrencyRecord, CurrencyRecord,
Stores, Stores,
WithdrawalGroupRecord, WithdrawalGroupRecord,
initRetryInfo,
updateRetryInfoTimeout,
ReserveUpdatedEventRecord,
WalletReserveHistoryItemType, WalletReserveHistoryItemType,
WithdrawalSourceType,
ReserveHistoryRecord, ReserveHistoryRecord,
ReserveBankInfo, ReserveBankInfo,
getRetryDuration,
} from "../types/dbTypes"; } from "../types/dbTypes";
import { Logger } from "../util/logging"; import { Logger } from "../util/logging";
import { Amounts } from "../util/amounts"; import { Amounts } from "../util/amounts";
@ -86,6 +81,7 @@ import {
} from "../util/http"; } from "../util/http";
import { codecForAny } from "../util/codec"; import { codecForAny } from "../util/codec";
import { URL } from "../util/url"; import { URL } from "../util/url";
import { initRetryInfo, getRetryDuration, updateRetryInfoTimeout } from "../util/retries";
const logger = new Logger("reserves.ts"); const logger = new Logger("reserves.ts");
@ -206,8 +202,8 @@ export async function createReserve(
if (!isAudited && !isTrusted) { if (!isAudited && !isTrusted) {
currencyRecord.exchanges.push({ currencyRecord.exchanges.push({
baseUrl: req.exchange, exchangeBaseUrl: req.exchange,
exchangePub: exchangeDetails.masterPublicKey, exchangeMasterPub: exchangeDetails.masterPublicKey,
}); });
} }
@ -554,7 +550,7 @@ async function updateReserve(
const currency = balance.currency; const currency = balance.currency;
let updateSummary: ReserveHistorySummary | undefined; let updateSummary: ReserveHistorySummary | undefined;
await ws.db.runWithWriteTransaction( await ws.db.runWithWriteTransaction(
[Stores.reserves, Stores.reserveUpdatedEvents, Stores.reserveHistory], [Stores.reserves, Stores.reserveHistory],
async (tx) => { async (tx) => {
const r = await tx.get(Stores.reserves, reservePub); const r = await tx.get(Stores.reserves, reservePub);
if (!r) { if (!r) {
@ -589,15 +585,6 @@ async function updateReserve(
reconciled.newAddedItems.length + reconciled.newMatchedItems.length != reconciled.newAddedItems.length + reconciled.newMatchedItems.length !=
0 0
) { ) {
const reserveUpdate: ReserveUpdatedEventRecord = {
reservePub: r.reservePub,
timestamp: getTimestampNow(),
amountReserveBalance: Amounts.stringify(balance),
amountExpected: Amounts.stringify(updateSummary.awaitedReserveAmount),
newHistoryTransactions,
reserveUpdateId,
};
await tx.put(Stores.reserveUpdatedEvents, reserveUpdate);
logger.trace("setting reserve status to 'withdrawing' after query"); logger.trace("setting reserve status to 'withdrawing' after query");
r.reserveStatus = ReserveRecordStatus.WITHDRAWING; r.reserveStatus = ReserveRecordStatus.WITHDRAWING;
r.retryInfo = initRetryInfo(); r.retryInfo = initRetryInfo();

View File

@ -25,8 +25,6 @@ import {
import * as Amounts from "../util/amounts"; import * as Amounts from "../util/amounts";
import { import {
Stores, Stores,
initRetryInfo,
updateRetryInfoTimeout,
TipPlanchet, TipPlanchet,
CoinRecord, CoinRecord,
CoinSourceType, CoinSourceType,
@ -47,6 +45,7 @@ import { URL } from "../util/url";
import { Logger } from "../util/logging"; import { Logger } from "../util/logging";
import { checkDbInvariant } from "../util/invariants"; import { checkDbInvariant } from "../util/invariants";
import { TalerErrorCode } from "../TalerErrorCode"; import { TalerErrorCode } from "../TalerErrorCode";
import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries";
const logger = new Logger("operations/tip.ts"); const logger = new Logger("operations/tip.ts");

View File

@ -20,7 +20,6 @@
import { InternalWalletState } from "./state"; import { InternalWalletState } from "./state";
import { import {
Stores, Stores,
WithdrawalSourceType,
WalletRefundItem, WalletRefundItem,
RefundState, RefundState,
ReserveRecordStatus, ReserveRecordStatus,
@ -95,10 +94,7 @@ export async function getTransactions(
Stores.reserveHistory, Stores.reserveHistory,
Stores.tips, Stores.tips,
Stores.withdrawalGroups, Stores.withdrawalGroups,
Stores.payEvents,
Stores.planchets, Stores.planchets,
Stores.refundEvents,
Stores.reserveUpdatedEvents,
Stores.recoupGroups, Stores.recoupGroups,
], ],
// Report withdrawals that are currently in progress. // Report withdrawals that are currently in progress.

View File

@ -21,12 +21,9 @@ import {
DenominationStatus, DenominationStatus,
CoinStatus, CoinStatus,
CoinRecord, CoinRecord,
initRetryInfo,
updateRetryInfoTimeout,
CoinSourceType, CoinSourceType,
DenominationSelectionInfo, DenominationSelectionInfo,
PlanchetRecord, PlanchetRecord,
WithdrawalSourceType,
DenomSelectionState, DenomSelectionState,
} from "../types/dbTypes"; } from "../types/dbTypes";
import { import {
@ -64,6 +61,7 @@ import { readSuccessResponseJsonOrThrow } from "../util/http";
import { URL } from "../util/url"; import { URL } from "../util/url";
import { TalerErrorCode } from "../TalerErrorCode"; import { TalerErrorCode } from "../TalerErrorCode";
import { encodeCrock } from "../crypto/talerCrypto"; import { encodeCrock } from "../crypto/talerCrypto";
import { updateRetryInfoTimeout, initRetryInfo } from "../util/retries";
const logger = new Logger("withdraw.ts"); const logger = new Logger("withdraw.ts");

View File

@ -46,6 +46,7 @@ import {
import { Timestamp, Duration, getTimestampNow } from "../util/time"; import { Timestamp, Duration, getTimestampNow } from "../util/time";
import { PayCoinSelection, PayCostInfo } from "../operations/pay"; import { PayCoinSelection, PayCostInfo } from "../operations/pay";
import { IDBKeyPath } from "idb-bridge"; import { IDBKeyPath } from "idb-bridge";
import { RetryInfo } from "../util/retries";
export enum ReserveRecordStatus { export enum ReserveRecordStatus {
/** /**
@ -84,74 +85,6 @@ export enum ReserveRecordStatus {
BANK_ABORTED = "bank-aborted", BANK_ABORTED = "bank-aborted",
} }
export interface RetryInfo {
firstTry: Timestamp;
nextRetry: Timestamp;
retryCounter: number;
active: boolean;
}
export interface RetryPolicy {
readonly backoffDelta: Duration;
readonly backoffBase: number;
}
const defaultRetryPolicy: RetryPolicy = {
backoffBase: 1.5,
backoffDelta: { d_ms: 200 },
};
export function updateRetryInfoTimeout(
r: RetryInfo,
p: RetryPolicy = defaultRetryPolicy,
): void {
const now = getTimestampNow();
if (now.t_ms === "never") {
throw Error("assertion failed");
}
if (p.backoffDelta.d_ms === "forever") {
r.nextRetry = { t_ms: "never" };
return;
}
r.active = true;
const t =
now.t_ms + p.backoffDelta.d_ms * Math.pow(p.backoffBase, r.retryCounter);
r.nextRetry = { t_ms: t };
}
export function getRetryDuration(
r: RetryInfo,
p: RetryPolicy = defaultRetryPolicy,
): Duration {
if (p.backoffDelta.d_ms === "forever") {
return { d_ms: "forever" };
}
const t = p.backoffDelta.d_ms * Math.pow(p.backoffBase, r.retryCounter);
return { d_ms: t };
}
export function initRetryInfo(
active = true,
p: RetryPolicy = defaultRetryPolicy,
): RetryInfo {
if (!active) {
return {
active: false,
firstTry: { t_ms: Number.MAX_SAFE_INTEGER },
nextRetry: { t_ms: Number.MAX_SAFE_INTEGER },
retryCounter: 0,
};
}
const info = {
firstTry: getTimestampNow(),
active: true,
nextRetry: { t_ms: 0 },
retryCounter: 0,
};
updateRetryInfoTimeout(info, p);
return info;
}
export enum WalletReserveHistoryItemType { export enum WalletReserveHistoryItemType {
Credit = "credit", Credit = "credit",
Withdraw = "withdraw", Withdraw = "withdraw",
@ -353,10 +286,12 @@ export interface AuditorRecord {
* Base url of the auditor. * Base url of the auditor.
*/ */
baseUrl: string; baseUrl: string;
/** /**
* Public signing key of the auditor. * Public signing key of the auditor.
*/ */
auditorPub: string; auditorPub: string;
/** /**
* Time when the auditing expires. * Time when the auditing expires.
*/ */
@ -371,11 +306,12 @@ export interface ExchangeForCurrencyRecord {
/** /**
* FIXME: unused? * FIXME: unused?
*/ */
exchangePub: string; exchangeMasterPub: string;
/** /**
* Base URL of the exchange. * Base URL of the exchange.
*/ */
baseUrl: string; exchangeBaseUrl: string;
} }
/** /**
@ -386,14 +322,17 @@ export interface CurrencyRecord {
* Name of the currency. * Name of the currency.
*/ */
name: string; name: string;
/** /**
* Number of fractional digits to show when rendering the currency. * Number of fractional digits to show when rendering the currency.
*/ */
fractionalDigits: number; fractionalDigits: number;
/** /**
* Auditors that the wallet trusts for this currency. * Auditors that the wallet trusts for this currency.
*/ */
auditors: AuditorRecord[]; auditors: AuditorRecord[];
/** /**
* Exchanges that the wallet trusts for this currency. * Exchanges that the wallet trusts for this currency.
*/ */
@ -722,7 +661,7 @@ export interface PlanchetRecord {
/** /**
* Planchet for a coin during refrehs. * Planchet for a coin during refrehs.
*/ */
export interface RefreshPlanchetRecord { export interface RefreshPlanchet {
/** /**
* Public key for the coin. * Public key for the coin.
*/ */
@ -1083,7 +1022,7 @@ export interface RefreshSessionRecord {
/** /**
* Planchets for each cut-and-choose instance. * Planchets for each cut-and-choose instance.
*/ */
planchetsForGammas: RefreshPlanchetRecord[][]; planchetsForGammas: RefreshPlanchet[][];
/** /**
* The transfer keys, kappa of them. * The transfer keys, kappa of them.
@ -1431,54 +1370,6 @@ export interface ConfigRecord {
value: any; value: any;
} }
/**
* Coin that we're depositing ourselves.
*/
export interface DepositCoin {
coinPaySig: CoinDepositPermission;
/**
* Undefined if coin not deposited, otherwise signature
* from the exchange confirming the deposit.
*/
depositedSig?: string;
}
/**
* Record stored in the wallet's database when the user sends coins back to
* their own bank account. Stores the status of coins that are deposited to
* the wallet itself, where the wallet acts as a "merchant" for the customer.
*/
export interface CoinsReturnRecord {
contractTermsRaw: string;
contractData: WalletContractData;
/**
* Private key where corresponding
* public key is used in the contract terms
* as merchant pub.
*/
merchantPriv: string;
coins: DepositCoin[];
/**
* Exchange base URL to deposit coins at.
*/
exchange: string;
/**
* Our own wire information for the deposit.
*/
wire: any;
}
export enum WithdrawalSourceType {
Tip = "tip",
Reserve = "reserve",
}
export interface DenominationSelectionInfo { export interface DenominationSelectionInfo {
totalCoinValue: AmountJson; totalCoinValue: AmountJson;
totalWithdrawCost: AmountJson; totalWithdrawCost: AmountJson;
@ -1610,31 +1501,6 @@ export enum ImportPayloadType {
CoreSchema = "core-schema", CoreSchema = "core-schema",
} }
/**
* Record to keep track of data imported into the wallet.
*/
export class WalletImportRecord {
/**
* Unique ID to reference this import record.
*/
walletImportId: string;
/**
* When was the data imported?
*/
timestampImportStarted: Timestamp;
timestampImportFinished: Timestamp | undefined;
payloadType: ImportPayloadType;
/**
* The actual data to import.
*/
payload: any;
}
/* tslint:disable:completed-docs */
class ExchangesStore extends Store<ExchangeRecord> { class ExchangesStore extends Store<ExchangeRecord> {
constructor() { constructor() {
@ -1773,51 +1639,21 @@ class PlanchetsStore extends Store<PlanchetRecord> {
); );
} }
class RefundEventsStore extends Store<RefundEventRecord> { /**
constructor() { * This store is effectively a materialized index for
super("refundEvents", { keyPath: "refundGroupId" }); * reserve records that are for a bank-integrated withdrawal.
} */
}
class PayEventsStore extends Store<PayEventRecord> {
constructor() {
super("payEvents", { keyPath: "proposalId" });
}
}
class ExchangeUpdatedEventsStore extends Store<ExchangeUpdatedEventRecord> {
constructor() {
super("exchangeUpdatedEvents", { keyPath: "exchangeBaseUrl" });
}
}
class ReserveUpdatedEventsStore extends Store<ReserveUpdatedEventRecord> {
constructor() {
super("reserveUpdatedEvents", { keyPath: "reservePub" });
}
}
class BankWithdrawUrisStore extends Store<BankWithdrawUriRecord> { class BankWithdrawUrisStore extends Store<BankWithdrawUriRecord> {
constructor() { constructor() {
super("bankWithdrawUris", { keyPath: "talerWithdrawUri" }); super("bankWithdrawUris", { keyPath: "talerWithdrawUri" });
} }
} }
class WalletImportsStore extends Store<WalletImportRecord> {
constructor() {
super("walletImports", { keyPath: "walletImportId" });
}
}
/** /**
* The stores and indices for the wallet database. * The stores and indices for the wallet database.
*/ */
export const Stores = { export const Stores = {
coins: new CoinsStore(), coins: new CoinsStore(),
coinsReturns: new Store<CoinsReturnRecord>("coinsReturns", {
keyPath: "contractTermsHash",
}),
config: new ConfigStore(), config: new ConfigStore(),
currencies: new CurrenciesStore(), currencies: new CurrenciesStore(),
denominations: new DenominationsStore(), denominations: new DenominationsStore(),
@ -1837,11 +1673,4 @@ export const Stores = {
withdrawalGroups: new WithdrawalGroupsStore(), withdrawalGroups: new WithdrawalGroupsStore(),
planchets: new PlanchetsStore(), planchets: new PlanchetsStore(),
bankWithdrawUris: new BankWithdrawUrisStore(), bankWithdrawUris: new BankWithdrawUrisStore(),
refundEvents: new RefundEventsStore(),
payEvents: new PayEventsStore(),
reserveUpdatedEvents: new ReserveUpdatedEventsStore(),
exchangeUpdatedEvents: new ExchangeUpdatedEventsStore(),
walletImports: new WalletImportsStore(),
}; };
/* tslint:enable:completed-docs */

View File

@ -22,8 +22,9 @@
* Imports. * Imports.
*/ */
import { TalerErrorDetails, BalancesResponse } from "./walletTypes"; import { TalerErrorDetails, BalancesResponse } from "./walletTypes";
import { RetryInfo, ReserveRecordStatus } from "./dbTypes"; import { ReserveRecordStatus } from "./dbTypes";
import { Timestamp, Duration } from "../util/time"; import { Timestamp, Duration } from "../util/time";
import { RetryInfo } from "../util/retries";
export enum PendingOperationType { export enum PendingOperationType {
Bug = "bug", Bug = "bug",