diff options
author | Florian Dold <florian@dold.me> | 2023-02-20 20:14:37 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2023-02-20 20:14:46 +0100 |
commit | 3daa4dbb3fc5199fb05d58b40c0d7c9ee287595e (patch) | |
tree | bdf3bcd9af71ce9cc77a8c4dc32ff0537654e83f /packages/taler-wallet-core/src/operations/pay-peer.ts | |
parent | 7bb81a008b7148cfd3fd656f858e4cbd755531ac (diff) | |
download | wallet-core-3daa4dbb3fc5199fb05d58b40c0d7c9ee287595e.tar.xz |
wallet-core: fix retryTransaction, improve tx/op identifier parsing/construction
Diffstat (limited to 'packages/taler-wallet-core/src/operations/pay-peer.ts')
-rw-r--r-- | packages/taler-wallet-core/src/operations/pay-peer.ts | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/packages/taler-wallet-core/src/operations/pay-peer.ts b/packages/taler-wallet-core/src/operations/pay-peer.ts index ff01342f8..4f65ec7ea 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer.ts @@ -87,15 +87,17 @@ import { TalerError } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; import { makeTransactionId, + resetOperationTimeout, runOperationWithErrorReporting, spendCoins, } from "../operations/common.js"; import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http"; import { checkDbInvariant } from "../util/invariants.js"; import { + constructTaskIdentifier, OperationAttemptResult, OperationAttemptResultType, - RetryTags, + TaskIdentifiers, } from "../util/retries.js"; import { getPeerPaymentBalanceDetailsInTx } from "./balance.js"; import { updateExchangeFromUrl } from "./exchanges.js"; @@ -103,7 +105,10 @@ import { getTotalRefreshCost } from "./refresh.js"; import { getExchangeWithdrawalInfo, internalCreateWithdrawalGroup, + processWithdrawalGroup, } from "./withdraw.js"; +import { PendingTaskType } from "../pending-types.js"; +import { stopLongpolling } from "./transactions.js"; const logger = new Logger("operations/peer-to-peer.ts"); @@ -590,13 +595,14 @@ export async function initiatePeerPushPayment( }); }); - await runOperationWithErrorReporting( - ws, - RetryTags.byPeerPushPaymentInitiationPursePub(pursePair.pub), - async () => { - return await processPeerPushInitiation(ws, pursePair.pub); - }, - ); + const taskId = constructTaskIdentifier({ + tag: PendingTaskType.PeerPushInitiation, + pursePub: pursePair.pub, + }); + + await runOperationWithErrorReporting(ws, taskId, async () => { + return await processPeerPushInitiation(ws, pursePair.pub); + }); return { contractPriv: contractKeyPair.priv, @@ -951,7 +957,7 @@ export async function confirmPeerPushPayment( await updateExchangeFromUrl(ws, peerInc.exchangeBaseUrl); - const retryTag = RetryTags.forPeerPushCredit(peerInc); + const retryTag = TaskIdentifiers.forPeerPushCredit(peerInc); await runOperationWithErrorReporting(ws, retryTag, () => processPeerPushCredit(ws, req.peerPushPaymentIncomingId), @@ -1113,7 +1119,7 @@ export async function acceptIncomingPeerPullPayment( await runOperationWithErrorReporting( ws, - RetryTags.forPeerPullPaymentDebit(ppi), + TaskIdentifiers.forPeerPullPaymentDebit(ppi), async () => { return processPeerPullDebit(ws, ppi.peerPullPaymentIncomingId); }, @@ -1263,7 +1269,23 @@ export async function processPeerPullCredit( } if (pullIni.status === OperationStatus.Finished) { - logger.warn("peer pull payment initiation is already finished"); + logger.warn( + "peer pull payment initiation is already finished, retrying withdrawal", + ); + + const withdrawalGroupId = pullIni.withdrawalGroupId; + + if (withdrawalGroupId) { + const taskId = constructTaskIdentifier({ + tag: PendingTaskType.Withdraw, + withdrawalGroupId, + }); + stopLongpolling(ws, taskId); + await resetOperationTimeout(ws, taskId); + await runOperationWithErrorReporting(ws, taskId, () => + processWithdrawalGroup(ws, withdrawalGroupId), + ); + } return { type: OperationAttemptResultType.Finished, result: undefined, @@ -1514,19 +1536,19 @@ export async function initiatePeerPullPayment( // whether purse creation has failed, or does the client/ // check this asynchronously from the transaction status? - await runOperationWithErrorReporting( - ws, - RetryTags.byPeerPullPaymentInitiationPursePub(pursePair.pub), - async () => { - return processPeerPullCredit(ws, pursePair.pub); - }, - ); + const taskId = constructTaskIdentifier({ + tag: PendingTaskType.PeerPullInitiation, + pursePub: pursePair.pub, + }); + + await runOperationWithErrorReporting(ws, taskId, async () => { + return processPeerPullCredit(ws, pursePair.pub); + }); // FIXME: Why do we create this only here? // What if the previous operation didn't succeed? - - // FIXME: Use a pre-computed withdrawal group ID - // so we don't create it multiple times. + // We actually should create it once we know the + // money arrived (via long-polling). await internalCreateWithdrawalGroup(ws, { amount: instructedAmount, |