taler-typescript-core

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

commit 52ba306d750311cc1b46c97c3135bcc9b66d0fff
parent 00bdbfe58348ed4d6cb70c85c656c86b2e2cd3fe
Author: Florian Dold <dold@taler.net>
Date:   Tue, 28 Jul 2026 12:00:05 +0200

wallet: settle an expired push debit as expired, not aborted

The exchange answers the merge long-poll with "gone" only when the purse
expired, and nobody aborted in that case.

Diffstat:
Mpackages/taler-harness/src/integrationtests/test-peer-push.ts | 5++++-
Mpackages/taler-wallet-core/src/pay-peer-push-debit.ts | 9++++++---
2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-peer-push.ts b/packages/taler-harness/src/integrationtests/test-peer-push.ts @@ -525,9 +525,12 @@ export async function runPeerPushTest(t: GlobalTestState) { t.logStep("P2P start wait for expiration"); await Promise.all([ + // Nobody aborted, the purse simply expired. wallet1.call(WalletApiOperation.TestingWaitTransactionState, { transactionId: tx.transactionId, - txState: stFinalUnsuccessful, + txState: { + major: TransactionMajorState.Expired, + }, }), wallet2.call(WalletApiOperation.TestingWaitTransactionState, { transactionId: prepare2.transactionId, diff --git a/packages/taler-wallet-core/src/pay-peer-push-debit.ts b/packages/taler-wallet-core/src/pay-peer-push-debit.ts @@ -1000,7 +1000,10 @@ async function processPeerPushDebitReady( } } case HttpStatusCode.Gone: - logger.info(`purse ${pursePub} is gone, aborting peer-push-debit`); + // The exchange answers the merge long-poll with "gone" only when the + // purse expired. Nobody aborted here, so the transaction is expired + // and not aborted, but the coins still have to come back to us. + logger.info(`purse ${pursePub} expired, refreshing peer-push-debit`); await wex.runWalletDbTx(async (tx) => { const [rec, h] = await ctx.getRecordHandle(tx); if (!rec) { @@ -1031,8 +1034,8 @@ async function processPeerPushDebitReady( rec.abortRefreshGroupId = refresh.refreshGroupId; } - rec.status = PeerPushDebitStatus.Aborted; - await h.update(rec, "ready-aborted"); + rec.status = PeerPushDebitStatus.Expired; + await h.update(rec, "ready-expired"); }); return TaskRunResult.backoff(); case HttpStatusCode.NotFound: