gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: wallet-core: simplify/improve


From: gnunet
Subject: [taler-wallet-core] branch master updated: wallet-core: simplify/improve insufficient balance details computation
Date: Thu, 07 Mar 2024 11:33:48 +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 5ca3c7878 wallet-core: simplify/improve insufficient balance details 
computation
5ca3c7878 is described below

commit 5ca3c7878da9a495c67ea7faed91c8dbce04e603
Author: Florian Dold <florian@dold.me>
AuthorDate: Thu Mar 7 11:33:41 2024 +0100

    wallet-core: simplify/improve insufficient balance details computation
---
 packages/taler-util/src/wallet-types.ts            |   4 +
 packages/taler-wallet-core/src/balance.ts          | 167 +++++++--------------
 packages/taler-wallet-core/src/coinSelection.ts    |  10 ++
 .../src/cta/Payment/stories.tsx                    |   6 +
 4 files changed, 76 insertions(+), 111 deletions(-)

diff --git a/packages/taler-util/src/wallet-types.ts 
b/packages/taler-util/src/wallet-types.ts
index 8be8fc4a0..cfbed04dc 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -882,6 +882,10 @@ export interface PaymentInsufficientBalanceDetails {
       balanceAvailable: AmountString;
       balanceMaterial: AmountString;
       balanceExchangeDepositable: AmountString;
+      balanceAgeAcceptable: AmountString;
+      balanceMerchantAcceptable: AmountString;
+      balanceMerchantDepositable: AmountString;
+      maxEffectiveSpendAmount: AmountString;
     };
   };
 }
diff --git a/packages/taler-wallet-core/src/balance.ts 
b/packages/taler-wallet-core/src/balance.ts
index 4c58814a1..26d348b39 100644
--- a/packages/taler-wallet-core/src/balance.ts
+++ b/packages/taler-wallet-core/src/balance.ts
@@ -59,8 +59,6 @@ import {
   assertUnreachable,
   BalanceFlag,
   BalancesResponse,
-  canonicalizeBaseUrl,
-  checkLogicInvariant,
   GetBalanceDetailRequest,
   Logger,
   parsePaytoUri,
@@ -487,100 +485,6 @@ export interface AcceptableExchanges {
   depositableExchanges: string[];
 }
 
-/**
- * Get all exchanges that are acceptable for a particular payment.
- */
-async function getAcceptableExchangeBaseUrlsInTx(
-  wex: WalletExecutionContext,
-  tx: WalletDbReadOnlyTransaction<["exchanges", "exchangeDetails"]>,
-  req: PaymentRestrictionsForBalance,
-): Promise<AcceptableExchanges> {
-  const acceptableExchangeUrls = new Set<string>();
-  const depositableExchangeUrls = new Set<string>();
-  // FIXME: We should have a DB index to look up all exchanges
-  // for a particular auditor ...
-
-  const canonExchanges = new Set<string>();
-  const canonAuditors = new Set<string>();
-
-  if (req.restrictExchanges) {
-    for (const exchangeHandle of req.restrictExchanges.exchanges) {
-      const normUrl = canonicalizeBaseUrl(exchangeHandle.exchangeBaseUrl);
-      canonExchanges.add(normUrl);
-    }
-
-    for (const auditorHandle of req.restrictExchanges.auditors) {
-      const normUrl = canonicalizeBaseUrl(auditorHandle.auditorBaseUrl);
-      canonAuditors.add(normUrl);
-    }
-  }
-
-  await tx.exchanges.iter().forEachAsync(async (exchange) => {
-    const dp = exchange.detailsPointer;
-    if (!dp) {
-      return;
-    }
-    const { currency, masterPublicKey } = dp;
-    const exchangeDetails = await tx.exchangeDetails.indexes.byPointer.get([
-      exchange.baseUrl,
-      currency,
-      masterPublicKey,
-    ]);
-    if (!exchangeDetails) {
-      return;
-    }
-
-    let acceptable = false;
-
-    if (canonExchanges.has(exchange.baseUrl)) {
-      acceptableExchangeUrls.add(exchange.baseUrl);
-      acceptable = true;
-    }
-    for (const exchangeAuditor of exchangeDetails.auditors) {
-      if (canonAuditors.has(exchangeAuditor.auditor_url)) {
-        acceptableExchangeUrls.add(exchange.baseUrl);
-        acceptable = true;
-        break;
-      }
-    }
-
-    if (!acceptable) {
-      return;
-    }
-    // FIXME: Also consider exchange and auditor public key
-    // instead of just base URLs?
-
-    let wireMethodSupported = false;
-
-    if (req.restrictWireMethods) {
-      for (const acc of exchangeDetails.wireInfo.accounts) {
-        const pp = parsePaytoUri(acc.payto_uri);
-        checkLogicInvariant(!!pp);
-        for (const wm of req.restrictWireMethods) {
-          if (pp.targetType === wm) {
-            wireMethodSupported = true;
-            break;
-          }
-          if (wireMethodSupported) {
-            break;
-          }
-        }
-      }
-    } else {
-      wireMethodSupported = true;
-    }
-
-    acceptableExchangeUrls.add(exchange.baseUrl);
-    if (wireMethodSupported) {
-      depositableExchangeUrls.add(exchange.baseUrl);
-    }
-  });
-  return {
-    acceptableExchanges: [...acceptableExchangeUrls],
-    depositableExchanges: [...depositableExchangeUrls],
-  };
-}
-
 export interface PaymentBalanceDetails {
   /**
    * Balance of type "available" (see balance.ts for definition).
@@ -648,8 +552,6 @@ export async function getPaymentBalanceDetailsInTx(
   >,
   req: PaymentRestrictionsForBalance,
 ): Promise<PaymentBalanceDetails> {
-  const acceptability = await getAcceptableExchangeBaseUrlsInTx(wex, tx, req);
-
   const d: PaymentBalanceDetails = {
     balanceAvailable: Amounts.zeroOfCurrency(req.currency),
     balanceMaterial: Amounts.zeroOfCurrency(req.currency),
@@ -691,38 +593,64 @@ export async function getPaymentBalanceDetailsInTx(
       ca.freshCoinCount,
     ).amount;
 
-    d.maxEffectiveSpendAmount = Amounts.add(
-      d.maxEffectiveSpendAmount,
-      Amounts.mult(ca.value, ca.freshCoinCount).amount,
-    ).amount;
-
-    d.maxEffectiveSpendAmount = Amounts.sub(
-      d.maxEffectiveSpendAmount,
-      Amounts.mult(denom.feeDeposit, ca.freshCoinCount).amount,
-    ).amount;
-
     let wireOkay = false;
     if (req.restrictWireMethods == null) {
       wireOkay = true;
     } else {
       for (const wm of req.restrictWireMethods) {
         const wmf = findMatchingWire(wm, req.depositPaytoUri, wireDetails);
+        if (wmf) {
+          wireOkay = true;
+          break;
+        }
+      }
+    }
+
+    if (wireOkay) {
+      d.balanceExchangeDepositable = Amounts.add(
+        d.balanceExchangeDepositable,
+        coinAmount,
+      ).amount;
+    }
+
+    let ageOkay = ca.maxAge === 0 || ca.maxAge > req.minAge;
+
+    let merchantExchangeAcceptable = false;
+
+    if (!req.restrictExchanges) {
+      merchantExchangeAcceptable = true;
+    } else {
+      for (const ex of req.restrictExchanges.exchanges) {
+        if (ex.exchangeBaseUrl === ca.exchangeBaseUrl) {
+          merchantExchangeAcceptable = true;
+          break;
+        }
+      }
+      for (const acceptedAuditor of req.restrictExchanges.auditors) {
+        for (const exchangeAuditor of wireDetails.auditors) {
+          if (acceptedAuditor.auditorBaseUrl === exchangeAuditor.auditor_url) {
+            merchantExchangeAcceptable = true;
+            break;
+          }
+        }
       }
     }
 
+    const merchantExchangeDepositable = merchantExchangeAcceptable && wireOkay;
+
     d.balanceAvailable = Amounts.add(d.balanceAvailable, coinAmount).amount;
     d.balanceMaterial = Amounts.add(d.balanceMaterial, coinAmount).amount;
-    if (ca.maxAge === 0 || ca.maxAge > req.minAge) {
+    if (ageOkay) {
       d.balanceAgeAcceptable = Amounts.add(
         d.balanceAgeAcceptable,
         coinAmount,
       ).amount;
-      if (acceptability.acceptableExchanges.includes(ca.exchangeBaseUrl)) {
+      if (merchantExchangeAcceptable) {
         d.balanceMerchantAcceptable = Amounts.add(
           d.balanceMerchantAcceptable,
           coinAmount,
         ).amount;
-        if (acceptability.depositableExchanges.includes(ca.exchangeBaseUrl)) {
+        if (merchantExchangeDepositable) {
           d.balanceMerchantDepositable = Amounts.add(
             d.balanceMerchantDepositable,
             coinAmount,
@@ -730,6 +658,23 @@ export async function getPaymentBalanceDetailsInTx(
         }
       }
     }
+
+    if (
+      ageOkay &&
+      wireOkay &&
+      merchantExchangeAcceptable &&
+      merchantExchangeDepositable
+    ) {
+      d.maxEffectiveSpendAmount = Amounts.add(
+        d.maxEffectiveSpendAmount,
+        Amounts.mult(ca.value, ca.freshCoinCount).amount,
+      ).amount;
+
+      d.maxEffectiveSpendAmount = Amounts.sub(
+        d.maxEffectiveSpendAmount,
+        Amounts.mult(denom.feeDeposit, ca.freshCoinCount).amount,
+      ).amount;
+    }
   }
 
   await tx.refreshGroups.iter().forEach((r) => {
diff --git a/packages/taler-wallet-core/src/coinSelection.ts 
b/packages/taler-wallet-core/src/coinSelection.ts
index 695be79ac..87b29a998 100644
--- a/packages/taler-wallet-core/src/coinSelection.ts
+++ b/packages/taler-wallet-core/src/coinSelection.ts
@@ -425,6 +425,16 @@ export async function reportInsufficientBalanceDetails(
       balanceExchangeDepositable: Amounts.stringify(
         exchDet.balanceExchangeDepositable,
       ),
+      balanceAgeAcceptable: Amounts.stringify(exchDet.balanceAgeAcceptable),
+      balanceMerchantAcceptable: Amounts.stringify(
+        exchDet.balanceMerchantAcceptable,
+      ),
+      balanceMerchantDepositable: Amounts.stringify(
+        exchDet.balanceMerchantDepositable,
+      ),
+      maxEffectiveSpendAmount: Amounts.stringify(
+        exchDet.maxEffectiveSpendAmount,
+      ),
     };
   }
 
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx 
b/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx
index 567b5c177..93b96c836 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx
@@ -60,6 +60,7 @@ export const NoEnoughBalanceAvailable = 
tests.createExample(BaseView, {
       balanceMerchantAcceptable: "USD:9" as AmountString,
       balanceMerchantDepositable: "USD:9" as AmountString,
       maxEffectiveSpendAmount: "USD:9.5" as AmountString,
+      balanceExchangeDepositable: "USD:9.5" as AmountString,
       perExchange: {},
     },
     talerUri: "taler://pay/..",
@@ -101,6 +102,7 @@ export const NoEnoughBalanceMaterial = 
tests.createExample(BaseView, {
       balanceMerchantAcceptable: "USD:9" as AmountString,
       balanceMerchantDepositable: "USD:0" as AmountString,
       maxEffectiveSpendAmount: "USD:9.5" as AmountString,
+      balanceExchangeDepositable: "USD:9.5" as AmountString,
       perExchange: {},
     },
     talerUri: "taler://pay/..",
@@ -142,6 +144,7 @@ export const NoEnoughBalanceAgeAcceptable = 
tests.createExample(BaseView, {
       balanceMerchantAcceptable: "USD:9" as AmountString,
       balanceMerchantDepositable: "USD:9" as AmountString,
       maxEffectiveSpendAmount: "USD:9.5" as AmountString,
+      balanceExchangeDepositable: "USD:9.5" as AmountString,
       perExchange: {},
     },
     talerUri: "taler://pay/..",
@@ -184,6 +187,7 @@ export const NoEnoughBalanceMerchantAcceptable = 
tests.createExample(BaseView, {
       balanceMerchantAcceptable: "USD:9" as AmountString,
       balanceMerchantDepositable: "USD:9" as AmountString,
       maxEffectiveSpendAmount: "USD:9.5" as AmountString,
+      balanceExchangeDepositable: "USD:9.5" as AmountString,
       perExchange: {},
     },
     talerUri: "taler://pay/..",
@@ -227,6 +231,7 @@ export const NoEnoughBalanceMerchantDepositable = 
tests.createExample(
         balanceMerchantAcceptable: "USD:10" as AmountString,
         balanceMerchantDepositable: "USD:9" as AmountString,
         maxEffectiveSpendAmount: "USD:9.5" as AmountString,
+        balanceExchangeDepositable: "USD:9.5" as AmountString,
         perExchange: {},
       },
       talerUri: "taler://pay/..",
@@ -269,6 +274,7 @@ export const NoEnoughBalanceFeeGap = 
tests.createExample(BaseView, {
       balanceMerchantAcceptable: "USD:10" as AmountString,
       balanceMerchantDepositable: "USD:10" as AmountString,
       maxEffectiveSpendAmount: "USD:9.5" as AmountString,
+      balanceExchangeDepositable: "USD:9.5" as AmountString,
       perExchange: {},
     },
     talerUri: "taler://pay/..",

-- 
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]