taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit d397eb0b2035f20d086f6e420bf0591e4cbb982e
parent 9750e03a74d9a9c86bc7bbacd0d9a8458c3ae2e7
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Tue, 13 Jan 2026 17:35:01 -0300

trying to reproduce deposit problem

Diffstat:
Apackages/taler-harness/src/integrationtests/test-deposit-twice.ts | 226+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2++
2 files changed, 228 insertions(+), 0 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-deposit-twice.ts b/packages/taler-harness/src/integrationtests/test-deposit-twice.ts @@ -0,0 +1,226 @@ +/* + This file is part of GNU Taler + (C) 2024 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, + j2s, + TransactionMajorState, + TransactionMinorState, + TransactionPeerPushDebit, +} from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { CoinConfig } from "../harness/denomStructures.js"; +import { + createSimpleTestkudosEnvironmentV3, + createWalletDaemonWithClient, + withdrawViaBankV3, +} from "../harness/environments.js"; +import { GlobalTestState } from "../harness/harness.js"; + +const coinCommon = { + cipher: "RSA" as const, + durationLegal: "3 years", + durationSpend: "2 years", + durationWithdraw: "7 days", + feeDeposit: "TESTKUDOS:0", + feeRefresh: "TESTKUDOS:0", + feeRefund: "TESTKUDOS:0", + feeWithdraw: "TESTKUDOS:0", + rsaKeySize: 1024, +}; + +const topsValues = [ + "TESTKUDOS:0.0025", + "TESTKUDOS:0.005", + "TESTKUDOS:0.01", + "TESTKUDOS:0.02", + "TESTKUDOS:0.04", + "TESTKUDOS:0.08", + "TESTKUDOS:0.16", + "TESTKUDOS:0.32", + "TESTKUDOS:0.64", + "TESTKUDOS:1.28", + "TESTKUDOS:2.56", + "TESTKUDOS:5.12", + "TESTKUDOS:10.24", + "TESTKUDOS:20.48", + "TESTKUDOS:40.96", + "TESTKUDOS:81.92", + "TESTKUDOS:163.84", + "TESTKUDOS:327.68", + "TESTKUDOS:655.36", +]; + +const coinConfigList: CoinConfig[] = topsValues.map( + (value, idx): CoinConfig => ({ + ...coinCommon, + name: `n${idx}`, + value, + }), +); + +/** + * Test deposit with a large number of coins. + * + * In particular, this checks that the wallet properly + * splits deposits into batches with <=64 coins per batch. + * + * Since we use an artificially large number of coins, this + * test is a bit slower than other tests. + */ +export async function runDepositTwiceTest(t: GlobalTestState) { + // Set up test environment + const { + walletClient: aliceWallet, + bankClient, + exchange, + } = await createSimpleTestkudosEnvironmentV3(t, coinConfigList); + + const { walletClient: bobWallet } = await createWalletDaemonWithClient(t, { + name: "booWallet", + }); + + // I sent 50.- to device A and 5.-- to device B from differen bank accounts. + const aliceWithdrawRes = await withdrawViaBankV3(t, { + walletClient: aliceWallet, + bankClient, + exchange, + amount: "TESTKUDOS:50", + }); + const bobWithdrawRes = await withdrawViaBankV3(t, { + walletClient: bobWallet, + bankClient, + exchange, + amount: "TESTKUDOS:5", + }); + + await Promise.all([ + aliceWithdrawRes.withdrawalFinishedCond, + bobWithdrawRes.withdrawalFinishedCond, + ]); + + // A is validated by postal letter and B by phone number. + // I made some transactions between the two devices (and no other). + // I did send back 5.- from device B to my bank account (the 0.01 for the additional verification is no where but the 5.-- arrived in the bank account). + const bobDepositResp = await bobWallet.call( + WalletApiOperation.CreateDepositGroup, + { + amount: "TESTKUDOS:5", + depositPaytoUri: bobWithdrawRes.accountPaytoUri, + }, + ); + + await bobWallet.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: bobDepositResp.transactionId, + txState: { + major: TransactionMajorState.Finalizing, + minor: TransactionMinorState.Track, + }, + }); + + { + const aliceBalance = await aliceWallet.call( + WalletApiOperation.GetBalances, + {}, + ); + const bobBalance = await bobWallet.call(WalletApiOperation.GetBalances, {}); + console.log(`BALANCES : ${j2s({ aliceBalance, bobBalance })}`); + } + + const tomorrow = AbsoluteTime.toProtocolTimestamp( + AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ days: 1 }), + ), + ); + + // I did send an other 10.- from A to B. + const initiate = await aliceWallet.call( + WalletApiOperation.InitiatePeerPushDebit, + { + partialContractTerms: { + summary: "sending 10 to bob", + amount: "TESTKUDOS:10", + purse_expiration: tomorrow, + }, + }, + ); + + await aliceWallet.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: initiate.transactionId, + txState: { + major: TransactionMajorState.Pending, + minor: TransactionMinorState.Ready, + }, + }); + + const aliceSending10Transaction = (await aliceWallet.call( + WalletApiOperation.GetTransactionById, + { + transactionId: initiate.transactionId, + }, + )) as TransactionPeerPushDebit; + + const bobAcceptingTransaction = await bobWallet.call( + WalletApiOperation.PreparePeerPushCredit, + { + talerUri: aliceSending10Transaction.talerUri!, + }, + ); + + await bobWallet.call(WalletApiOperation.ConfirmPeerPushCredit, { + transactionId: bobAcceptingTransaction.transactionId, + }); + + await bobWallet.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: bobAcceptingTransaction.transactionId, + txState: { + major: TransactionMajorState.Done, + }, + }); + + { + const aliceBalance = await aliceWallet.call( + WalletApiOperation.GetBalances, + {}, + ); + const bobBalance = await bobWallet.call(WalletApiOperation.GetBalances, {}); + console.log(`BALANCES : ${j2s({ aliceBalance, bobBalance })}`); + } + + // I tried to do a deposite to the the same bank account from B again and get the error message + const maxDepositResp = await bobWallet.call( + WalletApiOperation.GetMaxDepositAmount, + { + currency: "TESTKUDOS", + depositPaytoUri: bobWithdrawRes.accountPaytoUri, + }, + ); + + console.log(`DEPOSIT : ${j2s(maxDepositResp)}`); + + { + const aliceBalance = await aliceWallet.call( + WalletApiOperation.GetBalances, + {}, + ); + const bobBalance = await bobWallet.call(WalletApiOperation.GetBalances, {}); + console.log(`BALNACES : ${j2s({ aliceBalance, bobBalance })}`); + } +} + +runDepositTwiceTest.suites = ["wallet"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -51,6 +51,7 @@ import { runDenomLostTest } from "./test-denom-lost.js"; import { runDenomUnofferedTest } from "./test-denom-unoffered.js"; import { runDepositFaultTest } from "./test-deposit-fault.js"; import { runDepositLargeTest } from "./test-deposit-large.js"; +import { runDepositTwiceTest } from "./test-deposit-twice.js"; import { runDepositMergeTest } from "./test-deposit-merge.js"; import { runDepositTooLargeTest } from "./test-deposit-too-large.js"; import { runDepositTest } from "./test-deposit.js"; @@ -396,6 +397,7 @@ const allTests: TestMainFunction[] = [ runWalletExchangeMigrationExistingTest, runKycFormCompressionTest, runDepositLargeTest, + runDepositTwiceTest, runDepositTooLargeTest, runMerchantAcctselTest, runLibeufinConversionTest,