gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: do withdrawal with fewer DB a


From: gnunet
Subject: [taler-wallet-core] branch master updated: do withdrawal with fewer DB accesses
Date: Wed, 12 Jan 2022 16:54:41 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 9f6e3988 do withdrawal with fewer DB accesses
9f6e3988 is described below

commit 9f6e398884ee158cd22c685ce308043a25234095
Author: Florian Dold <florian@dold.me>
AuthorDate: Wed Jan 12 16:54:38 2022 +0100

    do withdrawal with fewer DB accesses
---
 packages/taler-wallet-core/src/db.ts               |  28 ++-
 .../taler-wallet-core/src/operations/pending.ts    |   6 -
 .../taler-wallet-core/src/operations/withdraw.ts   | 208 ++++++++++-----------
 packages/taler-wallet-core/src/pending-types.ts    |   5 -
 4 files changed, 124 insertions(+), 123 deletions(-)

diff --git a/packages/taler-wallet-core/src/db.ts 
b/packages/taler-wallet-core/src/db.ts
index 7f6b08e1..0b2d16ae 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -158,7 +158,7 @@ export interface ReserveRecord {
    *
    * Only applies if bankWithdrawStatusUrl is defined.
    *
-   * Set to 0 if that hasn't happened yet.
+   * Set to undefined if that hasn't happened yet.
    */
   timestampReserveInfoPosted: Timestamp | undefined;
 
@@ -210,7 +210,7 @@ export interface ReserveRecord {
 
   /**
    * Is there any work to be done for this reserve?
-   * 
+   *
    * FIXME: Technically redundant, since the reserveStatus would indicate this.
    */
   operationStatus: OperationStatus;
@@ -1341,6 +1341,9 @@ export interface DenomSelectionState {
  * the coin selection we want to withdraw.
  */
 export interface WithdrawalGroupRecord {
+  /**
+   * Unique identifier for the withdrawal group.
+   */
   withdrawalGroupId: string;
 
   /**
@@ -1348,8 +1351,15 @@ export interface WithdrawalGroupRecord {
    */
   secretSeed: string;
 
+  /**
+   * Public key of the reserve that we're withdrawing from.
+   */
   reservePub: string;
 
+  /**
+   * The exchange base URL that we're withdrawing from.
+   * (Redundantly stored, as the reserve record also has this info.)
+   */
   exchangeBaseUrl: string;
 
   /**
@@ -1363,6 +1373,10 @@ export interface WithdrawalGroupRecord {
    */
   timestampFinish?: Timestamp;
 
+  /**
+   * Operation status of the withdrawal group.
+   * Used for indexing in the database.
+   */
   operationStatus: OperationStatus;
 
   /**
@@ -1371,8 +1385,18 @@ export interface WithdrawalGroupRecord {
    */
   rawWithdrawalAmount: AmountJson;
 
+  /**
+   * Denominations selected for withdrawal.
+   */
   denomsSel: DenomSelectionState;
 
+  /**
+   * UID of the denomination selection.
+   * 
+   * Used for merging backups.
+   * 
+   * FIXME: Should this not also include a timestamp for more logical merging?
+   */
   denomSelUid: string;
 
   /**
diff --git a/packages/taler-wallet-core/src/operations/pending.ts 
b/packages/taler-wallet-core/src/operations/pending.ts
index 07c29e87..99d27583 100644
--- a/packages/taler-wallet-core/src/operations/pending.ts
+++ b/packages/taler-wallet-core/src/operations/pending.ts
@@ -37,13 +37,9 @@ import {
 } from "../pending-types.js";
 import {
   getTimestampNow,
-  isTimestampExpired,
-  j2s,
-  Logger,
   Timestamp,
 } from "@gnu-taler/taler-util";
 import { InternalWalletState } from "../common.js";
-import { getBalancesInsideTransaction } from "./balance.js";
 import { GetReadOnlyAccess } from "../util/query.js";
 
 async function gatherExchangePending(
@@ -353,9 +349,7 @@ export async function getPendingOperations(
       recoupGroups: x.recoupGroups,
     }))
     .runReadWrite(async (tx) => {
-      const walletBalance = await getBalancesInsideTransaction(ws, tx);
       const resp: PendingOperationsResponse = {
-        walletBalance,
         pendingOperations: [],
       };
       await gatherExchangePending(tx, now, resp);
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts 
b/packages/taler-wallet-core/src/operations/withdraw.ts
index c44435e8..dd8a90ad 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -55,6 +55,7 @@ import {
   ExchangeRecord,
   OperationStatus,
   PlanchetRecord,
+  WithdrawalGroupRecord,
 } from "../db.js";
 import { walletCoreDebugFlags } from "../util/debugFlags.js";
 import { readSuccessResponseJsonOrThrow } from "../util/http.js";
@@ -73,7 +74,7 @@ import {
 /**
  * Logger for this file.
  */
-const logger = new Logger("withdraw.ts");
+const logger = new Logger("operations/withdraw.ts");
 
 /**
  * FIXME: Eliminate this in favor of DenomSelectionState.
@@ -351,106 +352,95 @@ export async function getCandidateWithdrawalDenoms(
  */
 async function processPlanchetGenerate(
   ws: InternalWalletState,
-  withdrawalGroupId: string,
+  withdrawalGroup: WithdrawalGroupRecord,
   coinIdx: number,
 ): Promise<void> {
-  const withdrawalGroup = await ws.db
-    .mktx((x) => ({ withdrawalGroups: x.withdrawalGroups }))
-    .runReadOnly(async (tx) => {
-      return await tx.withdrawalGroups.get(withdrawalGroupId);
-    });
-  if (!withdrawalGroup) {
-    return;
-  }
   let planchet = await ws.db
     .mktx((x) => ({
       planchets: x.planchets,
     }))
     .runReadOnly(async (tx) => {
       return tx.planchets.indexes.byGroupAndIndex.get([
-        withdrawalGroupId,
+        withdrawalGroup.withdrawalGroupId,
         coinIdx,
       ]);
     });
-  if (!planchet) {
-    let ci = 0;
-    let denomPubHash: string | undefined;
-    for (
-      let di = 0;
-      di < withdrawalGroup.denomsSel.selectedDenoms.length;
-      di++
-    ) {
-      const d = withdrawalGroup.denomsSel.selectedDenoms[di];
-      if (coinIdx >= ci && coinIdx < ci + d.count) {
-        denomPubHash = d.denomPubHash;
-        break;
-      }
-      ci += d.count;
-    }
-    if (!denomPubHash) {
-      throw Error("invariant violated");
+  if (planchet) {
+    return;
+  }
+  let ci = 0;
+  let denomPubHash: string | undefined;
+  for (let di = 0; di < withdrawalGroup.denomsSel.selectedDenoms.length; di++) 
{
+    const d = withdrawalGroup.denomsSel.selectedDenoms[di];
+    if (coinIdx >= ci && coinIdx < ci + d.count) {
+      denomPubHash = d.denomPubHash;
+      break;
     }
+    ci += d.count;
+  }
+  if (!denomPubHash) {
+    throw Error("invariant violated");
+  }
 
-    const { denom, reserve } = await ws.db
-      .mktx((x) => ({
-        reserves: x.reserves,
-        denominations: x.denominations,
-      }))
-      .runReadOnly(async (tx) => {
-        const denom = await tx.denominations.get([
-          withdrawalGroup.exchangeBaseUrl,
-          denomPubHash!,
-        ]);
-        if (!denom) {
-          throw Error("invariant violated");
-        }
-        const reserve = await tx.reserves.get(withdrawalGroup.reservePub);
-        if (!reserve) {
-          throw Error("invariant violated");
-        }
-        return { denom, reserve };
-      });
-    const r = await ws.cryptoApi.createPlanchet({
-      denomPub: denom.denomPub,
-      feeWithdraw: denom.feeWithdraw,
-      reservePriv: reserve.reservePriv,
-      reservePub: reserve.reservePub,
-      value: denom.value,
-      coinIndex: coinIdx,
-      secretSeed: withdrawalGroup.secretSeed,
+  const { denom, reserve } = await ws.db
+    .mktx((x) => ({
+      reserves: x.reserves,
+      denominations: x.denominations,
+    }))
+    .runReadOnly(async (tx) => {
+      const denom = await tx.denominations.get([
+        withdrawalGroup.exchangeBaseUrl,
+        denomPubHash!,
+      ]);
+      if (!denom) {
+        throw Error("invariant violated");
+      }
+      const reserve = await tx.reserves.get(withdrawalGroup.reservePub);
+      if (!reserve) {
+        throw Error("invariant violated");
+      }
+      return { denom, reserve };
+    });
+  const r = await ws.cryptoApi.createPlanchet({
+    denomPub: denom.denomPub,
+    feeWithdraw: denom.feeWithdraw,
+    reservePriv: reserve.reservePriv,
+    reservePub: reserve.reservePub,
+    value: denom.value,
+    coinIndex: coinIdx,
+    secretSeed: withdrawalGroup.secretSeed,
+  });
+  const newPlanchet: PlanchetRecord = {
+    blindingKey: r.blindingKey,
+    coinEv: r.coinEv,
+    coinEvHash: r.coinEvHash,
+    coinIdx,
+    coinPriv: r.coinPriv,
+    coinPub: r.coinPub,
+    coinValue: r.coinValue,
+    denomPub: r.denomPub,
+    denomPubHash: r.denomPubHash,
+    isFromTip: false,
+    reservePub: r.reservePub,
+    withdrawalDone: false,
+    withdrawSig: r.withdrawSig,
+    withdrawalGroupId: withdrawalGroup.withdrawalGroupId,
+    lastError: undefined,
+  };
+  await ws.db
+    .mktx((x) => ({ planchets: x.planchets }))
+    .runReadWrite(async (tx) => {
+      const p = await tx.planchets.indexes.byGroupAndIndex.get([
+        withdrawalGroup.withdrawalGroupId,
+        coinIdx,
+      ]);
+      if (p) {
+        planchet = p;
+        return;
+      }
+      await tx.planchets.put(newPlanchet);
+      planchet = newPlanchet;
     });
-    const newPlanchet: PlanchetRecord = {
-      blindingKey: r.blindingKey,
-      coinEv: r.coinEv,
-      coinEvHash: r.coinEvHash,
-      coinIdx,
-      coinPriv: r.coinPriv,
-      coinPub: r.coinPub,
-      coinValue: r.coinValue,
-      denomPub: r.denomPub,
-      denomPubHash: r.denomPubHash,
-      isFromTip: false,
-      reservePub: r.reservePub,
-      withdrawalDone: false,
-      withdrawSig: r.withdrawSig,
-      withdrawalGroupId: withdrawalGroupId,
-      lastError: undefined,
-    };
-    await ws.db
-      .mktx((x) => ({ planchets: x.planchets }))
-      .runReadWrite(async (tx) => {
-        const p = await tx.planchets.indexes.byGroupAndIndex.get([
-          withdrawalGroupId,
-          coinIdx,
-        ]);
-        if (p) {
-          planchet = p;
-          return;
-        }
-        await tx.planchets.put(newPlanchet);
-        planchet = newPlanchet;
-      });
-  }
 }
 
 /**
@@ -460,7 +450,7 @@ async function processPlanchetGenerate(
  */
 async function processPlanchetExchangeRequest(
   ws: InternalWalletState,
-  withdrawalGroupId: string,
+  withdrawalGroup: WithdrawalGroupRecord,
   coinIdx: number,
 ): Promise<WithdrawResponse | undefined> {
   const d = await ws.db
@@ -471,12 +461,8 @@ async function processPlanchetExchangeRequest(
       denominations: x.denominations,
     }))
     .runReadOnly(async (tx) => {
-      const withdrawalGroup = await tx.withdrawalGroups.get(withdrawalGroupId);
-      if (!withdrawalGroup) {
-        return;
-      }
       let planchet = await tx.planchets.indexes.byGroupAndIndex.get([
-        withdrawalGroupId,
+        withdrawalGroup.withdrawalGroupId,
         coinIdx,
       ]);
       if (!planchet) {
@@ -503,7 +489,7 @@ async function processPlanchetExchangeRequest(
       }
 
       logger.trace(
-        `processing planchet #${coinIdx} in withdrawal ${withdrawalGroupId}`,
+        `processing planchet #${coinIdx} in withdrawal 
${withdrawalGroup.withdrawalGroupId}`,
       );
 
       const reqBody: any = {
@@ -543,7 +529,7 @@ async function processPlanchetExchangeRequest(
       .mktx((x) => ({ planchets: x.planchets }))
       .runReadWrite(async (tx) => {
         let planchet = await tx.planchets.indexes.byGroupAndIndex.get([
-          withdrawalGroupId,
+          withdrawalGroup.withdrawalGroupId,
           coinIdx,
         ]);
         if (!planchet) {
@@ -558,7 +544,7 @@ async function processPlanchetExchangeRequest(
 
 async function processPlanchetVerifyAndStoreCoin(
   ws: InternalWalletState,
-  withdrawalGroupId: string,
+  withdrawalGroup: WithdrawalGroupRecord,
   coinIdx: number,
   resp: WithdrawResponse,
 ): Promise<void> {
@@ -568,12 +554,8 @@ async function processPlanchetVerifyAndStoreCoin(
       planchets: x.planchets,
     }))
     .runReadOnly(async (tx) => {
-      const withdrawalGroup = await tx.withdrawalGroups.get(withdrawalGroupId);
-      if (!withdrawalGroup) {
-        return;
-      }
       let planchet = await tx.planchets.indexes.byGroupAndIndex.get([
-        withdrawalGroupId,
+        withdrawalGroup.withdrawalGroupId,
         coinIdx,
       ]);
       if (!planchet) {
@@ -635,7 +617,7 @@ async function processPlanchetVerifyAndStoreCoin(
       .mktx((x) => ({ planchets: x.planchets }))
       .runReadWrite(async (tx) => {
         let planchet = await tx.planchets.indexes.byGroupAndIndex.get([
-          withdrawalGroupId,
+          withdrawalGroup.withdrawalGroupId,
           coinIdx,
         ]);
         if (!planchet) {
@@ -679,7 +661,7 @@ async function processPlanchetVerifyAndStoreCoin(
       type: CoinSourceType.Withdraw,
       coinIndex: coinIdx,
       reservePub: planchet.reservePub,
-      withdrawalGroupId: withdrawalGroupId,
+      withdrawalGroupId: withdrawalGroup.withdrawalGroupId,
     },
     suspended: false,
   };
@@ -694,10 +676,6 @@ async function processPlanchetVerifyAndStoreCoin(
       planchets: x.planchets,
     }))
     .runReadWrite(async (tx) => {
-      const ws = await tx.withdrawalGroups.get(withdrawalGroupId);
-      if (!ws) {
-        return false;
-      }
       const p = await tx.planchets.get(planchetCoinPub);
       if (!p || p.withdrawalDone) {
         return false;
@@ -914,7 +892,7 @@ async function processWithdrawGroupImpl(
   let work: Promise<void>[] = [];
 
   for (let i = 0; i < numTotalCoins; i++) {
-    work.push(processPlanchetGenerate(ws, withdrawalGroupId, i));
+    work.push(processPlanchetGenerate(ws, withdrawalGroup, i));
   }
 
   // Generate coins concurrently (parallelism only happens in the crypto API 
workers)
@@ -925,14 +903,14 @@ async function processWithdrawGroupImpl(
   for (let coinIdx = 0; coinIdx < numTotalCoins; coinIdx++) {
     const resp = await processPlanchetExchangeRequest(
       ws,
-      withdrawalGroupId,
+      withdrawalGroup,
       coinIdx,
     );
     if (!resp) {
       continue;
     }
     work.push(
-      processPlanchetVerifyAndStoreCoin(ws, withdrawalGroupId, coinIdx, resp),
+      processPlanchetVerifyAndStoreCoin(ws, withdrawalGroup, coinIdx, resp),
     );
   }
 
@@ -1089,6 +1067,13 @@ export async function getExchangeWithdrawalInfo(
   return ret;
 }
 
+/**
+ * Get more information about a taler://withdraw URI.
+ *
+ * As side effects, the bank (via the bank integration API) is queried
+ * and the exchange suggested by the bank is permanently added
+ * to the wallet's list of known exchanges.
+ */
 export async function getWithdrawalDetailsForUri(
   ws: InternalWalletState,
   talerWithdrawUri: string,
@@ -1110,6 +1095,9 @@ export async function getWithdrawalDetailsForUri(
     }
   }
 
+  // Extract information about possible exchanges for the withdrawal
+  // operation from the database.
+
   const exchanges: ExchangeListItem[] = [];
 
   await ws.db
diff --git a/packages/taler-wallet-core/src/pending-types.ts 
b/packages/taler-wallet-core/src/pending-types.ts
index 5033163a..911d0d8b 100644
--- a/packages/taler-wallet-core/src/pending-types.ts
+++ b/packages/taler-wallet-core/src/pending-types.ts
@@ -248,9 +248,4 @@ export interface PendingOperationsResponse {
    * List of pending operations.
    */
   pendingOperations: PendingTaskInfo[];
-
-  /**
-   * Current wallet balance, including pending balances.
-   */
-  walletBalance: BalancesResponse;
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]