From 523280b3862b528512ff93c651bc0d9ed632fbf6 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 27 Feb 2024 17:39:58 +0100 Subject: wallet-core: thread through wallet execution context --- packages/taler-wallet-core/src/recoup.ts | 79 +++++++++++++++++--------------- 1 file changed, 41 insertions(+), 38 deletions(-) (limited to 'packages/taler-wallet-core/src/recoup.ts') diff --git a/packages/taler-wallet-core/src/recoup.ts b/packages/taler-wallet-core/src/recoup.ts index 3ef494c3a..8d5d3dd1f 100644 --- a/packages/taler-wallet-core/src/recoup.ts +++ b/packages/taler-wallet-core/src/recoup.ts @@ -63,7 +63,11 @@ import { } from "./db.js"; import { createRefreshGroup } from "./refresh.js"; import { constructTransactionIdentifier } from "./transactions.js"; -import { getDenomInfo, type InternalWalletState } from "./wallet.js"; +import { + WalletExecutionContext, + getDenomInfo, + type InternalWalletState, +} from "./wallet.js"; import { internalCreateWithdrawalGroup } from "./withdraw.js"; export const logger = new Logger("operations/recoup.ts"); @@ -73,7 +77,7 @@ export const logger = new Logger("operations/recoup.ts"); * a coin in the group as finished. */ export async function putGroupAsFinished( - ws: InternalWalletState, + wex: WalletExecutionContext, tx: WalletDbReadWriteTransaction< ["recoupGroups", "denominations", "refreshGroups", "coins"] >, @@ -91,7 +95,7 @@ export async function putGroupAsFinished( } async function recoupRewardCoin( - ws: InternalWalletState, + wex: WalletExecutionContext, recoupGroupId: string, coinIdx: number, coin: CoinRecord, @@ -99,7 +103,7 @@ async function recoupRewardCoin( // We can't really recoup a coin we got via tipping. // Thus we just put the coin to sleep. // FIXME: somehow report this to the user - await ws.db.runReadWriteTx( + await wex.db.runReadWriteTx( ["recoupGroups", "denominations", "refreshGroups", "coins"], async (tx) => { const recoupGroup = await tx.recoupGroups.get(recoupGroupId); @@ -109,23 +113,23 @@ async function recoupRewardCoin( if (recoupGroup.recoupFinishedPerCoin[coinIdx]) { return; } - await putGroupAsFinished(ws, tx, recoupGroup, coinIdx); + await putGroupAsFinished(wex, tx, recoupGroup, coinIdx); }, ); } async function recoupRefreshCoin( - ws: InternalWalletState, + wex: WalletExecutionContext, recoupGroupId: string, coinIdx: number, coin: CoinRecord, cs: RefreshCoinSource, ): Promise { - const d = await ws.db.runReadOnlyTx( + const d = await wex.db.runReadOnlyTx( ["coins", "denominations"], async (tx) => { const denomInfo = await getDenomInfo( - ws, + wex, tx, coin.exchangeBaseUrl, coin.denomPubHash, @@ -141,7 +145,7 @@ async function recoupRefreshCoin( return; } - const recoupRequest = await ws.cryptoApi.createRecoupRefreshRequest({ + const recoupRequest = await wex.cryptoApi.createRecoupRefreshRequest({ blindingKey: coin.blindingKey, coinPriv: coin.coinPriv, coinPub: coin.coinPub, @@ -155,7 +159,7 @@ async function recoupRefreshCoin( ); logger.trace(`making recoup request for ${coin.coinPub}`); - const resp = await ws.http.fetch(reqUrl.href, { + const resp = await wex.http.fetch(reqUrl.href, { method: "POST", body: recoupRequest, }); @@ -168,7 +172,7 @@ async function recoupRefreshCoin( throw Error(`Coin's oldCoinPub doesn't match reserve on recoup`); } - await ws.db.runReadWriteTx( + await wex.db.runReadWriteTx( ["coins", "denominations", "recoupGroups", "refreshGroups"], async (tx) => { const recoupGroup = await tx.recoupGroups.get(recoupGroupId); @@ -189,13 +193,13 @@ async function recoupRefreshCoin( return; } const oldCoinDenom = await getDenomInfo( - ws, + wex, tx, oldCoin.exchangeBaseUrl, oldCoin.denomPubHash, ); const revokedCoinDenom = await getDenomInfo( - ws, + wex, tx, revokedCoin.exchangeBaseUrl, revokedCoin.denomPubHash, @@ -220,22 +224,22 @@ async function recoupRefreshCoin( } await tx.coins.put(revokedCoin); await tx.coins.put(oldCoin); - await putGroupAsFinished(ws, tx, recoupGroup, coinIdx); + await putGroupAsFinished(wex, tx, recoupGroup, coinIdx); }, ); } export async function recoupWithdrawCoin( - ws: InternalWalletState, + wex: WalletExecutionContext, recoupGroupId: string, coinIdx: number, coin: CoinRecord, cs: WithdrawCoinSource, ): Promise { const reservePub = cs.reservePub; - const denomInfo = await ws.db.runReadOnlyTx(["denominations"], async (tx) => { + const denomInfo = await wex.db.runReadOnlyTx(["denominations"], async (tx) => { const denomInfo = await getDenomInfo( - ws, + wex, tx, coin.exchangeBaseUrl, coin.denomPubHash, @@ -247,7 +251,7 @@ export async function recoupWithdrawCoin( return; } - const recoupRequest = await ws.cryptoApi.createRecoupRequest({ + const recoupRequest = await wex.cryptoApi.createRecoupRequest({ blindingKey: coin.blindingKey, coinPriv: coin.coinPriv, coinPub: coin.coinPub, @@ -257,7 +261,7 @@ export async function recoupWithdrawCoin( }); const reqUrl = new URL(`/coins/${coin.coinPub}/recoup`, coin.exchangeBaseUrl); logger.trace(`requesting recoup via ${reqUrl.href}`); - const resp = await ws.http.fetch(reqUrl.href, { + const resp = await wex.http.fetch(reqUrl.href, { method: "POST", body: recoupRequest, }); @@ -273,7 +277,7 @@ export async function recoupWithdrawCoin( } // FIXME: verify that our expectations about the amount match - await ws.db.runReadWriteTx( + await wex.db.runReadWriteTx( ["coins", "denominations", "recoupGroups", "refreshGroups"], async (tx) => { const recoupGroup = await tx.recoupGroups.get(recoupGroupId); @@ -289,17 +293,16 @@ export async function recoupWithdrawCoin( } updatedCoin.status = CoinStatus.Dormant; await tx.coins.put(updatedCoin); - await putGroupAsFinished(ws, tx, recoupGroup, coinIdx); + await putGroupAsFinished(wex, tx, recoupGroup, coinIdx); }, ); } export async function processRecoupGroup( - ws: InternalWalletState, + wex: WalletExecutionContext, recoupGroupId: string, - cancellationToken: CancellationToken, ): Promise { - let recoupGroup = await ws.db.runReadOnlyTx(["recoupGroups"], async (tx) => { + let recoupGroup = await wex.db.runReadOnlyTx(["recoupGroups"], async (tx) => { return tx.recoupGroups.get(recoupGroupId); }); if (!recoupGroup) { @@ -311,7 +314,7 @@ export async function processRecoupGroup( } const ps = recoupGroup.coinPubs.map(async (x, i) => { try { - await processRecoupForCoin(ws, recoupGroupId, i); + await processRecoupForCoin(wex, recoupGroupId, i); } catch (e) { logger.warn(`processRecoup failed: ${e}`); throw e; @@ -319,7 +322,7 @@ export async function processRecoupGroup( }); await Promise.all(ps); - recoupGroup = await ws.db.runReadOnlyTx(["recoupGroups"], async (tx) => { + recoupGroup = await wex.db.runReadOnlyTx(["recoupGroups"], async (tx) => { return tx.recoupGroups.get(recoupGroupId); }); if (!recoupGroup) { @@ -338,7 +341,7 @@ export async function processRecoupGroup( const reservePrivMap: Record = {}; for (let i = 0; i < recoupGroup.coinPubs.length; i++) { const coinPub = recoupGroup.coinPubs[i]; - await ws.db.runReadOnlyTx(["coins", "reserves"], async (tx) => { + await wex.db.runReadOnlyTx(["coins", "reserves"], async (tx) => { const coin = await tx.coins.get(coinPub); if (!coin) { throw Error(`Coin ${coinPub} not found, can't request recoup`); @@ -363,13 +366,13 @@ export async function processRecoupGroup( ); logger.info(`querying reserve status for recoup via ${reserveUrl}`); - const resp = await ws.http.fetch(reserveUrl.href); + const resp = await wex.http.fetch(reserveUrl.href); const result = await readSuccessResponseJsonOrThrow( resp, codecForReserveStatus(), ); - await internalCreateWithdrawalGroup(ws, { + await internalCreateWithdrawalGroup(wex, { amount: Amounts.parseOrThrow(result.balance), exchangeBaseUrl: recoupGroup.exchangeBaseUrl, reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus, @@ -383,7 +386,7 @@ export async function processRecoupGroup( }); } - await ws.db.runReadWriteTx( + await wex.db.runReadWriteTx( [ "recoupGroups", "coinAvailability", @@ -400,7 +403,7 @@ export async function processRecoupGroup( rg2.operationStatus = RecoupOperationStatus.Finished; if (rg2.scheduleRefreshCoins.length > 0) { await createRefreshGroup( - ws, + wex, tx, Amounts.currencyOf(rg2.scheduleRefreshCoins[0].amount), rg2.scheduleRefreshCoins, @@ -452,7 +455,7 @@ export class RewardTransactionContext implements TransactionContext { } export async function createRecoupGroup( - ws: InternalWalletState, + wex: WalletExecutionContext, tx: WalletDbReadWriteTransaction< ["recoupGroups", "denominations", "refreshGroups", "coins"] >, @@ -476,7 +479,7 @@ export async function createRecoupGroup( const coinPub = coinPubs[coinIdx]; const coin = await tx.coins.get(coinPub); if (!coin) { - await putGroupAsFinished(ws, tx, recoupGroup, coinIdx); + await putGroupAsFinished(wex, tx, recoupGroup, coinIdx); continue; } await tx.coins.put(coin); @@ -491,11 +494,11 @@ export async function createRecoupGroup( * Run the recoup protocol for a single coin in a recoup group. */ async function processRecoupForCoin( - ws: InternalWalletState, + wex: WalletExecutionContext, recoupGroupId: string, coinIdx: number, ): Promise { - const coin = await ws.db.runReadOnlyTx( + const coin = await wex.db.runReadOnlyTx( ["coins", "recoupGroups"], async (tx) => { const recoupGroup = await tx.recoupGroups.get(recoupGroupId); @@ -527,11 +530,11 @@ async function processRecoupForCoin( switch (cs.type) { case CoinSourceType.Reward: - return recoupRewardCoin(ws, recoupGroupId, coinIdx, coin); + return recoupRewardCoin(wex, recoupGroupId, coinIdx, coin); case CoinSourceType.Refresh: - return recoupRefreshCoin(ws, recoupGroupId, coinIdx, coin, cs); + return recoupRefreshCoin(wex, recoupGroupId, coinIdx, coin, cs); case CoinSourceType.Withdraw: - return recoupWithdrawCoin(ws, recoupGroupId, coinIdx, coin, cs); + return recoupWithdrawCoin(wex, recoupGroupId, coinIdx, coin, cs); default: throw Error("unknown coin source type"); } -- cgit v1.2.3