diff options
author | Florian Dold <florian@dold.me> | 2024-02-22 11:33:32 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-02-27 14:58:36 +0100 |
commit | 2ab4ad686380b3cfe5c5245312e42af8a69c01f6 (patch) | |
tree | e82af5ea7defbc4bdd7b468f714212041914dc59 /packages/taler-wallet-core | |
parent | 41f34031ae934e8c802cdbb73fffb5a39c9c6a68 (diff) | |
download | wallet-core-2ab4ad686380b3cfe5c5245312e42af8a69c01f6.tar.gz wallet-core-2ab4ad686380b3cfe5c5245312e42af8a69c01f6.tar.bz2 wallet-core-2ab4ad686380b3cfe5c5245312e42af8a69c01f6.zip |
move operation out of ws
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r-- | packages/taler-wallet-core/src/coinSelection.ts | 4 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/common.ts | 4 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/deposits.ts | 6 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/pay-merchant.ts | 8 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/pay-peer-common.ts | 6 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/recoup.ts | 10 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/refresh.ts | 22 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 61 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/withdraw.ts | 27 |
9 files changed, 82 insertions, 66 deletions
diff --git a/packages/taler-wallet-core/src/coinSelection.ts b/packages/taler-wallet-core/src/coinSelection.ts index f0b435b54..e1ae613bc 100644 --- a/packages/taler-wallet-core/src/coinSelection.ts +++ b/packages/taler-wallet-core/src/coinSelection.ts @@ -64,7 +64,7 @@ import { getAutoRefreshExecuteThreshold } from "./common.js"; import { DenominationRecord, WalletDbReadOnlyTransaction } from "./db.js"; import { isWithdrawableDenom } from "./denominations.js"; import { getExchangeWireDetailsInTx } from "./exchanges.js"; -import { InternalWalletState } from "./wallet.js"; +import { getDenomInfo, InternalWalletState } from "./wallet.js"; const logger = new Logger("coinSelection.ts"); @@ -1088,7 +1088,7 @@ export async function selectPeerCoins( if (!coin) { throw Error("repair not possible, coin not found"); } - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts index 8c6650f4a..08adb2515 100644 --- a/packages/taler-wallet-core/src/common.ts +++ b/packages/taler-wallet-core/src/common.ts @@ -61,7 +61,7 @@ import { timestampPreciseToDb, } from "./db.js"; import { createRefreshGroup } from "./refresh.js"; -import { InternalWalletState } from "./wallet.js"; +import { InternalWalletState, getDenomInfo } from "./wallet.js"; const logger = new Logger("operations/common.ts"); @@ -161,7 +161,7 @@ export async function spendCoins( if (!coin) { throw Error("coin allocated for payment doesn't exist anymore"); } - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts index ed8778368..9db8cfc27 100644 --- a/packages/taler-wallet-core/src/deposits.ts +++ b/packages/taler-wallet-core/src/deposits.ts @@ -109,7 +109,7 @@ import { notifyTransition, parseTransactionIdentifier, } from "./transactions.js"; -import { InternalWalletState } from "./wallet.js"; +import { InternalWalletState, getDenomInfo } from "./wallet.js"; import { getCandidateWithdrawalDenomsTx } from "./withdraw.js"; /** @@ -1527,7 +1527,7 @@ export async function getCounterpartyEffectiveDepositAmount( if (!coin) { throw Error("can't calculate deposit amount, coin not found"); } - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, @@ -1593,7 +1593,7 @@ async function getTotalFeesForDepositAmount( if (!coin) { throw Error("can't calculate deposit amount, coin not found"); } - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts index 8fcb728d4..332660ad5 100644 --- a/packages/taler-wallet-core/src/pay-merchant.ts +++ b/packages/taler-wallet-core/src/pay-merchant.ts @@ -138,7 +138,11 @@ import { notifyTransition, parseTransactionIdentifier, } from "./transactions.js"; -import { EXCHANGE_COINS_LOCK, InternalWalletState } from "./wallet.js"; +import { + EXCHANGE_COINS_LOCK, + getDenomInfo, + InternalWalletState, +} from "./wallet.js"; import { getCandidateWithdrawalDenomsTx } from "./withdraw.js"; /** @@ -2959,7 +2963,7 @@ async function computeRefreshRequest( if (!coin) { throw Error("coin not found"); } - const denomInfo = await ws.getDenomInfo( + const denomInfo = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/pay-peer-common.ts b/packages/taler-wallet-core/src/pay-peer-common.ts index efb5bdb7e..dbc3376b4 100644 --- a/packages/taler-wallet-core/src/pay-peer-common.ts +++ b/packages/taler-wallet-core/src/pay-peer-common.ts @@ -33,7 +33,7 @@ import type { SelectedPeerCoin } from "./coinSelection.js"; import { SpendCoinDetails } from "./crypto/cryptoImplementation.js"; import { PeerPushPaymentCoinSelection, ReserveRecord } from "./db.js"; import { getTotalRefreshCost } from "./refresh.js"; -import { InternalWalletState } from "./wallet.js"; +import { InternalWalletState, getDenomInfo } from "./wallet.js"; import { getCandidateWithdrawalDenomsTx } from "./withdraw.js"; /** @@ -50,7 +50,7 @@ export async function queryCoinInfosForSelection( if (!coin) { throw Error("coin not found anymore"); } - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, @@ -84,7 +84,7 @@ export async function getTotalPeerPaymentCost( if (!coin) { throw Error("can't calculate payment cost, coin not found"); } - const denomInfo = await ws.getDenomInfo( + const denomInfo = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/recoup.ts b/packages/taler-wallet-core/src/recoup.ts index 0ec71f4e7..ecf55d42b 100644 --- a/packages/taler-wallet-core/src/recoup.ts +++ b/packages/taler-wallet-core/src/recoup.ts @@ -63,7 +63,7 @@ import { } from "./db.js"; import { createRefreshGroup } from "./refresh.js"; import { constructTransactionIdentifier } from "./transactions.js"; -import type { InternalWalletState } from "./wallet.js"; +import { getDenomInfo, type InternalWalletState } from "./wallet.js"; import { internalCreateWithdrawalGroup } from "./withdraw.js"; const logger = new Logger("operations/recoup.ts"); @@ -123,7 +123,7 @@ async function recoupWithdrawCoin( ): Promise<void> { const reservePub = cs.reservePub; const denomInfo = await ws.db.runReadOnlyTx(["denominations"], async (tx) => { - const denomInfo = await ws.getDenomInfo( + const denomInfo = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, @@ -194,7 +194,7 @@ async function recoupRefreshCoin( const d = await ws.db.runReadOnlyTx( ["coins", "denominations"], async (tx) => { - const denomInfo = await ws.getDenomInfo( + const denomInfo = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, @@ -258,13 +258,13 @@ async function recoupRefreshCoin( logger.warn("refresh old coin for recoup not found"); return; } - const oldCoinDenom = await ws.getDenomInfo( + const oldCoinDenom = await getDenomInfo( ws, tx, oldCoin.exchangeBaseUrl, oldCoin.denomPubHash, ); - const revokedCoinDenom = await ws.getDenomInfo( + const revokedCoinDenom = await getDenomInfo( ws, tx, revokedCoin.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts index f1ee84f3e..cc5eff12c 100644 --- a/packages/taler-wallet-core/src/refresh.ts +++ b/packages/taler-wallet-core/src/refresh.ts @@ -99,7 +99,11 @@ import { constructTransactionIdentifier, notifyTransition, } from "./transactions.js"; -import { EXCHANGE_COINS_LOCK, InternalWalletState } from "./wallet.js"; +import { + EXCHANGE_COINS_LOCK, + getDenomInfo, + InternalWalletState, +} from "./wallet.js"; import { getCandidateWithdrawalDenomsTx } from "./withdraw.js"; const logger = new Logger("refresh.ts"); @@ -378,7 +382,7 @@ async function provideRefreshSession( const { availableAmount, availableDenoms } = await ws.db.runReadOnlyTx( ["denominations"], async (tx) => { - const oldDenom = await ws.getDenomInfo( + const oldDenom = await getDenomInfo( ws, tx, exch.exchangeBaseUrl, @@ -516,7 +520,7 @@ async function refreshMelt( const oldCoin = await tx.coins.get(refreshGroup.oldCoinPubs[coinIndex]); checkDbInvariant(!!oldCoin, "melt coin doesn't exist"); - const oldDenom = await ws.getDenomInfo( + const oldDenom = await getDenomInfo( ws, tx, oldCoin.exchangeBaseUrl, @@ -530,7 +534,7 @@ async function refreshMelt( const newCoinDenoms: RefreshNewDenomInfo[] = []; for (const dh of refreshSession.newDenoms) { - const newDenom = await ws.getDenomInfo( + const newDenom = await getDenomInfo( ws, tx, oldCoin.exchangeBaseUrl, @@ -819,7 +823,7 @@ async function refreshReveal( const oldCoin = await tx.coins.get(refreshGroup.oldCoinPubs[coinIndex]); checkDbInvariant(!!oldCoin, "melt coin doesn't exist"); - const oldDenom = await ws.getDenomInfo( + const oldDenom = await getDenomInfo( ws, tx, oldCoin.exchangeBaseUrl, @@ -833,7 +837,7 @@ async function refreshReveal( const newCoinDenoms: RefreshNewDenomInfo[] = []; for (const dh of refreshSession.newDenoms) { - const newDenom = await ws.getDenomInfo( + const newDenom = await getDenomInfo( ws, tx, oldCoin.exchangeBaseUrl, @@ -1162,7 +1166,7 @@ export async function calculateRefreshOutput( for (const ocp of oldCoinPubs) { const coin = await tx.coins.get(ocp.coinPub); checkDbInvariant(!!coin, "coin must be in database"); - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, @@ -1210,7 +1214,7 @@ async function applyRefresh( for (const ocp of oldCoinPubs) { const coin = await tx.coins.get(ocp.coinPub); checkDbInvariant(!!coin, "coin must be in database"); - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, @@ -1420,7 +1424,7 @@ export async function forceRefresh( if (!coin) { throw Error(`coin (pubkey ${c}) not found`); } - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, coin.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index f21db0531..086c2ffa5 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -26,7 +26,7 @@ import { IDBFactory } from "@gnu-taler/idb-bridge"; import { AmountString, Amounts, - AsyncCondition, + CancellationToken, CoinDumpJson, CoinStatus, CoreApiResponse, @@ -135,6 +135,7 @@ import { validateIban, } from "@gnu-taler/taler-util"; import type { HttpRequestLibrary } from "@gnu-taler/taler-util/http"; +import { ObservabilityContext } from "../../taler-util/src/observability.js"; import { getUserAttentions, getUserAttentionsUnreadCount, @@ -269,6 +270,21 @@ import { const logger = new Logger("wallet.ts"); +/** + * Execution context for code that is run in the wallet. + * + * Typically the excecution context is either for a wallet-core + * request handler or for a shepherded task. + */ +export interface WalletExecutionContext { + readonly ws: InternalWalletState; + readonly cryptoApi: TalerCryptoInterface; + readonly cancellationToken: CancellationToken; + readonly http: HttpRequestLibrary; + readonly db: DbAccess<typeof WalletStoresV1>; + readonly oc: ObservabilityContext; +} + export const EXCHANGE_COINS_LOCK = "exchange-coins-lock"; export const EXCHANGE_RESERVES_LOCK = "exchange-reserves-lock"; @@ -440,7 +456,7 @@ async function dumpCoins(ws: InternalWalletState): Promise<CoinDumpJson> { if (cs.type == CoinSourceType.Withdraw) { withdrawalReservePub = cs.reservePub; } - const denomInfo = await ws.getDenomInfo( + const denomInfo = await getDenomInfo( ws, tx, c.exchangeBaseUrl, @@ -1438,6 +1454,24 @@ export class Wallet { } } +export async function getDenomInfo( + ws: InternalWalletState, + tx: WalletDbReadOnlyTransaction<["denominations"]>, + exchangeBaseUrl: string, + denomPubHash: string, +): Promise<DenominationInfo | undefined> { + const key = `${exchangeBaseUrl}:${denomPubHash}`; + const cached = ws.denomCache[key]; + if (cached) { + return cached; + } + const d = await tx.denominations.get([exchangeBaseUrl, denomPubHash]); + if (d) { + return DenominationRecord.toDenomInfo(d); + } + return undefined; +} + /** * Internal state of the wallet. * @@ -1445,10 +1479,9 @@ export class Wallet { */ export class InternalWalletState { cryptoApi: TalerCryptoInterface; - cryptoDispatcher: CryptoDispatcher; + private cryptoDispatcher: CryptoDispatcher; readonly timerGroup: TimerGroup; - workAvailable = new AsyncCondition(); stopped = false; private listeners: NotificationListener[] = []; @@ -1456,7 +1489,7 @@ export class InternalWalletState { initCalled = false; // FIXME: Use an LRU cache here. - private denomCache: Record<string, DenominationInfo> = {}; + denomCache: Record<string, DenominationInfo> = {}; /** * Promises that are waiting for a particular resource. @@ -1517,24 +1550,6 @@ export class InternalWalletState { } } - async getDenomInfo( - ws: InternalWalletState, - tx: WalletDbReadOnlyTransaction<["denominations"]>, - exchangeBaseUrl: string, - denomPubHash: string, - ): Promise<DenominationInfo | undefined> { - const key = `${exchangeBaseUrl}:${denomPubHash}`; - const cached = this.denomCache[key]; - if (cached) { - return cached; - } - const d = await tx.denominations.get([exchangeBaseUrl, denomPubHash]); - if (d) { - return DenominationRecord.toDenomInfo(d); - } - return undefined; - } - notify(n: WalletNotification): void { logger.trace(`Notification: ${j2s(n)}`); for (const l of this.listeners) { diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts index a54295613..c3c3c2a8e 100644 --- a/packages/taler-wallet-core/src/withdraw.ts +++ b/packages/taler-wallet-core/src/withdraw.ts @@ -146,7 +146,7 @@ import { WALLET_BANK_INTEGRATION_PROTOCOL_VERSION, WALLET_EXCHANGE_PROTOCOL_VERSION, } from "./versions.js"; -import type { InternalWalletState } from "./wallet.js"; +import { getDenomInfo, type InternalWalletState } from "./wallet.js"; /** * Logger for this file. @@ -678,12 +678,7 @@ async function processPlanchetGenerate( const denomPubHash = maybeDenomPubHash; const denom = await ws.db.runReadOnlyTx(["denominations"], async (tx) => { - return ws.getDenomInfo( - ws, - tx, - withdrawalGroup.exchangeBaseUrl, - denomPubHash, - ); + return getDenomInfo(ws, tx, withdrawalGroup.exchangeBaseUrl, denomPubHash); }); checkDbInvariant(!!denom); const r = await ws.cryptoApi.createPlanchet({ @@ -943,7 +938,7 @@ async function processPlanchetExchangeBatchRequest( logger.warn("processPlanchet: planchet already withdrawn"); continue; } - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, withdrawalGroup.exchangeBaseUrl, @@ -1057,7 +1052,7 @@ async function processPlanchetVerifyAndStoreCoin( logger.warn("processPlanchet: planchet already withdrawn"); return; } - const denomInfo = await ws.getDenomInfo( + const denomInfo = await getDenomInfo( ws, tx, withdrawalGroup.exchangeBaseUrl, @@ -1814,7 +1809,7 @@ export async function getExchangeWithdrawalInfo( await ws.db.runReadOnlyTx(["denominations"], async (tx) => { for (let i = 0; i < selectedDenoms.selectedDenoms.length; i++) { const ds = selectedDenoms.selectedDenoms[i]; - const denom = await ws.getDenomInfo( + const denom = await getDenomInfo( ws, tx, exchangeBaseUrl, @@ -1911,7 +1906,9 @@ export interface GetWithdrawalDetailsForUriOpts { type WithdrawalOperationMemoryMap = { [uri: string]: boolean | undefined; }; + const ongoingChecks: WithdrawalOperationMemoryMap = {}; + /** * Get more information about a taler://withdraw URI. * @@ -1964,9 +1961,10 @@ export async function getWithdrawalDetailsForUri( info.apiBaseUrl, ws.http, ); - console.log( - `waiting operation (${info.operationId}) to change from pending`, + logger.info( + `waiting for operation (${info.operationId}) to change from pending`, ); + // FIXME: This needs a cancellation token or timeout! bankApi .getWithdrawalOperationById(info.operationId, { old_state: "pending", @@ -1980,11 +1978,6 @@ export async function getWithdrawalDetailsForUri( 2, )}`, ); - ws.notify({ - type: NotificationType.WithdrawalOperationTransition, - operationId: info.operationId, - state: resp.type === "fail" ? info.status : resp.body.status, - }); ongoingChecks[talerWithdrawUri] = false; }); } |