aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations/pay-peer.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/operations/pay-peer.ts')
-rw-r--r--packages/taler-wallet-core/src/operations/pay-peer.ts64
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,