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: use division for


From: gnunet
Subject: [taler-wallet-core] branch master updated: wallet-core: use division for withdrawal coin selection
Date: Wed, 24 May 2023 12:54:10 +0200

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 ea953f2b7 wallet-core: use division for withdrawal coin selection
ea953f2b7 is described below

commit ea953f2b772b07780b94daecdefde6cd253a7e90
Author: Florian Dold <florian@dold.me>
AuthorDate: Wed May 24 12:54:07 2023 +0200

    wallet-core: use division for withdrawal coin selection
---
 packages/taler-util/src/amounts.test.ts            | 10 ++++++++
 packages/taler-util/src/amounts.ts                 | 28 ++++++++++++++++++++++
 .../taler-wallet-core/src/util/coinSelection.ts    | 11 +++------
 3 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/packages/taler-util/src/amounts.test.ts 
b/packages/taler-util/src/amounts.test.ts
index 064023e2d..644b8bdb4 100644
--- a/packages/taler-util/src/amounts.test.ts
+++ b/packages/taler-util/src/amounts.test.ts
@@ -138,3 +138,13 @@ test("amount multiplication", (t) => {
   t.is(Amounts.stringify(Amounts.mult(sAmt("EUR:1.11"), 4).amount), 
"EUR:4.44");
   t.is(Amounts.stringify(Amounts.mult(sAmt("EUR:1.11"), 5).amount), 
"EUR:5.55");
 });
+
+
+
+test("amount division", (t) => {
+  t.is(Amounts.divmod("EUR:5", "EUR:1").quotient, 5);
+  t.is(Amounts.stringify(Amounts.divmod("EUR:5", "EUR:1").remainder), "EUR:0");
+
+  t.is(Amounts.divmod("EUR:5", "EUR:2").quotient, 2);
+  t.is(Amounts.stringify(Amounts.divmod("EUR:5", "EUR:2").remainder), "EUR:1");
+});
diff --git a/packages/taler-util/src/amounts.ts 
b/packages/taler-util/src/amounts.ts
index d4e798030..a998c8f63 100644
--- a/packages/taler-util/src/amounts.ts
+++ b/packages/taler-util/src/amounts.ts
@@ -95,6 +95,11 @@ export interface Result {
  */
 export type AmountLike = AmountString | AmountJson;
 
+export interface DivmodResult {
+  quotient: number;
+  remainder: AmountJson;
+}
+
 /**
  * Helper class for dealing with amounts.
  */
@@ -135,6 +140,29 @@ export class Amounts {
     return amt;
   }
 
+  static divmod(a1: AmountLike, a2: AmountLike): DivmodResult {
+    const am1 = Amounts.jsonifyAmount(a1);
+    const am2 = Amounts.jsonifyAmount(a2);
+    if (am1.currency != am2.currency) {
+      throw Error(`incompatible currency (${am1.currency} vs${am2.currency})`);
+    }
+
+    const x1 = BigInt(am1.value) * BigInt(amountFractionalBase) + 
BigInt(am1.fraction);
+    const x2 = BigInt(am2.value) * BigInt(amountFractionalBase) + 
BigInt(am2.fraction);
+
+    const quotient = x1 / x2;
+    const remainderScaled = x1 % x2;
+
+    return {
+      quotient: Number(quotient),
+      remainder: {
+        currency: am1.currency,
+        value: Number(remainderScaled / BigInt(amountFractionalBase)),
+        fraction: Number(remainderScaled % BigInt(amountFractionalBase))
+      }
+    }
+  }
+
   static sum(amounts: AmountLike[]): Result {
     if (amounts.length <= 0) {
       throw Error("can't sum zero amounts");
diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts 
b/packages/taler-wallet-core/src/util/coinSelection.ts
index 3b986d72b..af6dab2bb 100644
--- a/packages/taler-wallet-core/src/util/coinSelection.ts
+++ b/packages/taler-wallet-core/src/util/coinSelection.ts
@@ -689,18 +689,13 @@ export function selectWithdrawalDenominations(
   );
 
   for (const d of denoms) {
-    let count = 0;
     const cost = Amounts.add(
       DenominationRecord.getValue(d),
       d.fees.feeWithdraw,
     ).amount;
-    for (;;) {
-      if (Amounts.cmp(remaining, cost) < 0) {
-        break;
-      }
-      remaining = Amounts.sub(remaining, cost).amount;
-      count++;
-    }
+    const res = Amounts.divmod(remaining, cost);
+    const count = res.quotient;
+    remaining = Amounts.sub(remaining, Amounts.mult(cost, 
count).amount).amount;
     if (count > 0) {
       totalCoinValue = Amounts.add(
         totalCoinValue,

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