From 7d6bcd42ea9efced6200cf94924aa38bed2dbb02 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 21 Sep 2022 20:46:45 +0200 Subject: wallet-core: use numeric status field to allow range queries --- .../src/operations/backup/export.ts | 4 +- .../src/operations/backup/import.ts | 11 +-- .../src/operations/peer-to-peer.ts | 6 +- .../taler-wallet-core/src/operations/pending.ts | 9 ++- .../taler-wallet-core/src/operations/recoup.ts | 4 +- .../src/operations/transactions.ts | 2 - .../taler-wallet-core/src/operations/withdraw.ts | 89 ++++++++++------------ 7 files changed, 62 insertions(+), 63 deletions(-) (limited to 'packages/taler-wallet-core/src/operations') diff --git a/packages/taler-wallet-core/src/operations/backup/export.ts b/packages/taler-wallet-core/src/operations/backup/export.ts index b39e6dc27..c8454a62f 100644 --- a/packages/taler-wallet-core/src/operations/backup/export.ts +++ b/packages/taler-wallet-core/src/operations/backup/export.ts @@ -71,6 +71,7 @@ import { RefreshCoinStatus, RefundState, WALLET_BACKUP_STATE_KEY, + WithdrawalGroupStatus, WithdrawalRecordType, } from "../../db.js"; import { InternalWalletState } from "../../internal-wallet-state.js"; @@ -167,8 +168,9 @@ export async function exportBackup( instructed_amount: Amounts.stringify(wg.instructedAmount), reserve_priv: wg.reservePriv, restrict_age: wg.restrictAge, + // FIXME: proper status conversion! operation_status: - wg.operationStatus == OperationStatus.Finished + wg.status == WithdrawalGroupStatus.Finished ? BackupOperationStatus.Finished : BackupOperationStatus.Pending, selected_denoms_uid: wg.denomSelUid, diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts index 20c7316c1..3a92273df 100644 --- a/packages/taler-wallet-core/src/operations/backup/import.ts +++ b/packages/taler-wallet-core/src/operations/backup/import.ts @@ -52,7 +52,7 @@ import { RefreshSessionRecord, RefundState, ReserveBankInfo, - ReserveRecordStatus, + WithdrawalGroupStatus, WalletContractData, WalletRefundItem, WalletStoresV1, @@ -531,9 +531,6 @@ export async function importBackup( exchangeBaseUrl: backupWg.exchange_base_url, instructedAmount: Amounts.parseOrThrow(backupWg.instructed_amount), secretSeed: backupWg.secret_seed, - operationStatus: backupWg.timestamp_finish - ? OperationStatus.Finished - : OperationStatus.Pending, denomsSel: await getDenomSelStateFromBackup( tx, backupWg.exchange_base_url, @@ -545,9 +542,9 @@ export async function importBackup( ), reservePriv: backupWg.reserve_priv, reservePub, - reserveStatus: backupWg.timestamp_finish - ? ReserveRecordStatus.Dormant - : ReserveRecordStatus.QueryingStatus, // FIXME! + status: backupWg.timestamp_finish + ? WithdrawalGroupStatus.Finished + : WithdrawalGroupStatus.QueryingStatus, // FIXME! timestampStart: backupWg.timestamp_created, wgInfo, restrictAge: backupWg.restrict_age, diff --git a/packages/taler-wallet-core/src/operations/peer-to-peer.ts b/packages/taler-wallet-core/src/operations/peer-to-peer.ts index 48d422e0b..d30cb294d 100644 --- a/packages/taler-wallet-core/src/operations/peer-to-peer.ts +++ b/packages/taler-wallet-core/src/operations/peer-to-peer.ts @@ -65,7 +65,7 @@ import { import { CoinStatus, MergeReserveInfo, - ReserveRecordStatus, + WithdrawalGroupStatus, WalletStoresV1, WithdrawalRecordType, } from "../db.js"; @@ -544,7 +544,7 @@ export async function acceptPeerPushPayment( contractTerms: peerInc.contractTerms, }, exchangeBaseUrl: peerInc.exchangeBaseUrl, - reserveStatus: ReserveRecordStatus.QueryingStatus, + reserveStatus: WithdrawalGroupStatus.QueryingStatus, reserveKeyPair: { priv: mergeReserveInfo.reservePriv, pub: mergeReserveInfo.reservePub, @@ -828,7 +828,7 @@ export async function initiatePeerRequestForPay( contractPriv: econtractResp.contractPriv, }, exchangeBaseUrl: req.exchangeBaseUrl, - reserveStatus: ReserveRecordStatus.QueryingStatus, + reserveStatus: WithdrawalGroupStatus.QueryingStatus, reserveKeyPair: { priv: mergeReserveInfo.reservePriv, pub: mergeReserveInfo.reservePub, diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index 9ba532ab7..18e8ec83b 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -28,6 +28,9 @@ import { BackupProviderStateTag, RefreshCoinStatus, OperationStatus, + WithdrawalGroupRecord, + WithdrawalGroupStatus, + OperationStatusRange, } from "../db.js"; import { PendingOperationsResponse, @@ -38,6 +41,7 @@ import { InternalWalletState } from "../internal-wallet-state.js"; import { GetReadOnlyAccess } from "../util/query.js"; import { RetryTags } from "../util/retries.js"; import { Wallet } from "../wallet.js"; +import { GlobalIDB } from "@gnu-taler/idb-bridge"; async function gatherExchangePending( tx: GetReadOnlyAccess<{ @@ -120,7 +124,10 @@ async function gatherWithdrawalPending( resp: PendingOperationsResponse, ): Promise { const wsrs = await tx.withdrawalGroups.indexes.byStatus.getAll( - OperationStatus.Pending, + GlobalIDB.KeyRange.bound( + OperationStatusRange.ACTIVE_START, + OperationStatusRange.ACTIVE_END, + ), ); for (const wsr of wsrs) { if (wsr.timestampFinish) { diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts index 119119035..6d899b947 100644 --- a/packages/taler-wallet-core/src/operations/recoup.ts +++ b/packages/taler-wallet-core/src/operations/recoup.ts @@ -44,7 +44,7 @@ import { CoinStatus, RecoupGroupRecord, RefreshCoinSource, - ReserveRecordStatus, + WithdrawalGroupStatus, WalletStoresV1, WithdrawalRecordType, WithdrawCoinSource, @@ -382,7 +382,7 @@ export async function processRecoupGroupHandler( await internalCreateWithdrawalGroup(ws, { amount: Amounts.parseOrThrow(result.balance), exchangeBaseUrl: recoupGroup.exchangeBaseUrl, - reserveStatus: ReserveRecordStatus.QueryingStatus, + reserveStatus: WithdrawalGroupStatus.QueryingStatus, reserveKeyPair: { pub: reservePub, priv: reservePrivMap[reservePub], diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 19f6aee64..be1233d2c 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -31,11 +31,9 @@ import { TalerProtocolTimestamp, Transaction, TransactionByIdRequest, - TransactionRefund, TransactionsRequest, TransactionsResponse, TransactionType, - WithdrawalDetails, WithdrawalType, } from "@gnu-taler/taler-util"; import { diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index ad9875400..ce910363f 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -71,7 +71,7 @@ import { ExchangeRecord, OperationStatus, PlanchetRecord, - ReserveRecordStatus, + WithdrawalGroupStatus, WalletStoresV1, WgInfo, WithdrawalGroupRecord, @@ -91,7 +91,11 @@ import { readSuccessResponseJsonOrThrow, throwUnexpectedRequestError, } from "../util/http.js"; -import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js"; +import { + checkDbInvariant, + checkLogicInvariant, + InvariantViolatedError, +} from "../util/invariants.js"; import { DbAccess, GetReadOnlyAccess } from "../util/query.js"; import { OperationAttemptResult, @@ -962,7 +966,7 @@ async function queryReserve( withdrawalGroupId, }); checkDbInvariant(!!withdrawalGroup); - if (withdrawalGroup.reserveStatus !== ReserveRecordStatus.QueryingStatus) { + if (withdrawalGroup.status !== WithdrawalGroupStatus.QueryingStatus) { return { ready: true }; } const reservePub = withdrawalGroup.reservePub; @@ -1010,7 +1014,7 @@ async function queryReserve( logger.warn(`withdrawal group ${withdrawalGroupId} not found`); return; } - wg.reserveStatus = ReserveRecordStatus.Dormant; + wg.status = WithdrawalGroupStatus.Finished; await tx.withdrawalGroups.put(wg); }); @@ -1039,13 +1043,13 @@ export async function processWithdrawalGroup( throw Error(`withdrawal group ${withdrawalGroupId} not found`); } - switch (withdrawalGroup.reserveStatus) { - case ReserveRecordStatus.RegisteringBank: + switch (withdrawalGroup.status) { + case WithdrawalGroupStatus.RegisteringBank: await processReserveBankStatus(ws, withdrawalGroupId); return await processWithdrawalGroup(ws, withdrawalGroupId, { forceNow: true, }); - case ReserveRecordStatus.QueryingStatus: { + case WithdrawalGroupStatus.QueryingStatus: { const res = await queryReserve(ws, withdrawalGroupId); if (res.ready) { return await processWithdrawalGroup(ws, withdrawalGroupId, { @@ -1057,7 +1061,7 @@ export async function processWithdrawalGroup( result: undefined, }; } - case ReserveRecordStatus.WaitConfirmBank: { + case WithdrawalGroupStatus.WaitConfirmBank: { const res = await processReserveBankStatus(ws, withdrawalGroupId); switch (res.status) { case BankStatusResultCode.Aborted: @@ -1075,23 +1079,20 @@ export async function processWithdrawalGroup( } break; } - case ReserveRecordStatus.BankAborted: { + case WithdrawalGroupStatus.BankAborted: { // FIXME return { type: OperationAttemptResultType.Pending, result: undefined, }; } - case ReserveRecordStatus.Dormant: + case WithdrawalGroupStatus.Finished: // We can try to withdraw, nothing needs to be done with the reserve. break; default: - logger.warn( - "unknown reserve record status:", - withdrawalGroup.reserveStatus, + throw new InvariantViolatedError( + `unknown reserve record status: ${withdrawalGroup.status}`, ); - assertUnreachable(withdrawalGroup.reserveStatus); - break; } await ws.exchangeOps.updateExchangeFromUrl( @@ -1108,7 +1109,7 @@ export async function processWithdrawalGroup( if (!wg) { return; } - wg.operationStatus = OperationStatus.Finished; + wg.status = WithdrawalGroupStatus.Finished; wg.timestampFinish = TalerProtocolTimestamp.now(); await tx.withdrawalGroups.put(wg); }); @@ -1192,7 +1193,7 @@ export async function processWithdrawalGroup( if (wg.timestampFinish === undefined && numFinished === numTotalCoins) { finishedForFirstTime = true; wg.timestampFinish = TalerProtocolTimestamp.now(); - wg.operationStatus = OperationStatus.Finished; + wg.status = WithdrawalGroupStatus.Finished; } await tx.withdrawalGroups.put(wg); @@ -1508,9 +1509,9 @@ async function registerReserveWithBank( .runReadOnly(async (tx) => { return await tx.withdrawalGroups.get(withdrawalGroupId); }); - switch (withdrawalGroup?.reserveStatus) { - case ReserveRecordStatus.WaitConfirmBank: - case ReserveRecordStatus.RegisteringBank: + switch (withdrawalGroup?.status) { + case WithdrawalGroupStatus.WaitConfirmBank: + case WithdrawalGroupStatus.RegisteringBank: break; default: return; @@ -1544,9 +1545,9 @@ async function registerReserveWithBank( if (!r) { return; } - switch (r.reserveStatus) { - case ReserveRecordStatus.RegisteringBank: - case ReserveRecordStatus.WaitConfirmBank: + switch (r.status) { + case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.WaitConfirmBank: break; default: return; @@ -1557,8 +1558,7 @@ async function registerReserveWithBank( r.wgInfo.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toTimestamp( AbsoluteTime.now(), ); - r.reserveStatus = ReserveRecordStatus.WaitConfirmBank; - r.operationStatus = OperationStatus.Pending; + r.status = WithdrawalGroupStatus.WaitConfirmBank; await tx.withdrawalGroups.put(r); }); ws.notify({ type: NotificationType.ReserveRegisteredWithBank }); @@ -1575,9 +1575,9 @@ async function processReserveBankStatus( const withdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, { withdrawalGroupId, }); - switch (withdrawalGroup?.reserveStatus) { - case ReserveRecordStatus.WaitConfirmBank: - case ReserveRecordStatus.RegisteringBank: + switch (withdrawalGroup?.status) { + case WithdrawalGroupStatus.WaitConfirmBank: + case WithdrawalGroupStatus.RegisteringBank: break; default: return { @@ -1616,9 +1616,9 @@ async function processReserveBankStatus( if (!r) { return; } - switch (r.reserveStatus) { - case ReserveRecordStatus.RegisteringBank: - case ReserveRecordStatus.WaitConfirmBank: + switch (r.status) { + case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.WaitConfirmBank: break; default: return; @@ -1628,8 +1628,7 @@ async function processReserveBankStatus( } const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); r.wgInfo.bankInfo.timestampBankConfirmed = now; - r.reserveStatus = ReserveRecordStatus.BankAborted; - r.operationStatus = OperationStatus.Finished; + r.status = WithdrawalGroupStatus.BankAborted; await tx.withdrawalGroups.put(r); }); return { @@ -1644,7 +1643,7 @@ async function processReserveBankStatus( } // FIXME: Why do we do this?! - if (withdrawalGroup.reserveStatus === ReserveRecordStatus.RegisteringBank) { + if (withdrawalGroup.status === WithdrawalGroupStatus.RegisteringBank) { await registerReserveWithBank(ws, withdrawalGroupId); return await processReserveBankStatus(ws, withdrawalGroupId); } @@ -1657,9 +1656,9 @@ async function processReserveBankStatus( return; } // Re-check reserve status within transaction - switch (r.reserveStatus) { - case ReserveRecordStatus.RegisteringBank: - case ReserveRecordStatus.WaitConfirmBank: + switch (r.status) { + case WithdrawalGroupStatus.RegisteringBank: + case WithdrawalGroupStatus.WaitConfirmBank: break; default: return; @@ -1671,8 +1670,7 @@ async function processReserveBankStatus( logger.info("withdrawal: transfer confirmed by bank."); const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); r.wgInfo.bankInfo.timestampBankConfirmed = now; - r.reserveStatus = ReserveRecordStatus.QueryingStatus; - r.operationStatus = OperationStatus.Pending; + r.status = WithdrawalGroupStatus.QueryingStatus; } else { logger.info("withdrawal: transfer not yet confirmed by bank"); r.wgInfo.bankInfo.confirmUrl = status.confirm_transfer_url; @@ -1689,7 +1687,7 @@ async function processReserveBankStatus( export async function internalCreateWithdrawalGroup( ws: InternalWalletState, args: { - reserveStatus: ReserveRecordStatus; + reserveStatus: WithdrawalGroupStatus; amount: AmountJson; exchangeBaseUrl: string; forcedDenomSel?: ForcedDenomSel; @@ -1728,12 +1726,11 @@ export async function internalCreateWithdrawalGroup( exchangeBaseUrl: canonExchange, instructedAmount: amount, timestampStart: now, - operationStatus: OperationStatus.Pending, rawWithdrawalAmount: initialDenomSel.totalWithdrawCost, secretSeed, reservePriv: reserveKeyPair.priv, reservePub: reserveKeyPair.pub, - reserveStatus: args.reserveStatus, + status: args.reserveStatus, withdrawalGroupId, restrictAge: args.restrictAge, senderWire: undefined, @@ -1839,7 +1836,7 @@ export async function acceptWithdrawalFromUri( }, restrictAge: req.restrictAge, forcedDenomSel: req.forcedDenomSel, - reserveStatus: ReserveRecordStatus.RegisteringBank, + reserveStatus: WithdrawalGroupStatus.RegisteringBank, }); const withdrawalGroupId = withdrawalGroup.withdrawalGroupId; @@ -1850,9 +1847,7 @@ export async function acceptWithdrawalFromUri( const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, { withdrawalGroupId, }); - if ( - processedWithdrawalGroup?.reserveStatus === ReserveRecordStatus.BankAborted - ) { + if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.BankAborted) { throw TalerError.fromDetail( TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK, {}, @@ -1898,7 +1893,7 @@ export async function createManualWithdrawal( exchangeBaseUrl: req.exchangeBaseUrl, forcedDenomSel: req.forcedDenomSel, restrictAge: req.restrictAge, - reserveStatus: ReserveRecordStatus.QueryingStatus, + reserveStatus: WithdrawalGroupStatus.QueryingStatus, }); const withdrawalGroupId = withdrawalGroup.withdrawalGroupId; -- cgit v1.2.3