aboutsummaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-util/src/talerTypes.ts42
-rw-r--r--packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts26
-rw-r--r--packages/taler-wallet-core/src/util/coinSelection.ts32
3 files changed, 63 insertions, 37 deletions
diff --git a/packages/taler-util/src/talerTypes.ts b/packages/taler-util/src/talerTypes.ts
index 2f2576d82..37350c661 100644
--- a/packages/taler-util/src/talerTypes.ts
+++ b/packages/taler-util/src/talerTypes.ts
@@ -47,6 +47,7 @@ import {
codecForDuration,
} from "./time.js";
import { Amounts, codecForAmountString } from "./amounts.js";
+import { strcmp } from "./helpers.js";
/**
* Denomination as found in the /keys response from the exchange.
@@ -1125,6 +1126,47 @@ export interface CsDenominationPubKey {
// FIXME: finish definition
}
+export namespace DenominationPubKey {
+ export function cmp(
+ p1: DenominationPubKey,
+ p2: DenominationPubKey,
+ ): -1 | 0 | 1 {
+ if (p1.cipher < p2.cipher) {
+ return -1;
+ } else if (p1.cipher > p2.cipher) {
+ return +1;
+ }
+ if (
+ p1.cipher === DenomKeyType.LegacyRsa &&
+ p2.cipher === DenomKeyType.LegacyRsa
+ ) {
+ return strcmp(p1.rsa_public_key, p2.rsa_public_key);
+ } else if (
+ p1.cipher === DenomKeyType.Rsa &&
+ p2.cipher === DenomKeyType.Rsa
+ ) {
+ if ((p1.age_mask ?? 0) < (p2.age_mask ?? 0)) {
+ return -1;
+ } else if ((p1.age_mask ?? 0) > (p2.age_mask ?? 0)) {
+ return 1;
+ }
+ return strcmp(p1.rsa_public_key, p2.rsa_public_key);
+ } else {
+ throw Error("unsupported cipher");
+ }
+ }
+
+ export function lift(p1: DenominationPubKey | string): DenominationPubKey {
+ if (typeof p1 === "string") {
+ return {
+ cipher: DenomKeyType.LegacyRsa,
+ rsa_public_key: p1,
+ };
+ }
+ return p1;
+ }
+}
+
export const codecForDenominationPubKey = () =>
buildCodecForUnion<DenominationPubKey>()
.discriminateOn("cipher")
diff --git a/packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts b/packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts
index 9badfd501..eceb26d79 100644
--- a/packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts
@@ -19,17 +19,14 @@
*/
import {
codecForExchangeKeysJson,
- ConfirmPayResultType,
+ DenominationPubKey,
Duration,
durationFromSpec,
- PreparePayResultType,
stringifyTimestamp,
} from "@gnu-taler/taler-util";
import {
NodeHttpLib,
- PendingOperationsResponse,
readSuccessResponseJsonOrThrow,
- WalletApiOperation,
} from "@gnu-taler/taler-wallet-core";
import { makeNoFeeCoinConfig } from "../harness/denomStructures";
import {
@@ -40,7 +37,7 @@ import {
MerchantService,
setupDb,
WalletCli,
- getPayto
+ getPayto,
} from "../harness/harness.js";
import { startWithdrawViaBank, withdrawViaBank } from "../harness/helpers.js";
@@ -192,19 +189,30 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
console.log("=== KEYS RESPONSE 1 ===");
console.log("list issue date", stringifyTimestamp(keys1.list_issue_date));
- console.log("num denoms", keys1.denoms.length)
+ console.log("num denoms", keys1.denoms.length);
console.log("denoms", JSON.stringify(denomPubs1, undefined, 2));
console.log("=== KEYS RESPONSE 2 ===");
console.log("list issue date", stringifyTimestamp(keys2.list_issue_date));
- console.log("num denoms", keys2.denoms.length)
+ console.log("num denoms", keys2.denoms.length);
console.log("denoms", JSON.stringify(denomPubs2, undefined, 2));
for (const da of denomPubs1) {
- if (!dps2.has(da.denomPub)) {
+ let found = false;
+ for (const db of denomPubs2) {
+ const d1 = DenominationPubKey.lift(da.denomPub);
+ const d2 = DenominationPubKey.lift(db.denomPub);
+ if (DenominationPubKey.cmp(d1, d2) === 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
console.log("=== ERROR ===");
- console.log(`denomination with public key ${da.denomPub} is not present in new /keys response`);
+ console.log(
+ `denomination with public key ${da.denomPub} is not present in new /keys response`,
+ );
console.log(
`the new /keys response was issued ${stringifyTimestamp(
keys2.list_issue_date,
diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts
index 9a122a8fa..4f8a01d19 100644
--- a/packages/taler-wallet-core/src/util/coinSelection.ts
+++ b/packages/taler-wallet-core/src/util/coinSelection.ts
@@ -27,7 +27,9 @@ import {
AmountJson,
Amounts,
DenominationPubKey,
- DenomKeyType, Logger, strcmp
+ DenomKeyType,
+ Logger,
+ strcmp,
} from "@gnu-taler/taler-util";
const logger = new Logger("coinSelection.ts");
@@ -210,32 +212,6 @@ function tallyFees(
};
}
-function denomPubCmp(
- p1: DenominationPubKey,
- p2: DenominationPubKey,
-): -1 | 0 | 1 {
- if (p1.cipher < p2.cipher) {
- return -1;
- } else if (p1.cipher > p2.cipher) {
- return +1;
- }
- if (
- p1.cipher === DenomKeyType.LegacyRsa &&
- p2.cipher === DenomKeyType.LegacyRsa
- ) {
- return strcmp(p1.rsa_public_key, p2.rsa_public_key);
- } else if (p1.cipher === DenomKeyType.Rsa && p2.cipher === DenomKeyType.Rsa) {
- if ((p1.age_mask ?? 0) < (p2.age_mask ?? 0)) {
- return -1;
- } else if ((p1.age_mask ?? 0) > (p2.age_mask ?? 0)) {
- return 1;
- }
- return strcmp(p1.rsa_public_key, p2.rsa_public_key);
- } else {
- throw Error("unsupported cipher");
- }
-}
-
/**
* Given a list of candidate coins, select coins to spend under the merchant's
* constraints.
@@ -302,7 +278,7 @@ export function selectPayCoins(
(o1, o2) =>
-Amounts.cmp(o1.availableAmount, o2.availableAmount) ||
Amounts.cmp(o1.feeDeposit, o2.feeDeposit) ||
- denomPubCmp(o1.denomPub, o2.denomPub),
+ DenominationPubKey.cmp(o1.denomPub, o2.denomPub),
);
// FIXME: Here, we should select coins in a smarter way.