gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: add bench3 for zipf and rando


From: gnunet
Subject: [taler-wallet-core] branch master updated: add bench3 for zipf and random merchant selection (by id)
Date: Mon, 09 May 2022 14:28:23 +0200

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

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

The following commit(s) were added to refs/heads/master by this push:
     new 935a1196 add bench3 for zipf and random merchant selection (by id)
935a1196 is described below

commit 935a119621a9ff7a79c410d6cc1bf0c9daa89216
Author: Marco Boss <bossm8@bfh.ch>
AuthorDate: Mon May 9 14:28:12 2022 +0200

    add bench3 for zipf and random merchant selection (by id)
---
 packages/taler-wallet-cli/src/bench2.ts            |   2 +-
 packages/taler-wallet-cli/src/bench3.ts            | 204 +++++++++++++++++++++
 .../src/benchMerchantIDGenerator.ts                |  83 +++++++++
 packages/taler-wallet-cli/src/index.ts             |  16 ++
 4 files changed, 304 insertions(+), 1 deletion(-)

diff --git a/packages/taler-wallet-cli/src/bench2.ts 
b/packages/taler-wallet-cli/src/bench2.ts
index 2ee53329..a51b98c1 100644
--- a/packages/taler-wallet-cli/src/bench2.ts
+++ b/packages/taler-wallet-cli/src/bench2.ts
@@ -44,7 +44,7 @@ import {
  * set up its own services.
  */
 export async function runBench2(configJson: any): Promise<void> {
-  const logger = new Logger("Bench1");
+  const logger = new Logger("Bench2");
 
   // Validate the configuration file for this benchmark.
   const benchConf = codecForBench2Config().decode(configJson);
diff --git a/packages/taler-wallet-cli/src/bench3.ts 
b/packages/taler-wallet-cli/src/bench3.ts
new file mode 100644
index 00000000..1d3c86cd
--- /dev/null
+++ b/packages/taler-wallet-cli/src/bench3.ts
@@ -0,0 +1,204 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Imports.
+ */
+import {
+  buildCodecForObject,
+  codecForNumber,
+  codecForString,
+  codecOptional,
+  j2s,
+  Logger,
+} from "@gnu-taler/taler-util";
+import {
+  getDefaultNodeWallet2,
+  NodeHttpLib,
+  WalletApiOperation,
+  Wallet,
+  AccessStats,
+} from "@gnu-taler/taler-wallet-core";
+import benchMerchantIDGenerator from "./benchMerchantIDGenerator.js";
+
+/**
+ * Entry point for the benchmark.
+ *
+ * The benchmark runs against an existing Taler deployment and does not
+ * set up its own services.
+ */
+export async function runBench3(configJson: any): Promise<void> {
+  const logger = new Logger("Bench3");
+
+  // Validate the configuration file for this benchmark.
+  const b3conf = codecForBench3Config().decode(configJson);
+
+  if (!b3conf.paytoTemplate.includes("${id")) {
+    throw new Error("Payto template url must contain '${id}' placeholder");
+  }
+
+  const myHttpLib = new NodeHttpLib();
+  myHttpLib.setThrottling(false);
+
+  const numIter = b3conf.iterations ?? 1;
+  const numDeposits = b3conf.deposits ?? 5;
+  const restartWallet = b3conf.restartAfter ?? 20;
+
+  const withdrawAmount = (numDeposits + 1) * 10;
+
+  const IDGenerator = benchMerchantIDGenerator(b3conf.randomAlg, 
b3conf.numMerchants ?? 100);
+
+  logger.info(
+    `Starting Benchmark iterations=${numIter} deposits=${numDeposits} with 
${b3conf.randomAlg} merchant selection`,
+  );
+
+  const trustExchange = !!process.env["TALER_WALLET_INSECURE_TRUST_EXCHANGE"];
+  if (trustExchange) {
+    logger.info("trusting exchange (not validating signatures)");
+  } else {
+    logger.info("not trusting exchange (validating signatures)");
+  }
+
+  let wallet = {} as Wallet;
+  let getDbStats: () => AccessStats;
+
+  for (let i = 0; i < numIter; i++) {
+    // Create a new wallet in each iteration
+    // otherwise the TPS go down
+    // my assumption is that the in-memory db file gets too large
+    if (i % restartWallet == 0) {
+      if (Object.keys(wallet).length !== 0) {
+        wallet.stop();
+        console.log("wallet DB stats", j2s(getDbStats!()));
+      }
+
+      const res = await getDefaultNodeWallet2({
+        // No persistent DB storage.
+        persistentStoragePath: undefined,
+        httpLib: myHttpLib,
+      });
+      wallet = res.wallet;
+      getDbStats = res.getDbStats;
+      if (trustExchange) {
+        wallet.setInsecureTrustExchange();
+      }
+      wallet.setBatchWithdrawal(true);
+      await wallet.client.call(WalletApiOperation.InitWallet, {});
+    }
+
+    logger.trace(`Starting withdrawal amount=${withdrawAmount}`);
+    let start = Date.now();
+
+    await wallet.client.call(WalletApiOperation.WithdrawFakebank, {
+      amount: b3conf.currency + ":" + withdrawAmount,
+      bank: b3conf.bank,
+      exchange: b3conf.exchange,
+    });
+
+    await wallet.runTaskLoop({
+      stopWhenDone: true,
+    });
+
+    logger.info(
+      `Finished withdrawal amount=${withdrawAmount} time=${Date.now() - 
start}`,
+    );
+
+    for (let i = 0; i < numDeposits; i++) {
+      logger.trace(`Starting deposit amount=10`);
+      start = Date.now();
+
+      let merchID = IDGenerator.getRandomMerchantID();
+      let payto = b3conf.paytoTemplate.replace("${id}", merchID.toString());
+
+      await wallet.client.call(WalletApiOperation.CreateDepositGroup, {
+        amount: b3conf.currency + ":10",
+        depositPaytoUri: payto,
+      });
+
+      await wallet.runTaskLoop({
+        stopWhenDone: true,
+      });
+
+      logger.info(`Finished deposit amount=10 time=${Date.now() - start}`);
+    }
+  }
+
+  wallet.stop();
+  console.log("wallet DB stats", j2s(getDbStats!()));
+}
+
+/**
+ * Format of the configuration file passed to the benchmark
+ */
+interface Bench3Config {
+  /**
+   * Base URL of the bank.
+   */
+  bank: string;
+
+  /**
+   * Payto url template for deposits, must contain '${id}' for replacements.
+   */
+  paytoTemplate: string;
+
+  /**
+   * Base URL of the exchange.
+   */
+  exchange: string;
+
+  /**
+   * How many withdraw/deposit iterations should be made?
+   * Defaults to 1.
+   */
+  iterations?: number;
+
+  currency: string;
+
+  deposits?: number;
+
+  /**
+   * How any iterations run until the wallet db gets purged
+   * Defaults to 20.
+   */
+  restartAfter?: number;
+
+  /**
+   * Number of merchants to select from randomly
+   */
+  numMerchants?: number;
+
+  /**
+   * Which random generator to use.
+   * Possible values: 'zipf', 'rand'
+   */
+  randomAlg: string;
+}
+
+/**
+ * Schema validation codec for Bench1Config.
+ */
+const codecForBench3Config = () =>
+  buildCodecForObject<Bench3Config>()
+    .property("bank", codecForString())
+    .property("paytoTemplate", codecForString())
+    .property("numMerchants", codecOptional(codecForNumber()))
+    .property("randomAlg", codecForString())
+    .property("exchange", codecForString())
+    .property("iterations", codecOptional(codecForNumber()))
+    .property("deposits", codecOptional(codecForNumber()))
+    .property("currency", codecForString())
+    .property("restartAfter", codecOptional(codecForNumber()))
+    .build("Bench1Config");
diff --git a/packages/taler-wallet-cli/src/benchMerchantIDGenerator.ts 
b/packages/taler-wallet-cli/src/benchMerchantIDGenerator.ts
new file mode 100644
index 00000000..b83c12bb
--- /dev/null
+++ b/packages/taler-wallet-cli/src/benchMerchantIDGenerator.ts
@@ -0,0 +1,83 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ 
+ @author: Boss Marco
+ */
+
+const getRandomInt = function(max: number) {
+  return Math.floor(Math.random() * max);
+}
+
+abstract class BenchMerchantIDGenerator {
+  abstract getRandomMerchantID(): number
+}
+
+class ZipfGenerator extends BenchMerchantIDGenerator {
+
+  weights: number[];
+  total_weight: number;
+
+  constructor(numMerchants: number) {
+    super();
+    this.weights = new Array<number>(numMerchants);
+    for (var i = 0; i < this.weights.length; i++) {
+      /* we use integers (floor), make sure we have big enough values 
+       * by multiplying with
+       * numMerchants again */
+      this.weights[i] = Math.floor((numMerchants/(i+1)) * numMerchants);
+    }
+    this.total_weight = this.weights.reduce((p, n) => p + n);
+  }
+
+  getRandomMerchantID(): number {
+    let random = getRandomInt(this.total_weight);
+    let current = 0;
+
+    for (var i = 0; i < this.weights.length; i++) {
+      current += this.weights[i];
+      if (random <= current) {
+          return i+1;
+      }
+    }
+
+    /* should never come here */
+    return getRandomInt(this.weights.length);
+  }
+}
+
+class RandomGenerator extends BenchMerchantIDGenerator {
+
+  max: number
+
+  constructor(numMerchants: number) {
+    super();
+    this.max = numMerchants
+  }
+
+  getRandomMerchantID() {
+    return getRandomInt(this.max);
+  }
+}
+
+export default function(type: string, maxID: number): BenchMerchantIDGenerator 
{
+  switch (type) {
+    case "zipf":
+      return new ZipfGenerator(maxID);
+    case "rand":
+      return new RandomGenerator(maxID);
+    default:
+      throw new Error("Valid types are 'zipf' and 'rand'");
+  }
+}
diff --git a/packages/taler-wallet-cli/src/index.ts 
b/packages/taler-wallet-cli/src/index.ts
index 5ba6e4bf..43bed3cc 100644
--- a/packages/taler-wallet-cli/src/index.ts
+++ b/packages/taler-wallet-cli/src/index.ts
@@ -65,6 +65,7 @@ import { runBench1 } from "./bench1.js";
 import { runEnv1 } from "./env1.js";
 import { GlobalTestState, runTestWithState } from "./harness/harness.js";
 import { runBench2 } from "./bench2.js";
+import { runBench3 } from "./bench3.js";
 import {
   TalerCryptoInterface,
   TalerCryptoInterfaceR,
@@ -693,6 +694,21 @@ advancedCli
     await runBench2(config);
   });
 
+advancedCli
+  .subcommand("bench3", "bench3", {
+    help: "Run the 'bench3' benchmark",
+  })
+  .requiredOption("configJson", ["--config-json"], clk.STRING)
+  .action(async (args) => {
+    let config: any;
+    try {
+      config = JSON.parse(args.bench3.configJson);
+    } catch (e) {
+      console.log("Could not parse config JSON");
+    }
+    await runBench3(config);
+  });
+
 advancedCli
   .subcommand("env1", "env1", {
     help: "Run a test environment for bench1",

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