taler-typescript-core

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

commit bf50fc933b8a5a610d5b432a80d1ecd7034852f9
parent 924021844669875d25ea73352ced9d43ef3b16a8
Author: Florian Dold <florian@dold.me>
Date:   Fri, 17 Jul 2026 18:21:57 +0200

wallet: be more consistent with state transition on Gone, make tests less timing sensitive

Diffstat:
Mpackages/taler-harness/src/integrationtests/test-peer-pull.ts | 21++++++++++++---------
Mpackages/taler-wallet-core/src/pay-peer-pull-debit.ts | 39+++++++++++++++------------------------
2 files changed, 27 insertions(+), 33 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-peer-pull.ts b/packages/taler-harness/src/integrationtests/test-peer-pull.ts @@ -36,6 +36,15 @@ const purse_expiration = AbsoluteTime.toProtocolTimestamp( AbsoluteTime.addDuration(AbsoluteTime.now(), Duration.fromSpec({ days: 2 })), ); +const stFailedOrExpired = [ + { + major: TransactionMajorState.Failed, + }, + { + major: TransactionMajorState.Expired, + }, +]; + /** * Run a test for basic peer-pull payments. */ @@ -205,9 +214,7 @@ export async function runPeerPullTest(t: GlobalTestState) { }), wallet3.call(WalletApiOperation.TestingWaitTransactionState, { transactionId: prepare3.transactionId, - txState: { - major: TransactionMajorState.Failed, - }, + txState: stFailedOrExpired, timeout: { seconds: 10 }, }), wallet4.call(WalletApiOperation.TestingWaitTransactionState, { @@ -309,18 +316,14 @@ export async function runPeerPullTest(t: GlobalTestState) { }), wallet3.call(WalletApiOperation.TestingWaitTransactionState, { transactionId: prepare3.transactionId, - txState: { - major: TransactionMajorState.Failed, - }, + txState: stFailedOrExpired, timeout: { seconds: 10 }, }), ]), Promise.all([ wallet2.call(WalletApiOperation.TestingWaitTransactionState, { transactionId: prepare2.transactionId, - txState: { - major: TransactionMajorState.Failed, - }, + txState: stFailedOrExpired, timeout: { seconds: 10 }, }), wallet3.call(WalletApiOperation.TestingWaitTransactionState, { diff --git a/packages/taler-wallet-core/src/pay-peer-pull-debit.ts b/packages/taler-wallet-core/src/pay-peer-pull-debit.ts @@ -61,7 +61,6 @@ import { encodeCrock, getRandomBytes, j2s, - makeTalerErrorDetail, } from "@gnu-taler/taler-util"; import { PreviousPayCoins, selectPeerCoins } from "./coinSelection.js"; import { @@ -77,11 +76,10 @@ import { import { PeerPullDebitRecordStatus, RefreshOperationStatus, + WalletPeerPullDebit, timestampPreciseFromDb, timestampPreciseToDb, - WalletPeerPullDebit, } from "./db-common.js"; -import { WalletIndexedDbTransaction } from "./db-indexeddb.js"; import { getExchangeScopeInfo, getScopeForAllExchanges } from "./exchanges.js"; import { getTotalPeerPaymentCost, @@ -217,6 +215,18 @@ export class PeerPullDebitTransactionContext implements TransactionContext { }); } + async expireTransaction(fromSt: PeerPullDebitRecordStatus): Promise<void> { + const { wex } = this; + await wex.runLegacyWalletDbTx(async (tx) => { + const [rec, h] = await this.getRecordHandle(tx); + if (rec?.status != fromSt) { + return; + } + rec.status = PeerPullDebitRecordStatus.Expired; + await h.update(rec); + }); + } + async userDeleteTransaction(): Promise<void> { await this.wex.runLegacyWalletDbTx(async (tx) => { await this.deleteTransactionInTx(tx); @@ -457,20 +467,7 @@ async function processPeerPullDebitDialogProposed( break; case HttpStatusCode.Gone: // Exchange says that purse doesn't exist anymore => expired! - await ctx.wex.runLegacyWalletDbTx(async (tx) => { - const [rec, h] = await ctx.getRecordHandle(tx); - if (!rec) { - return; - } - switch (rec.status) { - case PeerPullDebitRecordStatus.DialogProposed: - rec.status = PeerPullDebitRecordStatus.Expired; - break; - default: - return; - } - await h.update(rec); - }); + await ctx.expireTransaction(PeerPullDebitRecordStatus.DialogProposed); return TaskRunResult.finished(); case HttpStatusCode.NotFound: await ctx.failTransaction(pullIni.status, resp.detail); @@ -611,13 +608,7 @@ async function processPeerPullDebitPendingDeposit( case "ok": continue; case HttpStatusCode.Gone: { - await ctx.failTransaction( - peerPullInc.status, - makeTalerErrorDetail( - TalerErrorCode.WALLET_PEER_PULL_DEBIT_PURSE_GONE, - {}, - ), - ); + await ctx.expireTransaction(peerPullInc.status); return TaskRunResult.finished(); } case HttpStatusCode.Conflict: