commit 392d95a9cebf57e34ac81b1ec86d79828e0996cc
parent c39124414fa013a6bd42ee48c646775429776aa5
Author: Florian Dold <dold@taler.net>
Date: Wed, 19 Aug 2026 21:42:07 +0200
wallet-core: batch deposit and recoup lookups
Diffstat:
2 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts
@@ -899,6 +899,10 @@ async function refundDepositGroup(
// as we don't know if deposit request will still arrive
// before doing the refresh.
const refundReqPerCoin: ExchangeRefundRequest[] = Array(newTxPerCoin.length);
+ const coins = await wex.runWalletDbTx((tx) =>
+ tx.getCoinsByPubs(payCoinSelection.coinPubs),
+ );
+ const coinsByPub = new Map(coins.map((coin) => [coin.coinPub, coin]));
for (let i = 0; i < statusPerCoin.length; i++) {
const st = statusPerCoin[i];
@@ -909,11 +913,9 @@ async function refundDepositGroup(
break;
default: {
const coinPub = payCoinSelection.coinPubs[i];
- const coinExchange = await wex.runWalletDbTx(async (tx) => {
- const coinRecord = await tx.getCoin(coinPub);
- checkDbInvariant(!!coinRecord, `coin ${coinPub} not found in DB`);
- return coinRecord.exchangeBaseUrl;
- });
+ const coinRecord = coinsByPub.get(coinPub);
+ checkDbInvariant(!!coinRecord, `coin ${coinPub} not found in DB`);
+ const coinExchange = coinRecord.exchangeBaseUrl;
const refundAmount = payCoinSelection.coinContributions[i];
// We use a constant refund transaction ID, since there can
// only be one refund for this contract.
diff --git a/packages/taler-wallet-core/src/recoup.ts b/packages/taler-wallet-core/src/recoup.ts
@@ -305,25 +305,26 @@ export async function processRecoupGroup(
const reserveSet = new Set<string>();
const reservePrivMap: Record<string, string> = {};
- for (let i = 0; i < recoupGroup.coinPubs.length; i++) {
- const coinPub = recoupGroup.coinPubs[i];
- await wex.runWalletDbTx(async (tx) => {
- const coin = await tx.getCoin(coinPub);
+ await wex.runWalletDbTx(async (tx) => {
+ const coins = await tx.getCoinsByPubs(recoupGroup.coinPubs);
+ const coinsByPub = new Map(coins.map((coin) => [coin.coinPub, coin]));
+ const reservePubs: string[] = [];
+ for (const coinPub of recoupGroup.coinPubs) {
+ const coin = coinsByPub.get(coinPub);
if (!coin) {
throw Error(`Coin ${coinPub} not found, can't request recoup`);
}
if (coin.coinSource.type === CoinSourceType.Withdraw) {
- const reserve = await tx.getReserveByReservePub(
- coin.coinSource.reservePub,
- );
- if (!reserve) {
- return;
- }
- reserveSet.add(coin.coinSource.reservePub);
- reservePrivMap[coin.coinSource.reservePub] = reserve.reservePriv;
+ reservePubs.push(coin.coinSource.reservePub);
}
- });
- }
+ }
+ const uniqueReservePubs = [...new Set(reservePubs)];
+ const reserves = await tx.getReservesByPubs(uniqueReservePubs);
+ for (const reserve of reserves) {
+ reserveSet.add(reserve.reservePub);
+ reservePrivMap[reserve.reservePub] = reserve.reservePriv;
+ }
+ });
for (const reservePub of reserveSet) {
logger.info(`querying reserve status for recoup of ${reservePub}`);