commit 7595228344db6e6a9ce934c1cb1a068153ced89f
parent 1397e87627bce6ecd7a2739670eb2f5eab3b99dc
Author: Antoine A <>
Date: Thu, 10 Apr 2025 20:20:14 +0200
harness: clean and improve peer tests
Diffstat:
8 files changed, 683 insertions(+), 895 deletions(-)
diff --git a/packages/taler-harness/src/integrationtests/test-peer-pull-large.ts b/packages/taler-harness/src/integrationtests/test-peer-pull-large.ts
@@ -14,33 +14,22 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-/**
- * Imports.
- */
import {
AbsoluteTime,
- AmountString,
Duration,
- j2s,
- NotificationType,
- TalerCorebankApiClient,
TransactionMajorState,
TransactionMinorState,
TransactionType,
- WalletNotification,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { CoinConfig } from "../harness/denomStructures.js";
import {
- createSimpleTestkudosEnvironmentV2,
+ createSimpleTestkudosEnvironmentV3,
createWalletDaemonWithClient,
withdrawViaBankV3,
} from "../harness/environments.js";
import {
- BankServiceHandle,
- ExchangeService,
GlobalTestState,
- WalletClient,
} from "../harness/harness.js";
const coinCommon = {
@@ -63,6 +52,13 @@ const coinConfigList: CoinConfig[] = [
},
];
+const purse_expiration = AbsoluteTime.toProtocolTimestamp(
+ AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ Duration.fromSpec({ days: 2 }),
+ ),
+);
+
/**
* Test peer pull payments with a large number of coins.
*
@@ -71,135 +67,77 @@ const coinConfigList: CoinConfig[] = [
*/
export async function runPeerPullLargeTest(t: GlobalTestState) {
// Set up test environment
-
- const { bank, exchange } = await createSimpleTestkudosEnvironmentV2(
- t,
- coinConfigList,
- );
-
- let allW1Notifications: WalletNotification[] = [];
- let allW2Notifications: WalletNotification[] = [];
-
- const w1 = await createWalletDaemonWithClient(t, {
- name: "w1",
- persistent: true,
- handleNotification(wn) {
- allW1Notifications.push(wn);
- },
- });
- const w2 = await createWalletDaemonWithClient(t, {
- name: "w2",
- persistent: true,
- handleNotification(wn) {
- allW2Notifications.push(wn);
- },
- });
+ const [
+ { walletClient: wallet1, bankClient, exchange },
+ { walletClient: wallet2 },
+ ] = await Promise.all([
+ createSimpleTestkudosEnvironmentV3(t, coinConfigList),
+ createWalletDaemonWithClient(t, {
+ name: "w2"
+ })
+ ]);
// Withdraw digital cash into the wallet.
- const wallet1 = w1.walletClient;
- const wallet2 = w2.walletClient;
-
- await checkNormalPeerPull(t, bank, exchange, wallet1, wallet2);
-}
-
-async function checkNormalPeerPull(
- t: GlobalTestState,
- bank: BankServiceHandle,
- exchange: ExchangeService,
- wallet1: WalletClient,
- wallet2: WalletClient,
-): Promise<void> {
- t.logStep("starting withdrawal");
- const bankClient = new TalerCorebankApiClient(bank.corebankApiBaseUrl);
const withdrawRes = await withdrawViaBankV3(t, {
walletClient: wallet2,
bankClient,
exchange,
amount: "TESTKUDOS:500",
});
-
await withdrawRes.withdrawalFinishedCond;
- t.logStep("finished withdrawal");
-
- const purseExpiration = AbsoluteTime.toProtocolTimestamp(
- AbsoluteTime.addDuration(
- AbsoluteTime.now(),
- Duration.fromSpec({ days: 2 }),
- ),
- );
-
- const resp = await wallet1.client.call(
+ const initiate = await wallet1.call(
WalletApiOperation.InitiatePeerPullCredit,
{
exchangeBaseUrl: exchange.baseUrl,
partialContractTerms: {
summary: "Hello World",
- amount: "TESTKUDOS:200" as AmountString,
- purse_expiration: purseExpiration,
+ amount: "TESTKUDOS:200",
+ purse_expiration,
},
},
);
- const peerPullCreditReadyCond = wallet1.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === resp.transactionId &&
- x.newTxState.major === TransactionMajorState.Pending &&
- x.newTxState.minor === TransactionMinorState.Ready,
- );
-
- await peerPullCreditReadyCond;
+ await wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready
+ },
+ });
- const creditTx = await wallet1.call(WalletApiOperation.GetTransactionById, {
- transactionId: resp.transactionId,
+ const tx = await wallet1.call(WalletApiOperation.GetTransactionById, {
+ transactionId: initiate.transactionId,
});
- t.assertDeepEqual(creditTx.type, TransactionType.PeerPullCredit);
- t.assertTrue(!!creditTx.talerUri);
+ t.assertDeepEqual(tx.type, TransactionType.PeerPullCredit);
+ t.assertTrue(!!tx.talerUri);
- const checkResp = await wallet2.client.call(
+ const prepare = await wallet2.client.call(
WalletApiOperation.PreparePeerPullDebit,
{
- talerUri: creditTx.talerUri,
+ talerUri: tx.talerUri,
},
);
- console.log(`checkResp: ${j2s(checkResp)}`);
-
- const peerPullCreditDoneCond = wallet1.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === resp.transactionId &&
- x.newTxState.major === TransactionMajorState.Done,
- );
-
- const peerPullDebitDoneCond = wallet2.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === checkResp.transactionId &&
- x.newTxState.major === TransactionMajorState.Done,
- );
-
await wallet2.client.call(WalletApiOperation.ConfirmPeerPullDebit, {
- transactionId: checkResp.transactionId,
+ transactionId: prepare.transactionId,
});
- await peerPullCreditDoneCond;
- await peerPullDebitDoneCond;
-
- const txn1 = await wallet1.client.call(
- WalletApiOperation.GetTransactions,
- {},
- );
-
- const txn2 = await wallet2.client.call(
- WalletApiOperation.GetTransactions,
- {},
- );
-
- console.log(`txn1: ${j2s(txn1)}`);
- console.log(`txn2: ${j2s(txn2)}`);
+ await Promise.all([
+ wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ }),
+ wallet2.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: prepare.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ })
+ ]);
}
runPeerPullLargeTest.suites = ["wallet", "slow"];
diff --git a/packages/taler-harness/src/integrationtests/test-peer-pull.ts b/packages/taler-harness/src/integrationtests/test-peer-pull.ts
@@ -0,0 +1,214 @@
+/*
+ This file is part of GNU Taler
+ (C) 2020 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/>
+ */
+
+import {
+ AbsoluteTime,
+ AmountString,
+ Duration,
+ TransactionMajorState,
+ TransactionMinorState,
+ TransactionType,
+} from "@gnu-taler/taler-util";
+import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import {
+ createSimpleTestkudosEnvironmentV3,
+ createWalletDaemonWithClient,
+ withdrawViaBankV3,
+} from "../harness/environments.js";
+import {
+ GlobalTestState,
+} from "../harness/harness.js";
+
+const purse_expiration = AbsoluteTime.toProtocolTimestamp(
+ AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ Duration.fromSpec({ days: 2 }),
+ ),
+);
+
+/**
+ * Run a test for basic peer-pull payments.
+ */
+export async function runPeerPullTest(t: GlobalTestState) {
+ const [
+ { walletClient: wallet1, bankClient, exchange },
+ { walletClient: wallet2 },
+ ] = await Promise.all([
+ createSimpleTestkudosEnvironmentV3(t),
+ createWalletDaemonWithClient(t, {
+ name: "w2"
+ })
+ ]);
+
+ // Withdraw digital cash into the wallet.
+ const withdrawRes = await withdrawViaBankV3(t, {
+ walletClient: wallet2,
+ bankClient,
+ exchange,
+ amount: "TESTKUDOS:20",
+ });
+ await withdrawRes.withdrawalFinishedCond;
+
+ t.logStep("Check debit amount logic");
+ {
+ await wallet1.call(WalletApiOperation.AddExchange, {
+ exchangeBaseUrl: exchange.baseUrl
+ });
+ const [
+ checkfive,
+ checkzero
+ ] = await Promise.all([
+ wallet1.client.call(
+ WalletApiOperation.CheckPeerPullCredit,
+ {
+ amount: "TESTKUDOS:5" as AmountString,
+ exchangeBaseUrl: exchange.baseUrl,
+ },
+ ),
+ wallet1.client.call(
+ WalletApiOperation.CheckPeerPullCredit,
+ {
+ amount: "TESTKUDOS:0" as AmountString,
+ exchangeBaseUrl: exchange.baseUrl,
+ },
+ ),
+ ]);
+
+ t.assertDeepEqual(checkfive.amountRaw, "TESTKUDOS:5");
+
+ t.assertDeepEqual(checkzero.amountRaw, "TESTKUDOS:0");
+ t.assertDeepEqual(checkzero.amountEffective, "TESTKUDOS:0");
+ t.assertDeepEqual(checkzero.numCoins, 0);
+ }
+
+ t.logStep("P2P pull confirm");
+ {
+ const initiate = await wallet1.client.call(
+ WalletApiOperation.InitiatePeerPullCredit,
+ {
+ exchangeBaseUrl: exchange.baseUrl,
+ partialContractTerms: {
+ summary: "Hello World",
+ amount: "TESTKUDOS:5",
+ purse_expiration,
+ },
+ },
+ );
+
+ await wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready
+ },
+ });
+
+ const tx = await wallet1.call(WalletApiOperation.GetTransactionById, {
+ transactionId: initiate.transactionId,
+ });
+
+ t.assertDeepEqual(tx.type, TransactionType.PeerPullCredit);
+ t.assertTrue(!!tx.talerUri);
+
+ const prepare = await wallet2.client.call(
+ WalletApiOperation.PreparePeerPullDebit,
+ {
+ talerUri: tx.talerUri,
+ },
+ );
+
+ await wallet2.client.call(WalletApiOperation.ConfirmPeerPullDebit, {
+ transactionId: prepare.transactionId,
+ });
+
+ await Promise.all([
+ wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ }),
+ wallet2.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: prepare.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ })
+ ]);
+ }
+
+ t.logStep("P2P pull abort");
+ {
+ const initiate = await wallet1.client.call(
+ WalletApiOperation.InitiatePeerPullCredit,
+ {
+ exchangeBaseUrl: exchange.baseUrl,
+ partialContractTerms: {
+ summary: "Hello World",
+ amount: "TESTKUDOS:5" as AmountString,
+ purse_expiration,
+ },
+ },
+ );
+
+ await wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready,
+ },
+ });
+
+ const tx = await wallet1.call(WalletApiOperation.GetTransactionById, {
+ transactionId: initiate.transactionId,
+ });
+
+ t.assertDeepEqual(tx.type, TransactionType.PeerPullCredit);
+ t.assertTrue(!!tx.talerUri);
+
+ const prepare = await wallet2.client.call(
+ WalletApiOperation.PreparePeerPullDebit,
+ {
+ talerUri: tx.talerUri,
+ },
+ );
+
+ await wallet1.call(WalletApiOperation.AbortTransaction, {
+ transactionId: initiate.transactionId,
+ });
+
+ await wallet2.client.call(WalletApiOperation.ConfirmPeerPullDebit, {
+ transactionId: prepare.transactionId,
+ });
+
+ await Promise.all([
+ wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Aborted,
+ },
+ }),
+ wallet2.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: prepare.transactionId,
+ txState: {
+ major: TransactionMajorState.Aborted,
+ },
+ })
+ ]);
+ }
+}
+
+runPeerPullTest.suites = ["wallet"];
diff --git a/packages/taler-harness/src/integrationtests/test-peer-push-abort.ts b/packages/taler-harness/src/integrationtests/test-peer-push-abort.ts
@@ -1,92 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2020 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 {
- AbsoluteTime,
- Duration,
- TransactionMajorState,
- TransactionMinorState,
-} from "@gnu-taler/taler-util";
-import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import {
- createSimpleTestkudosEnvironmentV3,
- withdrawViaBankV3,
-} from "../harness/environments.js";
-import { GlobalTestState } from "../harness/harness.js";
-
-/**
- * Run a test for aborting peer-push payments.
- */
-export async function runPeerPushAbortTest(t: GlobalTestState) {
- const { bank, bankClient, exchange, walletClient } =
- await createSimpleTestkudosEnvironmentV3(t);
-
- const wres = await withdrawViaBankV3(t, {
- walletClient,
- bankClient,
- exchange,
- amount: "TESTKUDOS:20",
- });
-
- await wres.withdrawalFinishedCond;
-
- const purse_expiration = AbsoluteTime.toProtocolTimestamp(
- AbsoluteTime.addDuration(
- AbsoluteTime.now(),
- Duration.fromSpec({ days: 2 }),
- ),
- );
-
- const pdi = await walletClient.call(
- WalletApiOperation.InitiatePeerPushDebit,
- {
- partialContractTerms: {
- amount: "TESTKUDOS:7",
- summary: "Hi!",
- purse_expiration,
- },
- },
- );
-
- await walletClient.call(WalletApiOperation.TestingWaitTransactionState, {
- transactionId: pdi.transactionId,
- txState: {
- major: TransactionMajorState.Pending,
- minor: TransactionMinorState.Ready,
- },
- });
-
- await walletClient.call(WalletApiOperation.AbortTransaction, {
- transactionId: pdi.transactionId,
- });
-
- await walletClient.call(WalletApiOperation.TestingWaitTransactionState, {
- transactionId: pdi.transactionId,
- txState: {
- major: TransactionMajorState.Aborted,
- },
- });
-
- await walletClient.call(WalletApiOperation.TestingWaitRefreshesFinal, {});
-
- const bal = await walletClient.call(WalletApiOperation.GetBalances, {});
- t.assertAmountEquals(bal.balances[0].available, "TESTKUDOS:18.88");
-}
-
-runPeerPushAbortTest.suites = ["wallet"];
diff --git a/packages/taler-harness/src/integrationtests/test-peer-push-large.ts b/packages/taler-harness/src/integrationtests/test-peer-push-large.ts
@@ -1,6 +1,6 @@
/*
This file is part of GNU Taler
- (C) 2020 Taler Systems S.A.
+ (C) 2020-2025 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
@@ -14,25 +14,17 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-/**
- * Imports.
- */
import {
AbsoluteTime,
- AmountString,
Duration,
- NotificationType,
- TalerCorebankApiClient,
TransactionMajorState,
TransactionMinorState,
TransactionType,
- WalletNotification,
- j2s,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { CoinConfig } from "../harness/denomStructures.js";
import {
- createSimpleTestkudosEnvironmentV2,
+ createSimpleTestkudosEnvironmentV3,
createWalletDaemonWithClient,
withdrawViaBankV3,
} from "../harness/environments.js";
@@ -58,126 +50,104 @@ const coinConfigList: CoinConfig[] = [
},
];
+const purse_expiration = AbsoluteTime.toProtocolTimestamp(
+ AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ Duration.fromSpec({ days: 2 }),
+ ),
+);
+
/**
- * Run a test for a multi-batch peer push payment.
+ * Test peer push payments with a large number of coins.
+ *
+ * Since we use an artificallly large number of coins, this
+ * test is a bit slower than other tests.
*/
export async function runPeerPushLargeTest(t: GlobalTestState) {
- const { bank, exchange } = await createSimpleTestkudosEnvironmentV2(
- t,
- coinConfigList,
- );
-
- let allW1Notifications: WalletNotification[] = [];
- let allW2Notifications: WalletNotification[] = [];
-
- const w1 = await createWalletDaemonWithClient(t, {
- name: "w1",
- handleNotification(wn) {
- allW1Notifications.push(wn);
- },
- });
- const w2 = await createWalletDaemonWithClient(t, {
- name: "w2",
- handleNotification(wn) {
- allW2Notifications.push(wn);
- },
- });
+ // Set up test environment
+ const [
+ { walletClient: wallet1, bankClient, exchange },
+ { walletClient: wallet2 },
+ ] = await Promise.all([
+ createSimpleTestkudosEnvironmentV3(t, coinConfigList),
+ createWalletDaemonWithClient(t, {
+ name: "w2"
+ })
+ ]);
// Withdraw digital cash into the wallet.
-
- const bankClient = new TalerCorebankApiClient(bank.baseUrl);
-
const withdrawRes = await withdrawViaBankV3(t, {
- walletClient: w1.walletClient,
+ walletClient: wallet1,
bankClient,
exchange,
amount: "TESTKUDOS:300",
});
-
await withdrawRes.withdrawalFinishedCond;
- const purse_expiration = AbsoluteTime.toProtocolTimestamp(
- AbsoluteTime.addDuration(
- AbsoluteTime.now(),
- Duration.fromSpec({ days: 2 }),
- ),
- );
-
- const checkResp0 = await w1.walletClient.call(
+ const check = await wallet1.call(
WalletApiOperation.CheckPeerPushDebit,
{
- amount: "TESTKUDOS:200" as AmountString,
+ amount: "TESTKUDOS:200",
},
);
+ t.assertAmountEquals(check.amountEffective, "TESTKUDOS:200");
- t.assertAmountEquals(checkResp0.amountEffective, "TESTKUDOS:200");
-
- const resp = await w1.walletClient.call(
+ const initiate = await wallet1.call(
WalletApiOperation.InitiatePeerPushDebit,
{
partialContractTerms: {
summary: "Hello World 🥺",
- amount: "TESTKUDOS:200" as AmountString,
+ amount: "TESTKUDOS:200",
purse_expiration,
},
},
);
- console.log(resp);
-
- const peerPushReadyCond = w1.walletClient.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.newTxState.major === TransactionMajorState.Pending &&
- x.newTxState.minor === TransactionMinorState.Ready &&
- x.transactionId === resp.transactionId,
- );
-
- await peerPushReadyCond;
+ await wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready
+ },
+ });
- const txDetails = await w1.walletClient.call(
+ const tx = await wallet1.call(
WalletApiOperation.GetTransactionById,
{
- transactionId: resp.transactionId,
+ transactionId: initiate.transactionId,
},
);
- t.assertDeepEqual(txDetails.type, TransactionType.PeerPushDebit);
- t.assertTrue(!!txDetails.talerUri);
+ t.assertDeepEqual(tx.type, TransactionType.PeerPushDebit);
+ t.assertTrue(!!tx.talerUri);
- const checkResp = await w2.walletClient.call(
+ const prepare = await wallet2.call(
WalletApiOperation.PreparePeerPushCredit,
{
- talerUri: txDetails.talerUri,
+ talerUri: tx.talerUri,
},
);
- console.log(checkResp);
-
- const acceptResp = await w2.walletClient.call(
+ await wallet2.call(
WalletApiOperation.ConfirmPeerPushCredit,
{
- transactionId: checkResp.transactionId,
+ transactionId: prepare.transactionId,
},
);
- console.log(acceptResp);
-
- await w2.walletClient.call(
- WalletApiOperation.TestingWaitTransactionsFinal,
- {},
- );
-
- const txn1 = await w1.walletClient.call(
- WalletApiOperation.GetTransactions,
- {},
- );
- const txn2 = await w2.walletClient.call(
- WalletApiOperation.GetTransactions,
- {},
- );
-
- console.log(`txn1: ${j2s(txn1)}`);
- console.log(`txn2: ${j2s(txn2)}`);
+ await Promise.all([
+ wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ }),
+ wallet2.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: prepare.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ })
+ ]);
}
-runPeerPushLargeTest.suites = ["wallet"];
+runPeerPushLargeTest.suites = ["wallet", "slow"];
diff --git a/packages/taler-harness/src/integrationtests/test-peer-push.ts b/packages/taler-harness/src/integrationtests/test-peer-push.ts
@@ -0,0 +1,358 @@
+/*
+ This file is part of GNU Taler
+ (C) 2020-2025 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/>
+ */
+
+import {
+ AbsoluteTime,
+ Duration,
+ TalerErrorCode,
+ TransactionMajorState,
+ TransactionMinorState,
+ TransactionType,
+} from "@gnu-taler/taler-util";
+import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import {
+ createSimpleTestkudosEnvironmentV3,
+ createWalletDaemonWithClient,
+ withdrawViaBankV3,
+} from "../harness/environments.js";
+import { GlobalTestState } from "../harness/harness.js";
+
+const purse_expiration = AbsoluteTime.toProtocolTimestamp(
+ AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ Duration.fromSpec({ days: 2 }),
+ ),
+);
+
+/**
+ * Run a test for basic peer-push payments.
+ */
+export async function runPeerPushTest(t: GlobalTestState) {
+ const [
+ { walletClient: wallet1, bankClient, exchange },
+ { walletClient: wallet2 },
+ ] = await Promise.all([
+ createSimpleTestkudosEnvironmentV3(t),
+ createWalletDaemonWithClient(t, {
+ name: "w2"
+ })
+ ]);
+
+ // Withdraw digital cash into the wallet.
+ const withdrawRes = await withdrawViaBankV3(t, {
+ walletClient: wallet1,
+ bankClient,
+ exchange,
+ amount: "TESTKUDOS:20",
+ });
+ await withdrawRes.withdrawalFinishedCond;
+
+ t.logStep("Check debit amount logic");
+ {
+ const [
+ maxpeer,
+ checkzero,
+ checkfive
+ ] = await Promise.all([
+ wallet1.call(
+ WalletApiOperation.GetMaxPeerPushDebitAmount,
+ {
+ currency: "TESTKUDOS"
+ }
+ ),
+ wallet1.call(
+ WalletApiOperation.CheckPeerPushDebit,
+ {
+ amount: "TESTKUDOS:0"
+ }
+ ),
+ wallet1.call(
+ WalletApiOperation.CheckPeerPushDebit,
+ {
+ amount: "TESTKUDOS:5"
+ }
+ )
+ ]);
+
+ t.assertDeepEqual(maxpeer.exchangeBaseUrl, exchange.baseUrl);
+ t.assertAmountEquals(maxpeer.rawAmount, "TESTKUDOS:19.1");
+ t.assertAmountEquals(maxpeer.effectiveAmount, "TESTKUDOS:19.53");
+
+ t.assertAmountEquals(checkzero.amountRaw, "TESTKUDOS:0");
+ t.assertAmountEquals(checkzero.amountEffective, "TESTKUDOS:0");
+
+ t.assertAmountEquals(checkfive.amountRaw, "TESTKUDOS:5");
+ t.assertAmountEquals(checkfive.amountEffective, "TESTKUDOS:5.49");
+ }
+
+ t.logStep("P2P push confirm");
+ {
+ const initiate = await wallet1.call(
+ WalletApiOperation.InitiatePeerPushDebit,
+ {
+ partialContractTerms: {
+ summary: "Hello World 🥺",
+ amount: "TESTKUDOS:5",
+ purse_expiration,
+ },
+ },
+ );
+
+ await wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready
+ },
+ });
+
+ // Check balance update
+ {
+ const bal = await wallet1.call(WalletApiOperation.GetBalances, {});
+ t.assertAmountEquals(bal.balances[0].pendingOutgoing, "TESTKUDOS:5.49");
+ }
+
+ const tx = await wallet1.call(
+ WalletApiOperation.GetTransactionById,
+ { transactionId: initiate.transactionId }
+ );
+ t.assertDeepEqual(tx.type, TransactionType.PeerPushDebit);
+ t.assertTrue(!!tx.talerUri);
+
+ const prepare = await wallet2.call(
+ WalletApiOperation.PreparePeerPushCredit,
+ { talerUri: tx.talerUri }
+ );
+ {
+ const idempotent = await wallet2.call(
+ WalletApiOperation.PreparePeerPushCredit,
+ { talerUri: tx.talerUri }
+ );
+ t.assertTrue(prepare.transactionId === idempotent.transactionId);
+ }
+
+ await wallet2.call(
+ WalletApiOperation.ConfirmPeerPushCredit,
+ { transactionId: prepare.transactionId }
+ );
+ await wallet2.call(
+ WalletApiOperation.ConfirmPeerPushCredit,
+ { transactionId: prepare.transactionId }
+ );
+
+ await Promise.all([
+ wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ }),
+ wallet2.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: prepare.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ })
+ ]);
+
+ const bal = await wallet1.call(WalletApiOperation.GetBalances, {});
+ t.assertAmountEquals(bal.balances[0].available, "TESTKUDOS:14.04");
+
+
+ // Check wallet1 scan after completion
+ const reprepare1 = await wallet1.call(
+ WalletApiOperation.PreparePeerPushCredit,
+ { talerUri: tx.talerUri }
+ ); // FIXME this should fails
+ await wallet1.call(
+ WalletApiOperation.ConfirmPeerPushCredit,
+ { transactionId: reprepare1.transactionId }
+ );
+ // FIXME this should fail
+
+
+ // Check wallet2 rescan after completion
+ const reprepare2 = await wallet2.call(
+ WalletApiOperation.PreparePeerPushCredit,
+ { talerUri: tx.talerUri }
+ );
+ t.assertTrue(prepare.transactionId === reprepare2.transactionId)
+ }
+
+ t.logStep("P2P push insufficient balance");
+ {
+ const ex1 = await t.assertThrowsTalerErrorAsync(
+ wallet1.call(WalletApiOperation.InitiatePeerPushDebit, {
+ partialContractTerms: {
+ summary: "(this will fail)",
+ amount: "TESTKUDOS:15",
+ purse_expiration,
+ },
+ })
+ );
+ t.assertTrue(ex1.errorDetail.code === TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION);
+ // FIXME propagate the error correctly
+ // t.assertTrue(ex1.errorDetail.code === TalerErrorCode.WALLET_PEER_PUSH_PAYMENT_INSUFFICIENT_BALANCE);
+ }
+
+ t.logStep("P2P push abort");
+ {
+ const initiate = await wallet1.call(
+ WalletApiOperation.InitiatePeerPushDebit,
+ {
+ partialContractTerms: {
+ amount: "TESTKUDOS:7",
+ summary: "Hi!",
+ purse_expiration,
+ },
+ },
+ );
+
+ await wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready,
+ },
+ });
+
+ const tx = await wallet1.call(
+ WalletApiOperation.GetTransactionById,
+ {
+ transactionId: initiate.transactionId,
+ },
+ );
+ t.assertDeepEqual(tx.type, TransactionType.PeerPushDebit);
+ t.assertTrue(!!tx.talerUri);
+
+ const prepare = await wallet2.client.call(
+ WalletApiOperation.PreparePeerPushCredit,
+ {
+ talerUri: tx.talerUri,
+ },
+ );
+
+ await wallet1.call(WalletApiOperation.AbortTransaction, {
+ transactionId: initiate.transactionId,
+ });
+
+ await wallet2.client.call(WalletApiOperation.ConfirmPeerPushCredit, {
+ transactionId: prepare.transactionId,
+ });
+
+ await Promise.all([
+ wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Aborted,
+ },
+ }),
+ // FIXME check wallet2 is also aborted
+ /*wallet2.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: prepare.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ })*/
+ ]);
+
+ const bal = await wallet1.call(WalletApiOperation.GetBalances, {});
+ t.assertAmountEquals(bal.balances[0].available, "TESTKUDOS:13.49");
+ }
+
+ t.logStep("P2P push expire");
+ {
+ const initiate = await wallet1.call(
+ WalletApiOperation.InitiatePeerPushDebit,
+ {
+ partialContractTerms: {
+ summary: "second tx, will expire",
+ amount: "TESTKUDOS:5",
+ purse_expiration,
+ },
+ },
+ );
+
+ await wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Pending,
+ minor: TransactionMinorState.Ready,
+ },
+ });
+
+ const tx = await wallet1.call(
+ WalletApiOperation.GetTransactionById,
+ {
+ transactionId: initiate.transactionId,
+ },
+ );
+ t.assertDeepEqual(tx.type, TransactionType.PeerPushDebit);
+ t.assertTrue(!!tx.talerUri);
+
+ const prepare = await wallet2.call(WalletApiOperation.PreparePeerPushCredit, {
+ talerUri: tx.talerUri,
+ });
+
+ const timetravelOffsetMs = Duration.toMilliseconds(
+ Duration.fromSpec({ days: 5 }),
+ );
+
+ console.log("stopping exchange to apply time-travel");
+
+ await exchange.stop();
+ exchange.setTimetravel(timetravelOffsetMs);
+ await exchange.start();
+ await exchange.pingUntilAvailable();
+
+ console.log("running expire");
+ await exchange.runExpireOnce();
+ console.log("done running expire");
+
+ console.log("purse should now be expired");
+
+ await Promise.all([
+ wallet1.call(WalletApiOperation.TestingSetTimetravel, {
+ offsetMs: timetravelOffsetMs,
+ }),
+ wallet2.call(WalletApiOperation.TestingSetTimetravel, {
+ offsetMs: timetravelOffsetMs,
+ }),
+ ]);
+
+ await wallet2.client.call(WalletApiOperation.ConfirmPeerPushCredit, {
+ transactionId: prepare.transactionId,
+ });
+
+ await Promise.all([
+ wallet1.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: initiate.transactionId,
+ txState: {
+ major: TransactionMajorState.Aborted,
+ },
+ }),
+ // FIXME check wallet2 is also aborted
+ /*wallet2.call(WalletApiOperation.TestingWaitTransactionState, {
+ transactionId: prepare.transactionId,
+ txState: {
+ major: TransactionMajorState.Done,
+ },
+ })*/
+ ]);
+ }
+}
+
+runPeerPushTest.suites = ["wallet"];
diff --git a/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts b/packages/taler-harness/src/integrationtests/test-peer-to-peer-pull.ts
@@ -1,311 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2020 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 {
- AbsoluteTime,
- AmountString,
- Duration,
- j2s,
- NotificationType,
- TalerCorebankApiClient,
- TransactionMajorState,
- TransactionMinorState,
- TransactionType,
- WalletNotification,
-} from "@gnu-taler/taler-util";
-import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import {
- createSimpleTestkudosEnvironmentV3,
- createWalletDaemonWithClient,
- withdrawViaBankV3,
-} from "../harness/environments.js";
-import {
- ExchangeService,
- GlobalTestState,
- WalletClient,
-} from "../harness/harness.js";
-
-/**
- * Run test for basic, bank-integrated withdrawal and payment.
- */
-export async function runPeerToPeerPullTest(t: GlobalTestState) {
- // Set up test environment
-
- const { bankClient, exchange } = await createSimpleTestkudosEnvironmentV3(t);
-
- let allW1Notifications: WalletNotification[] = [];
- let allW2Notifications: WalletNotification[] = [];
-
- const w1 = await createWalletDaemonWithClient(t, {
- name: "w1",
- persistent: true,
- handleNotification(wn) {
- allW1Notifications.push(wn);
- },
- });
- const w2 = await createWalletDaemonWithClient(t, {
- name: "w2",
- persistent: true,
- handleNotification(wn) {
- allW2Notifications.push(wn);
- },
- });
-
- // Withdraw digital cash into the wallet.
- const wallet1 = w1.walletClient;
- const wallet2 = w2.walletClient;
-
- await checkNormalPeerPull(t, bankClient, exchange, wallet1, wallet2);
-
- console.log(`w1 notifications: ${j2s(allW1Notifications)}`);
-
- // Check that we don't have an excessive number of notifications.
- t.assertTrue(allW1Notifications.length <= 60);
-
- await checkAbortedPeerPull(t, bankClient, exchange, wallet1, wallet2);
-}
-
-async function checkNormalPeerPull(
- t: GlobalTestState,
- bankClient: TalerCorebankApiClient,
- exchange: ExchangeService,
- wallet1: WalletClient,
- wallet2: WalletClient,
-): Promise<void> {
- const withdrawRes = await withdrawViaBankV3(t, {
- walletClient: wallet2,
- bankClient,
- exchange,
- amount: "TESTKUDOS:20",
- });
-
- await withdrawRes.withdrawalFinishedCond;
-
- const purseExpiration = AbsoluteTime.toProtocolTimestamp(
- AbsoluteTime.addDuration(
- AbsoluteTime.now(),
- Duration.fromSpec({ days: 2 }),
- ),
- );
-
- await wallet1.call(WalletApiOperation.AddExchange, {
- exchangeBaseUrl: exchange.baseUrl,
- });
-
- const checkPullCreditResp1 = await wallet1.client.call(
- WalletApiOperation.CheckPeerPullCredit,
- {
- amount: "TESTKUDOS:5" as AmountString,
- exchangeBaseUrl: exchange.baseUrl,
- },
- );
-
- t.assertDeepEqual(checkPullCreditResp1.amountRaw, "TESTKUDOS:5");
-
- const checkPullCreditResp2 = await wallet1.client.call(
- WalletApiOperation.CheckPeerPullCredit,
- {
- amount: "TESTKUDOS:0" as AmountString,
- exchangeBaseUrl: exchange.baseUrl,
- },
- );
-
- t.assertDeepEqual(checkPullCreditResp2.amountRaw, "TESTKUDOS:0");
- t.assertDeepEqual(checkPullCreditResp2.amountEffective, "TESTKUDOS:0");
- t.assertDeepEqual(checkPullCreditResp2.numCoins, 0);
-
- const resp = await wallet1.client.call(
- WalletApiOperation.InitiatePeerPullCredit,
- {
- exchangeBaseUrl: exchange.baseUrl,
- partialContractTerms: {
- summary: "Hello World",
- amount: "TESTKUDOS:5" as AmountString,
- purse_expiration: purseExpiration,
- },
- },
- );
-
- const peerPullCreditReadyCond = wallet1.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === resp.transactionId &&
- x.newTxState.major === TransactionMajorState.Pending &&
- x.newTxState.minor === TransactionMinorState.Ready,
- );
-
- await peerPullCreditReadyCond;
-
- const creditTx = await wallet1.call(WalletApiOperation.GetTransactionById, {
- transactionId: resp.transactionId,
- });
-
- t.assertDeepEqual(creditTx.type, TransactionType.PeerPullCredit);
- t.assertTrue(!!creditTx.talerUri);
-
- const checkResp = await wallet2.client.call(
- WalletApiOperation.PreparePeerPullDebit,
- {
- talerUri: creditTx.talerUri,
- },
- );
-
- console.log(`checkResp: ${j2s(checkResp)}`);
-
- const peerPullCreditDoneCond = wallet1.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === resp.transactionId &&
- x.newTxState.major === TransactionMajorState.Done,
- );
-
- const peerPullDebitDoneCond = wallet2.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === checkResp.transactionId &&
- x.newTxState.major === TransactionMajorState.Done,
- );
-
- await wallet2.client.call(WalletApiOperation.ConfirmPeerPullDebit, {
- transactionId: checkResp.transactionId,
- });
-
- await peerPullCreditDoneCond;
- await peerPullDebitDoneCond;
-
- const txn1 = await wallet1.client.call(
- WalletApiOperation.GetTransactions,
- {},
- );
-
- const txn2 = await wallet2.client.call(
- WalletApiOperation.GetTransactions,
- {},
- );
-
- console.log(`txn1: ${j2s(txn1)}`);
- console.log(`txn2: ${j2s(txn2)}`);
-}
-
-async function checkAbortedPeerPull(
- t: GlobalTestState,
- bankClient: TalerCorebankApiClient,
- exchange: ExchangeService,
- wallet1: WalletClient,
- wallet2: WalletClient,
-): Promise<void> {
- const withdrawRes = await withdrawViaBankV3(t, {
- walletClient: wallet2,
- bankClient,
- exchange,
- amount: "TESTKUDOS:20",
- });
-
- await withdrawRes.withdrawalFinishedCond;
-
- const purseExpiration = AbsoluteTime.toProtocolTimestamp(
- AbsoluteTime.addDuration(
- AbsoluteTime.now(),
- Duration.fromSpec({ days: 2 }),
- ),
- );
-
- const resp = await wallet1.client.call(
- WalletApiOperation.InitiatePeerPullCredit,
- {
- exchangeBaseUrl: exchange.baseUrl,
- partialContractTerms: {
- summary: "Hello World",
- amount: "TESTKUDOS:5" as AmountString,
- purse_expiration: purseExpiration,
- },
- },
- );
-
- const peerPullCreditReadyCond = wallet1.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === resp.transactionId &&
- x.newTxState.major === TransactionMajorState.Pending &&
- x.newTxState.minor === TransactionMinorState.Ready,
- );
-
- await peerPullCreditReadyCond;
-
- const creditTx = await wallet1.call(WalletApiOperation.GetTransactionById, {
- transactionId: resp.transactionId,
- });
-
- t.assertDeepEqual(creditTx.type, TransactionType.PeerPullCredit);
- t.assertTrue(!!creditTx.talerUri);
-
- const checkResp = await wallet2.client.call(
- WalletApiOperation.PreparePeerPullDebit,
- {
- talerUri: creditTx.talerUri,
- },
- );
-
- console.log(`checkResp: ${j2s(checkResp)}`);
-
- const peerPullCreditAbortedCond = wallet1.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === resp.transactionId &&
- x.newTxState.major === TransactionMajorState.Aborted,
- );
-
- const peerPullDebitAbortedCond = wallet2.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.transactionId === checkResp.transactionId &&
- x.newTxState.major === TransactionMajorState.Aborted,
- );
-
- await wallet1.call(WalletApiOperation.AbortTransaction, {
- transactionId: resp.transactionId,
- });
-
- await wallet2.client.call(WalletApiOperation.ConfirmPeerPullDebit, {
- transactionId: checkResp.transactionId,
- });
-
- console.log(`waiting for ${resp.transactionId} to go to state aborted`);
- console.log("checkpoint: before-aborted-wait");
- await peerPullCreditAbortedCond;
- console.log("checkpoint: after-credit-aborted-wait");
- await peerPullDebitAbortedCond;
- console.log("checkpoint: after-debit-aborted-wait");
- console.log("checkpoint: after-aborted-wait");
-
- const txn1 = await wallet1.client.call(
- WalletApiOperation.GetTransactions,
- {},
- );
-
- const txn2 = await wallet2.client.call(
- WalletApiOperation.GetTransactions,
- {},
- );
-
- console.log(`txn1: ${j2s(txn1)}`);
- console.log(`txn2: ${j2s(txn2)}`);
-}
-
-runPeerToPeerPullTest.suites = ["wallet"];
diff --git a/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts b/packages/taler-harness/src/integrationtests/test-peer-to-peer-push.ts
@@ -1,287 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2020-2025 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 {
- AbsoluteTime,
- AmountString,
- Duration,
- NotificationType,
- TransactionMajorState,
- TransactionMinorState,
- TransactionType,
- WalletNotification,
- j2s,
-} from "@gnu-taler/taler-util";
-import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import {
- createSimpleTestkudosEnvironmentV3,
- createWalletDaemonWithClient,
- withdrawViaBankV3,
-} from "../harness/environments.js";
-import { GlobalTestState } from "../harness/harness.js";
-
-/**
- * Run a test for basic peer-push payments.
- */
-export async function runPeerToPeerPushTest(t: GlobalTestState) {
- const { bankClient, exchange } = await createSimpleTestkudosEnvironmentV3(t);
-
- let allW1Notifications: WalletNotification[] = [];
- let allW2Notifications: WalletNotification[] = [];
-
- const w1 = await createWalletDaemonWithClient(t, {
- name: "w1",
- handleNotification(wn) {
- allW1Notifications.push(wn);
- },
- });
- const w2 = await createWalletDaemonWithClient(t, {
- name: "w2",
- handleNotification(wn) {
- allW2Notifications.push(wn);
- },
- });
-
- // Withdraw digital cash into the wallet.
-
- const withdrawRes = await withdrawViaBankV3(t, {
- walletClient: w1.walletClient,
- bankClient,
- exchange,
- amount: "TESTKUDOS:20",
- });
-
- await withdrawRes.withdrawalFinishedCond;
-
- {
- const maxResp1 = await w1.walletClient.call(
- WalletApiOperation.GetMaxPeerPushDebitAmount,
- {
- currency: "TESTKUDOS",
- },
- );
-
- t.assertDeepEqual(maxResp1.exchangeBaseUrl, exchange.baseUrl);
- t.assertAmountEquals(maxResp1.rawAmount, "TESTKUDOS:19.1");
- t.assertAmountEquals(maxResp1.effectiveAmount, "TESTKUDOS:19.53");
- }
-
- const purse_expiration = AbsoluteTime.toProtocolTimestamp(
- AbsoluteTime.addDuration(
- AbsoluteTime.now(),
- Duration.fromSpec({ days: 2 }),
- ),
- );
-
- {
- const checkRespSmall = await w1.walletClient.call(
- WalletApiOperation.CheckPeerPushDebit,
- {
- amount: "TESTKUDOS:0" as AmountString,
- },
- );
- }
-
- const checkResp0 = await w1.walletClient.call(
- WalletApiOperation.CheckPeerPushDebit,
- {
- amount: "TESTKUDOS:5" as AmountString,
- },
- );
-
- t.assertAmountEquals(checkResp0.amountRaw, "TESTKUDOS:5");
- t.assertAmountEquals(checkResp0.amountEffective, "TESTKUDOS:5.49");
-
- {
- const resp = await w1.walletClient.call(
- WalletApiOperation.InitiatePeerPushDebit,
- {
- partialContractTerms: {
- summary: "Hello World 😁😇",
- amount: "TESTKUDOS:5" as AmountString,
- purse_expiration,
- },
- },
- );
-
- console.log(resp);
- }
-
- {
- const bal = await w1.walletClient.call(WalletApiOperation.GetBalances, {});
- t.assertAmountEquals(bal.balances[0].pendingOutgoing, "TESTKUDOS:5.49");
- }
-
- await w1.walletClient.call(WalletApiOperation.TestingWaitRefreshesFinal, {});
-
- const resp = await w1.walletClient.call(
- WalletApiOperation.InitiatePeerPushDebit,
- {
- partialContractTerms: {
- summary: "Hello World 🥺",
- amount: "TESTKUDOS:5" as AmountString,
- purse_expiration,
- },
- },
- );
-
- console.log(resp);
-
- const peerPushReadyCond = w1.walletClient.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.newTxState.major === TransactionMajorState.Pending &&
- x.newTxState.minor === TransactionMinorState.Ready &&
- x.transactionId === resp.transactionId,
- );
-
- await peerPushReadyCond;
-
- const txDetails = await w1.walletClient.call(
- WalletApiOperation.GetTransactionById,
- {
- transactionId: resp.transactionId,
- },
- );
- t.assertDeepEqual(txDetails.type, TransactionType.PeerPushDebit);
- t.assertTrue(!!txDetails.talerUri);
-
- const prepareResp = await w2.walletClient.call(
- WalletApiOperation.PreparePeerPushCredit,
- {
- talerUri: txDetails.talerUri,
- },
- );
-
- console.log(prepareResp);
-
- const acceptResp = await w2.walletClient.call(
- WalletApiOperation.ConfirmPeerPushCredit,
- {
- transactionId: prepareResp.transactionId,
- },
- );
-
- console.log(acceptResp);
-
- const txn1 = await w1.walletClient.call(
- WalletApiOperation.GetTransactions,
- {},
- );
- const txn2 = await w2.walletClient.call(
- WalletApiOperation.GetTransactions,
- {},
- );
-
- console.log(`txn1: ${j2s(txn1)}`);
- console.log(`txn2: ${j2s(txn2)}`);
-
- // We expect insufficient balance here!
- const ex1 = await t.assertThrowsTalerErrorAsync(
- w1.walletClient.call(WalletApiOperation.InitiatePeerPushDebit, {
- partialContractTerms: {
- summary: "(this will fail)",
- amount: "TESTKUDOS:15" as AmountString,
- purse_expiration,
- },
- })
- );
-
- console.log("got expected exception detail", j2s(ex1.errorDetail));
-
- const initiateResp2 = await w1.walletClient.call(
- WalletApiOperation.InitiatePeerPushDebit,
- {
- partialContractTerms: {
- summary: "second tx, will expire",
- amount: "TESTKUDOS:5" as AmountString,
- purse_expiration,
- },
- },
- );
-
- const peerPushReadyCond2 = w1.walletClient.waitForNotificationCond(
- (x) =>
- x.type === NotificationType.TransactionStateTransition &&
- x.newTxState.major === TransactionMajorState.Pending &&
- x.newTxState.minor === TransactionMinorState.Ready &&
- x.transactionId === initiateResp2.transactionId,
- );
-
- await peerPushReadyCond2;
-
- const txDetails3 = await w1.walletClient.call(
- WalletApiOperation.GetTransactionById,
- {
- transactionId: initiateResp2.transactionId,
- },
- );
- t.assertDeepEqual(txDetails3.type, TransactionType.PeerPushDebit);
- t.assertTrue(!!txDetails3.talerUri);
-
- await w2.walletClient.call(WalletApiOperation.PreparePeerPushCredit, {
- talerUri: txDetails3.talerUri,
- });
-
- const timetravelOffsetMs = Duration.toMilliseconds(
- Duration.fromSpec({ days: 5 }),
- );
-
- console.log("stopping exchange to apply time-travel");
-
- await exchange.stop();
- exchange.setTimetravel(timetravelOffsetMs);
- await exchange.start();
- await exchange.pingUntilAvailable();
-
- console.log("running expire");
- await exchange.runExpireOnce();
- console.log("done running expire");
-
- console.log("purse should now be expired");
-
- await w1.walletClient.call(WalletApiOperation.TestingSetTimetravel, {
- offsetMs: timetravelOffsetMs,
- });
-
- await w2.walletClient.call(WalletApiOperation.TestingSetTimetravel, {
- offsetMs: timetravelOffsetMs,
- });
-
- await w1.walletClient.call(
- WalletApiOperation.TestingWaitTransactionsFinal,
- {},
- );
-
- await w2.walletClient.call(
- WalletApiOperation.TestingWaitTransactionsFinal,
- {},
- );
-
- const txDetails2 = await w1.walletClient.call(
- WalletApiOperation.GetTransactionById,
- {
- transactionId: initiateResp2.transactionId,
- },
- );
-
- console.log(`tx details 2: ${j2s(txDetails2)}`);
-}
-
-runPeerToPeerPushTest.suites = ["wallet"];
diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts
@@ -100,12 +100,11 @@ import { runPaymentTransientTest } from "./test-payment-transient.js";
import { runPaymentZeroTest } from "./test-payment-zero.js";
import { runPaymentTest } from "./test-payment.js";
import { runPaywallFlowTest } from "./test-paywall-flow.js";
+import { runPeerPullTest } from "./test-peer-pull.js";
+import { runPeerPushTest } from "./test-peer-push.js";
import { runPeerPullLargeTest } from "./test-peer-pull-large.js";
-import { runPeerPushAbortTest } from "./test-peer-push-abort.js";
import { runPeerPushLargeTest } from "./test-peer-push-large.js";
import { runPeerRepairTest } from "./test-peer-repair.js";
-import { runPeerToPeerPullTest } from "./test-peer-to-peer-pull.js";
-import { runPeerToPeerPushTest } from "./test-peer-to-peer-push.js";
import { runRefundAutoTest } from "./test-refund-auto.js";
import { runRefundGoneTest } from "./test-refund-gone.js";
import { runRefundIncrementalTest } from "./test-refund-incremental.js";
@@ -214,8 +213,8 @@ const allTests: TestMainFunction[] = [
runMultiExchangeTest,
runWalletBalanceTest,
runPaywallFlowTest,
- runPeerToPeerPullTest,
- runPeerToPeerPushTest,
+ runPeerPullTest,
+ runPeerPushTest,
runRefundAutoTest,
runRefundGoneTest,
runRefundIncrementalTest,
@@ -300,7 +299,6 @@ const allTests: TestMainFunction[] = [
runKycDepositAggregateImplicitAuthTest,
runKycAmpTimeoutTest,
runKycAmpFailureTest,
- runPeerPushAbortTest,
runWithdrawalCashacceptorTest,
runWithdrawalConflictTest,
runBankWopTest,