From 8624d798b799d78a4b6393493a0750027094904d Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 25 May 2023 19:11:03 +0200 Subject: wallet-core: fix issues with aborting deposits --- .../taler-wallet-core/src/operations/common.ts | 2 +- .../taler-wallet-core/src/operations/deposits.ts | 49 ++++++++++++---------- .../taler-wallet-core/src/operations/pending.ts | 5 ++- .../src/operations/transactions.ts | 20 +-------- 4 files changed, 33 insertions(+), 43 deletions(-) (limited to 'packages/taler-wallet-core/src/operations') diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index 5ad1e7112..203bf6788 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -232,7 +232,7 @@ export async function resetOperationTimeout( if (retryRecord) { // Note that we don't reset the lastError, it should still be visible // while the retry runs. - retryRecord.retryInfo = RetryInfo.increment(retryRecord.retryInfo); + retryRecord.retryInfo = RetryInfo.reset(); await tx.operationRetries.put(retryRecord); } }); diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index c3d24cbf3..6c41d76f6 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -89,6 +89,7 @@ import { import { selectPayCoinsNew } from "../util/coinSelection.js"; import { constructTransactionIdentifier, + notifyTransition, parseTransactionIdentifier, stopLongpolling, } from "./transactions.js"; @@ -158,8 +159,16 @@ export function computeDepositTransactionStatus( return { major: TransactionMajorState.Suspended, }; + case DepositOperationStatus.Aborting: + return { + major: TransactionMajorState.Aborting, + }; + case DepositOperationStatus.Aborted: + return { + major: TransactionMajorState.Aborted, + } default: - throw Error("unexpected deposit group state"); + throw Error(`unexpected deposit group state (${dg.operationStatus})`); } } @@ -379,8 +388,11 @@ async function waitForRefreshOnDepositGroup( ): Promise { const abortRefreshGroupId = depositGroup.abortRefreshGroupId; checkLogicInvariant(!!abortRefreshGroupId); - // FIXME: Emit notification on state transition! - const res = await ws.db + const transactionId = constructTransactionIdentifier({ + tag: TransactionType.Deposit, + depositGroupId: depositGroup.depositGroupId, + }); + const transitionInfo = await ws.db .mktx((x) => [x.refreshGroups, x.depositGroups]) .runReadWrite(async (tx) => { const refreshGroup = await tx.refreshGroups.get(abortRefreshGroupId); @@ -405,30 +417,17 @@ async function waitForRefreshOnDepositGroup( if (!newDg) { return; } - const oldDepositTxStatus = computeDepositTransactionStatus(newDg); + const oldTxState = computeDepositTransactionStatus(newDg); newDg.operationStatus = newOpState; - const newDepositTxStatus = computeDepositTransactionStatus(newDg); + const newTxState = computeDepositTransactionStatus(newDg); await tx.depositGroups.put(newDg); - return { oldDepositTxStatus, newDepositTxStatus }; + return { oldTxState, newTxState }; } return undefined; }); - if (res) { - const transactionId = constructTransactionIdentifier({ - tag: TransactionType.Deposit, - depositGroupId: depositGroup.depositGroupId, - }); - ws.notify({ - type: NotificationType.TransactionStateTransition, - transactionId, - oldTxState: res.oldDepositTxStatus, - newTxState: res.newDepositTxStatus, - }); - return OperationAttemptResult.pendingEmpty(); - } else { - return OperationAttemptResult.pendingEmpty(); - } + notifyTransition(ws, transactionId, transitionInfo); + return OperationAttemptResult.pendingEmpty(); } async function refundDepositGroup( @@ -436,6 +435,7 @@ async function refundDepositGroup( depositGroup: DepositGroupRecord, ): Promise { const newTxPerCoin = [...depositGroup.transactionPerCoin]; + logger.info(`status per coin: ${j2s(depositGroup.transactionPerCoin)}`); for (let i = 0; i < depositGroup.transactionPerCoin.length; i++) { const st = depositGroup.transactionPerCoin[i]; switch (st) { @@ -475,6 +475,7 @@ async function refundDepositGroup( method: "POST", body: refundReq, }); + logger.info(`coin ${i} refund HTTP status for coin: ${httpResp.status}`); let newStatus: DepositElementStatus; if (httpResp.status === 200) { // FIXME: validate response @@ -492,7 +493,7 @@ async function refundDepositGroup( let isDone = true; for (let i = 0; i < newTxPerCoin.length; i++) { if ( - newTxPerCoin[i] != DepositElementStatus.RefundFailed || + newTxPerCoin[i] != DepositElementStatus.RefundFailed && newTxPerCoin[i] != DepositElementStatus.RefundSuccess ) { isDone = false; @@ -535,6 +536,7 @@ async function refundDepositGroup( await tx.depositGroups.put(newDg); }); + return OperationAttemptResult.pendingEmpty(); } @@ -775,10 +777,13 @@ export async function processDepositGroup( } if (depositGroup.operationStatus === DepositOperationStatus.Aborting) { + logger.info("processing deposit tx in 'aborting'"); const abortRefreshGroupId = depositGroup.abortRefreshGroupId; if (!abortRefreshGroupId) { + logger.info("refunding deposit group"); return refundDepositGroup(ws, depositGroup); } + logger.info("waiting for refresh"); return waitForRefreshOnDepositGroup(ws, depositGroup); } return OperationAttemptResult.finishedEmpty(); diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index 25d58d8e6..54b12383b 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -198,7 +198,10 @@ async function gatherDepositPending( resp: PendingOperationsResponse, ): Promise { const dgs = await tx.depositGroups.indexes.byStatus.getAll( - OperationStatus.Pending, + GlobalIDB.KeyRange.bound( + OperationStatusRange.ACTIVE_START, + OperationStatusRange.ACTIVE_END, + ), ); for (const dg of dgs) { if (dg.timestampFinished) { diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 478fa5ada..74df9acfb 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -1307,7 +1307,7 @@ export async function retryTransaction( ws: InternalWalletState, transactionId: string, ): Promise { - logger.info(`retrying transaction ${transactionId}`); + logger.info(`resetting retry timeout for ${transactionId}`); const parsedTx = parseTransactionIdentifier(transactionId); @@ -1325,9 +1325,6 @@ export async function retryTransaction( }); await resetOperationTimeout(ws, taskId); stopLongpolling(ws, taskId); - await runOperationWithErrorReporting(ws, taskId, () => - processPeerPullCredit(ws, parsedTx.pursePub), - ); break; } case TransactionType.Deposit: { @@ -1337,9 +1334,6 @@ export async function retryTransaction( }); await resetOperationTimeout(ws, taskId); stopLongpolling(ws, taskId); - await runOperationWithErrorReporting(ws, taskId, () => - processDepositGroup(ws, parsedTx.depositGroupId), - ); break; } case TransactionType.Withdrawal: { @@ -1350,9 +1344,6 @@ export async function retryTransaction( }); await resetOperationTimeout(ws, taskId); stopLongpolling(ws, taskId); - await runOperationWithErrorReporting(ws, taskId, () => - processWithdrawalGroup(ws, parsedTx.withdrawalGroupId), - ); break; } case TransactionType.Payment: { @@ -1362,9 +1353,6 @@ export async function retryTransaction( }); await resetOperationTimeout(ws, taskId); stopLongpolling(ws, taskId); - await runOperationWithErrorReporting(ws, taskId, () => - processPurchasePay(ws, parsedTx.proposalId), - ); break; } case TransactionType.Tip: { @@ -1374,9 +1362,6 @@ export async function retryTransaction( }); await resetOperationTimeout(ws, taskId); stopLongpolling(ws, taskId); - await runOperationWithErrorReporting(ws, taskId, () => - processTip(ws, parsedTx.walletTipId), - ); break; } case TransactionType.Refresh: { @@ -1386,9 +1371,6 @@ export async function retryTransaction( }); await resetOperationTimeout(ws, taskId); stopLongpolling(ws, taskId); - await runOperationWithErrorReporting(ws, taskId, () => - processRefreshGroup(ws, parsedTx.refreshGroupId), - ); break; } default: -- cgit v1.2.3