From ddf1d123515d2afbedcd4e1df80a7c4dc2c0d1f6 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 19 Dec 2023 00:40:42 +0100 Subject: wallet-core: factor out denom query, don't use .iter() --- .../taler-wallet-core/src/operations/deposits.ts | 13 +++-- .../taler-wallet-core/src/operations/exchanges.ts | 5 +- .../src/operations/pay-merchant.ts | 12 +++-- .../src/operations/pay-peer-common.ts | 12 +++-- .../src/operations/pay-peer-push-debit.ts | 2 + .../taler-wallet-core/src/operations/refresh.ts | 15 +++--- .../taler-wallet-core/src/operations/reward.ts | 2 + .../taler-wallet-core/src/operations/withdraw.ts | 62 ++++++++++++++-------- 8 files changed, 75 insertions(+), 48 deletions(-) (limited to 'packages/taler-wallet-core/src/operations') diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index 057450b78..8205b7583 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -72,6 +72,7 @@ import { PendingTaskType, RefreshOperationStatus, createRefreshGroup, + getCandidateWithdrawalDenomsTx, getTotalRefreshCost, timestampPreciseToDb, timestampProtocolFromDb, @@ -1531,6 +1532,7 @@ async function getTotalFeesForDepositAmount( const coinFee: AmountJson[] = []; const refreshFee: AmountJson[] = []; const exchangeSet: Set = new Set(); + const currency = Amounts.currencyOf(total); await ws.db .mktx((x) => [x.coins, x.denominations, x.exchanges, x.exchangeDetails]) @@ -1552,11 +1554,12 @@ async function getTotalFeesForDepositAmount( coinFee.push(Amounts.parseOrThrow(denom.feeDeposit)); exchangeSet.add(coin.exchangeBaseUrl); - const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl - .iter(coin.exchangeBaseUrl) - .filter((x) => - Amounts.isSameCurrency(x.value, pcs.coinContributions[i]), - ); + const allDenoms = await getCandidateWithdrawalDenomsTx( + ws, + tx, + coin.exchangeBaseUrl, + currency, + ); const amountLeft = Amounts.sub( denom.value, pcs.coinContributions[i], diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index f4ee80e9e..8f878ecc0 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -1297,11 +1297,8 @@ export async function getExchangeDetailedInfo( if (!exchangeDetails) { return; } - const denominationRecords = - await tx.denominations.indexes.byExchangeBaseUrl - .iter(ex.baseUrl) - .toArray(); + await tx.denominations.indexes.byExchangeBaseUrl.getAll(ex.baseUrl); if (!denominationRecords) { return; diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index fb8a6d898..5d58f4c2f 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -98,6 +98,7 @@ import { WalletStoresV1, } from "../db.js"; import { + getCandidateWithdrawalDenomsTx, PendingTaskType, RefundGroupRecord, RefundGroupStatus, @@ -171,11 +172,12 @@ export async function getTotalPaymentCost( "can't calculate payment cost, denomination for coin not found", ); } - const allDenoms = ( - await tx.denominations.indexes.byExchangeBaseUrl.getAll( - coin.exchangeBaseUrl, - ) - ).filter((x) => x.currency === currency); + const allDenoms = await getCandidateWithdrawalDenomsTx( + ws, + tx, + coin.exchangeBaseUrl, + currency, + ); const amountLeft = Amounts.sub( denom.value, pcs.coinContributions[i], diff --git a/packages/taler-wallet-core/src/operations/pay-peer-common.ts b/packages/taler-wallet-core/src/operations/pay-peer-common.ts index aa9e0c858..1a5dc6e89 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-common.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-common.ts @@ -39,6 +39,7 @@ import { InternalWalletState } from "../internal-wallet-state.js"; import type { SelectedPeerCoin } from "../util/coinSelection.js"; import { checkDbInvariant } from "../util/invariants.js"; import { getTotalRefreshCost } from "./refresh.js"; +import { getCandidateWithdrawalDenomsTx } from "./withdraw.js"; const logger = new Logger("operations/peer-to-peer.ts"); @@ -109,11 +110,12 @@ export async function getTotalPeerPaymentCost( "can't calculate payment cost, denomination for coin not found", ); } - const allDenoms = ( - await tx.denominations.indexes.byExchangeBaseUrl.getAll( - coin.exchangeBaseUrl, - ) - ).filter((x) => x.currency === currency); + const allDenoms = await getCandidateWithdrawalDenomsTx( + ws, + tx, + coin.exchangeBaseUrl, + currency, + ); const amountLeft = Amounts.sub( denomInfo.value, pcs[i].contribution, diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts index c79aca1ad..a2a412811 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts @@ -713,6 +713,8 @@ export async function initiatePeerPushDebit( coinSelRes.result.coins, ); + logger.info(`computed total peer payment cost`); + const pursePub = pursePair.pub; const transactionId = constructTaskIdentifier({ diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index 5ea8fae23..17ac54cfb 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -78,6 +78,7 @@ import { WalletStoresV1, } from "../db.js"; import { + getCandidateWithdrawalDenomsTx, isWithdrawableDenom, PendingTaskType, RefreshSessionRecord, @@ -241,7 +242,7 @@ async function provideRefreshSession( throw Error("db inconsistent: denomination for coin not found"); } - // FIXME: use an index here, based on the withdrawal expiration time. + // FIXME: Use denom groups instead of querying all denominations! const availableDenoms: DenominationRecord[] = await tx.denominations.indexes.byExchangeBaseUrl .iter(exch.exchangeBaseUrl) @@ -975,17 +976,19 @@ export async function calculateRefreshOutput( const denomsPerExchange: Record = {}; + // FIXME: Use denom groups instead of querying all denominations! const getDenoms = async ( exchangeBaseUrl: string, ): Promise => { if (denomsPerExchange[exchangeBaseUrl]) { return denomsPerExchange[exchangeBaseUrl]; } - const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl - .iter(exchangeBaseUrl) - .filter((x) => { - return isWithdrawableDenom(x, ws.config.testing.denomselAllowLate); - }); + const allDenoms = await getCandidateWithdrawalDenomsTx( + ws, + tx, + exchangeBaseUrl, + currency, + ); denomsPerExchange[exchangeBaseUrl] = allDenoms; return allDenoms; }; diff --git a/packages/taler-wallet-core/src/operations/reward.ts b/packages/taler-wallet-core/src/operations/reward.ts index a1bf13ec4..79beb6432 100644 --- a/packages/taler-wallet-core/src/operations/reward.ts +++ b/packages/taler-wallet-core/src/operations/reward.ts @@ -173,6 +173,7 @@ export async function prepareTip( logger.trace(`status ${j2s(tipPickupStatus)}`); const amount = Amounts.parseOrThrow(tipPickupStatus.reward_amount); + const currency = amount.currency; logger.trace("new tip, creating tip record"); await fetchFreshExchange(ws, tipPickupStatus.exchange_url); @@ -192,6 +193,7 @@ export async function prepareTip( const denoms = await getCandidateWithdrawalDenoms( ws, tipPickupStatus.exchange_url, + currency, ); const selectedDenoms = selectWithdrawalDenominations(amount, denoms); diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 3dffab7d6..392b3753d 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -102,6 +102,7 @@ import { import { ExchangeDetailsRecord, ExchangeEntryDbRecordStatus, + Wallet, isWithdrawableDenom, timestampPreciseToDb, } from "../index.js"; @@ -613,20 +614,29 @@ export async function getBankWithdrawalInfo( export async function getCandidateWithdrawalDenoms( ws: InternalWalletState, exchangeBaseUrl: string, + currency: string, ): Promise { return await ws.db .mktx((x) => [x.denominations]) .runReadOnly(async (tx) => { - const allDenoms = - await tx.denominations.indexes.byExchangeBaseUrl.getAll( - exchangeBaseUrl, - ); - return allDenoms.filter((d) => - isWithdrawableDenom(d, ws.config.testing.denomselAllowLate), - ); + return getCandidateWithdrawalDenomsTx(ws, tx, exchangeBaseUrl, currency); }); } +export async function getCandidateWithdrawalDenomsTx( + ws: InternalWalletState, + tx: GetReadOnlyAccess<{ denominations: typeof WalletStoresV1.denominations }>, + exchangeBaseUrl: string, + currency: string, +): Promise { + // FIXME: Use denom groups instead of querying all denominations! + const allDenoms = + await tx.denominations.indexes.byExchangeBaseUrl.getAll(exchangeBaseUrl); + return allDenoms + .filter((d) => d.currency === currency) + .filter((d) => isWithdrawableDenom(d, ws.config.testing.denomselAllowLate)); +} + /** * Generate a planchet for a coin index in a withdrawal group. * Does not actually withdraw the coin yet. @@ -1193,7 +1203,11 @@ export async function updateWithdrawalDenoms( // First do a pass where the validity of candidate denominations // is checked and the result is stored in the database. logger.trace("getting candidate denominations"); - const denominations = await getCandidateWithdrawalDenoms(ws, exchangeBaseUrl); + const denominations = await getCandidateWithdrawalDenoms( + ws, + exchangeBaseUrl, + exchangeDetails.currency, + ); logger.trace(`got ${denominations.length} candidate denominations`); const batchSize = 500; let current = 0; @@ -1776,7 +1790,11 @@ export async function getExchangeWithdrawalInfo( await updateWithdrawalDenoms(ws, exchangeBaseUrl); logger.trace("getting candidate denoms"); - const denoms = await getCandidateWithdrawalDenoms(ws, exchangeBaseUrl); + const denoms = await getCandidateWithdrawalDenoms( + ws, + exchangeBaseUrl, + instructedAmount.currency, + ); logger.trace("selecting withdrawal denoms"); const selectedDenoms = selectWithdrawalDenominations( instructedAmount, @@ -1833,15 +1851,11 @@ export async function getExchangeWithdrawalInfo( checkLogicInvariant(!!earliestDepositExpiration); - const possibleDenoms = await ws.db - .mktx((x) => [x.denominations]) - .runReadOnly(async (tx) => { - const ds = - await tx.denominations.indexes.byExchangeBaseUrl.getAll( - exchangeBaseUrl, - ); - return ds.filter((x) => x.isOffered); - }); + const possibleDenoms = await getCandidateWithdrawalDenoms( + ws, + exchangeBaseUrl, + instructedAmount.currency, + ); let versionMatch; if (exchange.protocolVersionRange) { @@ -1950,13 +1964,10 @@ export async function getWithdrawalDetailsForUri( tx, r.baseUrl, ); - const denominations = await tx.denominations.indexes.byExchangeBaseUrl - .iter(r.baseUrl) - .toArray(); const retryRecord = await tx.operationRetries.get( TaskIdentifiers.forExchangeUpdate(r), ); - if (exchangeDetails && denominations) { + if (exchangeDetails) { exchanges.push( makeExchangeListItem(r, exchangeDetails, retryRecord?.lastError), ); @@ -2309,6 +2320,7 @@ export async function internalPrepareCreateWithdrawalGroup( const secretSeed = encodeCrock(getRandomBytes(32)); const canonExchange = canonicalizeBaseUrl(args.exchangeBaseUrl); const amount = args.amount; + const currency = Amounts.currencyOf(amount); let withdrawalGroupId; @@ -2333,7 +2345,11 @@ export async function internalPrepareCreateWithdrawalGroup( } await updateWithdrawalDenoms(ws, canonExchange); - const denoms = await getCandidateWithdrawalDenoms(ws, canonExchange); + const denoms = await getCandidateWithdrawalDenoms( + ws, + canonExchange, + currency, + ); let initialDenomSel: DenomSelectionState; const denomSelUid = encodeCrock(getRandomBytes(16)); -- cgit v1.2.3