diff options
author | Florian Dold <florian@dold.me> | 2023-06-26 19:27:34 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2023-06-26 19:27:42 +0200 |
commit | a844136489611525726c117cb28086b854bee5c0 (patch) | |
tree | bb3384fab39600c35675cd8e36caac9246ef9782 /packages/taler-wallet-core/src/operations/balance.ts | |
parent | 2779086a32a62d6d16b7813c2ca4944dc02c4d93 (diff) | |
download | wallet-core-a844136489611525726c117cb28086b854bee5c0.tar.xz |
wallet-core: make changes to available amount atomic
W.r.t. transactions
Diffstat (limited to 'packages/taler-wallet-core/src/operations/balance.ts')
-rw-r--r-- | packages/taler-wallet-core/src/operations/balance.ts | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/packages/taler-wallet-core/src/operations/balance.ts b/packages/taler-wallet-core/src/operations/balance.ts index 3ab6649d7..af88181c0 100644 --- a/packages/taler-wallet-core/src/operations/balance.ts +++ b/packages/taler-wallet-core/src/operations/balance.ts @@ -20,14 +20,17 @@ * There are multiple definition of the wallet's balance. * We use the following terminology: * - * - "available": Balance that the wallet believes will certainly be available - * for spending, modulo any failures of the exchange or double spending issues. - * This includes available coins *not* allocated to any - * spending/refresh/... operation. Pending withdrawals are *not* counted - * towards this balance, because they are not certain to succeed. - * Pending refreshes *are* counted towards this balance. - * This balance type is nice to show to the user, because it does not - * temporarily decrease after payment when we are waiting for refreshes + * - "available": Balance that is available + * for spending from transactions in their final state and + * expected to be available from pending refreshes. + * + * - "pending-incoming": Expected (positive!) delta + * to the available balance that we expect to have + * after pending operations reach the "done" state. + * + * - "pending-outgoing": Amount that is currently allocated + * to be spent, but the spend operation could still be aborted + * and part of the pending-outgoing amount could be recovered. * * - "material": Balance that the wallet believes it could spend *right now*, * without waiting for any operations to complete. @@ -61,11 +64,13 @@ import { AllowedExchangeInfo, RefreshGroupRecord, WalletStoresV1, + WithdrawalGroupStatus, } from "../db.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { checkLogicInvariant } from "../util/invariants.js"; import { GetReadOnlyAccess } from "../util/query.js"; import { getExchangeDetails } from "./exchanges.js"; +import { assertUnreachable } from "../util/assertUnreachable.js"; /** * Logger. @@ -133,7 +138,8 @@ export async function getBalancesInsideTransaction( await tx.coinAvailability.iter().forEach((ca) => { const b = initBalance(ca.currency); - for (let i = 0; i < ca.freshCoinCount; i++) { + const count = ca.visibleCoinCount ?? 0; + for (let i = 0; i < count; i++) { b.available = Amounts.add(b.available, { currency: ca.currency, fraction: ca.amountFrac, @@ -150,14 +156,40 @@ export async function getBalancesInsideTransaction( ).amount; }); - await tx.withdrawalGroups.iter().forEach((wds) => { - if (wds.timestampFinish) { - return; + // FIXME: Use indexing to filter out final transactions. + await tx.withdrawalGroups.iter().forEach((wgRecord) => { + switch (wgRecord.status) { + case WithdrawalGroupStatus.AbortedBank: + case WithdrawalGroupStatus.AbortedExchange: + case WithdrawalGroupStatus.FailedAbortingBank: + case WithdrawalGroupStatus.FailedBankAborted: + case WithdrawalGroupStatus.Finished: + // Does not count as pendingIncoming + return; + case WithdrawalGroupStatus.PendingReady: + case WithdrawalGroupStatus.AbortingBank: + case WithdrawalGroupStatus.PendingAml: + case WithdrawalGroupStatus.PendingKyc: + case WithdrawalGroupStatus.PendingQueryingStatus: + case WithdrawalGroupStatus.SuspendedWaitConfirmBank: + case WithdrawalGroupStatus.SuspendedReady: + case WithdrawalGroupStatus.SuspendedRegisteringBank: + case WithdrawalGroupStatus.SuspendedKyc: + case WithdrawalGroupStatus.SuspendedAbortingBank: + case WithdrawalGroupStatus.SuspendedAml: + case WithdrawalGroupStatus.PendingRegisteringBank: + case WithdrawalGroupStatus.PendingWaitConfirmBank: + case WithdrawalGroupStatus.SuspendedQueryingStatus: + break; + default: + assertUnreachable(wgRecord.status); } - const b = initBalance(Amounts.currencyOf(wds.denomsSel.totalWithdrawCost)); + const b = initBalance( + Amounts.currencyOf(wgRecord.denomsSel.totalWithdrawCost), + ); b.pendingIncoming = Amounts.add( b.pendingIncoming, - wds.denomsSel.totalCoinValue, + wgRecord.denomsSel.totalCoinValue, ).amount; }); |