From 1ce53e1c211296233f2f683c64e156e4d3a79678 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 14 Sep 2023 17:36:15 +0200 Subject: wallet-core: consistently use usec timestamps in DB --- .../taler-wallet-core/src/operations/common.ts | 45 ++++++++++++---------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'packages/taler-wallet-core/src/operations/common.ts') diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index 50dd3dc5c..e8e492c08 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -40,6 +40,7 @@ import { TalerError, TalerErrorCode, TalerErrorDetail, + TalerPreciseTimestamp, TombstoneIdStr, TransactionIdStr, TransactionType, @@ -49,6 +50,7 @@ import { CryptoApiStoppedError } from "../crypto/workers/crypto-dispatcher.js"; import { BackupProviderRecord, CoinRecord, + DbPreciseTimestamp, DepositGroupRecord, ExchangeDetailsRecord, ExchangeEntryDbRecordStatus, @@ -62,6 +64,7 @@ import { RecoupGroupRecord, RefreshGroupRecord, RewardRecord, + timestampPreciseToDb, WalletStoresV1, WithdrawalGroupRecord, } from "../db.js"; @@ -360,11 +363,11 @@ async function storePendingTaskError( retryRecord = { id: pendingTaskId, lastError: e, - retryInfo: RetryInfo.reset(), + retryInfo: DbRetryInfo.reset(), }; } else { retryRecord.lastError = e; - retryRecord.retryInfo = RetryInfo.increment(retryRecord.retryInfo); + retryRecord.retryInfo = DbRetryInfo.increment(retryRecord.retryInfo); } await tx.operationRetries.put(retryRecord); return taskToTransactionNotification(ws, tx, pendingTaskId, e); @@ -383,7 +386,7 @@ export async function resetPendingTaskTimeout( if (retryRecord) { // Note that we don't reset the lastError, it should still be visible // while the retry runs. - retryRecord.retryInfo = RetryInfo.reset(); + retryRecord.retryInfo = DbRetryInfo.reset(); await tx.operationRetries.put(retryRecord); } return taskToTransactionNotification(ws, tx, pendingTaskId, undefined); @@ -403,14 +406,14 @@ async function storePendingTaskPending( if (!retryRecord) { retryRecord = { id: pendingTaskId, - retryInfo: RetryInfo.reset(), + retryInfo: DbRetryInfo.reset(), }; } else { if (retryRecord.lastError) { hadError = true; } delete retryRecord.lastError; - retryRecord.retryInfo = RetryInfo.increment(retryRecord.retryInfo); + retryRecord.retryInfo = DbRetryInfo.increment(retryRecord.retryInfo); } await tx.operationRetries.put(retryRecord); if (hadError) { @@ -736,9 +739,9 @@ export interface TaskRunLongpollResult { type: TaskRunResultType.Longpoll; } -export interface RetryInfo { - firstTry: AbsoluteTime; - nextRetry: AbsoluteTime; +export interface DbRetryInfo { + firstTry: DbPreciseTimestamp; + nextRetry: DbPreciseTimestamp; retryCounter: number; } @@ -755,7 +758,7 @@ const defaultRetryPolicy: RetryPolicy = { }; function updateTimeout( - r: RetryInfo, + r: DbRetryInfo, p: RetryPolicy = defaultRetryPolicy, ): void { const now = AbsoluteTime.now(); @@ -763,7 +766,9 @@ function updateTimeout( throw Error("assertion failed"); } if (p.backoffDelta.d_ms === "forever") { - r.nextRetry = AbsoluteTime.never(); + r.nextRetry = timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(AbsoluteTime.never()), + ); return; } @@ -775,12 +780,12 @@ function updateTimeout( (p.maxTimeout.d_ms === "forever" ? nextIncrement : Math.min(p.maxTimeout.d_ms, nextIncrement)); - r.nextRetry = AbsoluteTime.fromMilliseconds(t); + r.nextRetry = timestampPreciseToDb(TalerPreciseTimestamp.fromMilliseconds(t)); } -export namespace RetryInfo { +export namespace DbRetryInfo { export function getDuration( - r: RetryInfo | undefined, + r: DbRetryInfo | undefined, p: RetryPolicy = defaultRetryPolicy, ): Duration { if (!r) { @@ -797,11 +802,11 @@ export namespace RetryInfo { }; } - export function reset(p: RetryPolicy = defaultRetryPolicy): RetryInfo { - const now = AbsoluteTime.now(); - const info = { - firstTry: now, - nextRetry: now, + export function reset(p: RetryPolicy = defaultRetryPolicy): DbRetryInfo { + const now = TalerPreciseTimestamp.now(); + const info: DbRetryInfo = { + firstTry: timestampPreciseToDb(now), + nextRetry: timestampPreciseToDb(now), retryCounter: 0, }; updateTimeout(info, p); @@ -809,9 +814,9 @@ export namespace RetryInfo { } export function increment( - r: RetryInfo | undefined, + r: DbRetryInfo | undefined, p: RetryPolicy = defaultRetryPolicy, - ): RetryInfo { + ): DbRetryInfo { if (!r) { return reset(p); } -- cgit v1.2.3 From 8e70b89593a375bb19432e6521daed618ae779f5 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 2 Oct 2023 23:24:06 +0200 Subject: wallet-core: currency hint for preset exchanges --- packages/taler-wallet-core/src/db.ts | 6 ++++++ packages/taler-wallet-core/src/operations/common.ts | 2 +- packages/taler-wallet-core/src/operations/exchanges.ts | 4 +++- packages/taler-wallet-core/src/wallet-api-types.ts | 7 ++++++- packages/taler-wallet-core/src/wallet.ts | 18 ++++++++++++------ 5 files changed, 28 insertions(+), 9 deletions(-) (limited to 'packages/taler-wallet-core/src/operations/common.ts') diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 156651cc6..d59085dcc 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -620,6 +620,12 @@ export interface ExchangeEntryRecord { */ baseUrl: string; + /** + * Currency hint for a preset exchange, relevant + * when we didn't contact a preset exchange yet. + */ + presetCurrencyHint?: string; + /** * When did we confirm the last withdrawal from this exchange? * diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index e8e492c08..b28a5363d 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -593,7 +593,7 @@ export function makeExchangeListItem( return { exchangeBaseUrl: r.baseUrl, - currency: exchangeDetails?.currency, + currency: exchangeDetails?.currency ?? r.presetCurrencyHint, exchangeUpdateStatus, exchangeEntryStatus, tosStatus: exchangeDetails diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 5e966b719..82d7b42bf 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -309,6 +309,7 @@ export async function downloadExchangeInfo( export async function addPresetExchangeEntry( tx: WalletDbReadWriteTransaction<"exchanges">, exchangeBaseUrl: string, + currencyHint?: string, ): Promise { let exchange = await tx.exchanges.get(exchangeBaseUrl); if (!exchange) { @@ -316,6 +317,7 @@ export async function addPresetExchangeEntry( entryStatus: ExchangeEntryDbRecordStatus.Preset, updateStatus: ExchangeEntryDbUpdateStatus.Initial, baseUrl: exchangeBaseUrl, + presetCurrencyHint: currencyHint, detailsPointer: undefined, lastUpdate: undefined, lastKeysEtag: undefined, @@ -330,7 +332,7 @@ export async function addPresetExchangeEntry( } } -export async function provideExchangeRecordInTx( +async function provideExchangeRecordInTx( ws: InternalWalletState, tx: GetReadWriteAccess<{ exchanges: typeof WalletStoresV1.exchanges; diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index 26e86f43f..375e0a1b2 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -254,6 +254,11 @@ export type GetVersionOp = { */ export type WalletConfigParameter = RecursivePartial; +export interface BuiltinExchange { + exchangeBaseUrl: string; + currencyHint?: string; +} + export interface WalletConfig { /** * Initialization values useful for a complete startup. @@ -261,7 +266,7 @@ export interface WalletConfig { * These are values may be overridden by different wallets */ builtin: { - exchanges: string[]; + exchanges: BuiltinExchange[]; }; /** diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 44076667d..203adec0f 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -200,7 +200,6 @@ import { downloadTosFromAcceptedFormat, getExchangeDetails, getExchangeRequestTimeout, - provideExchangeRecordInTx, updateExchangeFromUrl, updateExchangeFromUrlHandler, } from "./operations/exchanges.js"; @@ -535,10 +534,12 @@ async function fillDefaults(ws: InternalWalletState): Promise { logger.trace("defaults already applied"); return; } - for (const baseUrl of ws.config.builtin.exchanges) { - await addPresetExchangeEntry(tx, baseUrl); - const now = AbsoluteTime.now(); - provideExchangeRecordInTx(ws, tx, baseUrl, now); + for (const exch of ws.config.builtin.exchanges) { + await addPresetExchangeEntry( + tx, + exch.exchangeBaseUrl, + exch.currencyHint, + ); } await tx.config.put({ key: ConfigRecordKey.CurrencyDefaultsApplied, @@ -1672,7 +1673,12 @@ export class Wallet { public static defaultConfig: Readonly = { builtin: { - exchanges: ["https://exchange.demo.taler.net/"], + exchanges: [ + { + exchangeBaseUrl: "https://exchange.demo.taler.net/", + currencyHint: "KUDOS", + }, + ], }, features: { allowHttp: false, -- cgit v1.2.3