From e075134ffc94fda3582b179122bda594d91a962b Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Sat, 15 Oct 2022 11:52:07 +0200 Subject: wallet-core: simplify coin record we only track the allocation now, not the remaining amount --- .../src/operations/backup/export.ts | 10 +++-- .../src/operations/backup/import.ts | 6 +-- .../taler-wallet-core/src/operations/balance.ts | 25 ++++++++---- .../taler-wallet-core/src/operations/common.ts | 26 ++++++++---- .../src/operations/pay-merchant.ts | 46 +++++++++------------- .../taler-wallet-core/src/operations/pay-peer.ts | 8 ++-- .../taler-wallet-core/src/operations/recoup.ts | 42 ++++++++++---------- .../taler-wallet-core/src/operations/refresh.ts | 24 ++++++----- packages/taler-wallet-core/src/operations/tip.ts | 5 +-- .../src/operations/transactions.ts | 8 ++-- .../taler-wallet-core/src/operations/withdraw.ts | 7 +--- 11 files changed, 110 insertions(+), 97 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 30e61e382..1472b1b90 100644 --- a/packages/taler-wallet-core/src/operations/backup/export.ts +++ b/packages/taler-wallet-core/src/operations/backup/export.ts @@ -54,6 +54,7 @@ import { BACKUP_VERSION_MINOR, canonicalizeBaseUrl, canonicalJson, + CoinStatus, encodeCrock, getRandomBytes, hash, @@ -63,7 +64,6 @@ import { } from "@gnu-taler/taler-util"; import { CoinSourceType, - CoinStatus, ConfigRecordKey, DenominationRecord, PurchaseStatus, @@ -206,7 +206,6 @@ export async function exportBackup( coins: recoupGroup.coinPubs.map((x, i) => ({ coin_pub: x, recoup_finished: recoupGroup.recoupFinishedPerCoin[i], - old_amount: Amounts.stringify(recoupGroup.oldAmountPerCoin[i]), })), }); }); @@ -259,8 +258,13 @@ export async function exportBackup( blinding_key: coin.blindingKey, coin_priv: coin.coinPriv, coin_source: bcs, - current_amount: Amounts.stringify(coin.currentAmount), fresh: coin.status === CoinStatus.Fresh, + spend_allocation: coin.spendAllocation + ? { + amount: coin.spendAllocation.amount, + id: coin.spendAllocation.id, + } + : undefined, denom_sig: coin.denomSig, }); }); diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts index 3bbb7d798..9c5eea9af 100644 --- a/packages/taler-wallet-core/src/operations/backup/import.ts +++ b/packages/taler-wallet-core/src/operations/backup/import.ts @@ -27,6 +27,7 @@ import { BackupRefundState, BackupWgType, codecForContractTerms, + CoinStatus, DenomKeyType, DenomSelectionState, j2s, @@ -41,10 +42,8 @@ import { CoinRecord, CoinSource, CoinSourceType, - CoinStatus, DenominationRecord, DenominationVerificationStatus, - OperationStatus, ProposalDownloadInfo, PurchaseStatus, PurchasePayInfo, @@ -272,7 +271,6 @@ export async function importCoin( blindingKey: backupCoin.blinding_key, coinEvHash: compCoin.coinEvHash, coinPriv: backupCoin.coin_priv, - currentAmount: Amounts.parseOrThrow(backupCoin.current_amount), denomSig: backupCoin.denom_sig, coinPub: compCoin.coinPub, exchangeBaseUrl, @@ -284,7 +282,7 @@ export async function importCoin( // FIXME! ageCommitmentProof: undefined, // FIXME! - allocation: undefined, + spendAllocation: undefined, }; if (coinRecord.status === CoinStatus.Fresh) { await makeCoinAvailable(ws, tx, coinRecord); diff --git a/packages/taler-wallet-core/src/operations/balance.ts b/packages/taler-wallet-core/src/operations/balance.ts index 44357fdf4..3db66b5d9 100644 --- a/packages/taler-wallet-core/src/operations/balance.ts +++ b/packages/taler-wallet-core/src/operations/balance.ts @@ -23,7 +23,7 @@ import { Amounts, Logger, } from "@gnu-taler/taler-util"; -import { CoinStatus, WalletStoresV1 } from "../db.js"; +import { WalletStoresV1 } from "../db.js"; import { GetReadOnlyAccess } from "../util/query.js"; import { InternalWalletState } from "../internal-wallet-state.js"; @@ -42,6 +42,7 @@ export async function getBalancesInsideTransaction( ws: InternalWalletState, tx: GetReadOnlyAccess<{ coins: typeof WalletStoresV1.coins; + coinAvailability: typeof WalletStoresV1.coinAvailability; refreshGroups: typeof WalletStoresV1.refreshGroups; withdrawalGroups: typeof WalletStoresV1.withdrawalGroups; }>, @@ -64,12 +65,14 @@ export async function getBalancesInsideTransaction( return balanceStore[currency]; }; - await tx.coins.iter().forEach((c) => { - // Only count fresh coins, as dormant coins will - // already be in a refresh session. - if (c.status === CoinStatus.Fresh) { - const b = initBalance(c.currentAmount.currency); - b.available = Amounts.add(b.available, c.currentAmount).amount; + await tx.coinAvailability.iter().forEach((ca) => { + const b = initBalance(ca.currency); + for (let i = 0; i < ca.freshCoinCount; i++) { + b.available = Amounts.add(b.available, { + currency: ca.currency, + fraction: ca.amountFrac, + value: ca.amountVal, + }).amount; } }); @@ -139,7 +142,13 @@ export async function getBalances( logger.trace("starting to compute balance"); const wbal = await ws.db - .mktx((x) => [x.coins, x.refreshGroups, x.purchases, x.withdrawalGroups]) + .mktx((x) => [ + x.coins, + x.coinAvailability, + x.refreshGroups, + x.purchases, + x.withdrawalGroups, + ]) .runReadOnly(async (tx) => { return getBalancesInsideTransaction(ws, tx); }); diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index d17530c7f..5e02f3d7b 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -20,6 +20,8 @@ import { AmountJson, Amounts, + CoinRefreshRequest, + CoinStatus, j2s, Logger, RefreshReason, @@ -29,7 +31,7 @@ import { TransactionIdStr, TransactionType, } from "@gnu-taler/taler-util"; -import { WalletStoresV1, CoinStatus, CoinRecord } from "../db.js"; +import { WalletStoresV1, CoinRecord } from "../db.js"; import { makeErrorDetail, TalerError } from "../errors.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js"; @@ -103,11 +105,19 @@ export async function spendCoins( }>, csi: CoinsSpendInfo, ): Promise { + let refreshCoinPubs: CoinRefreshRequest[] = []; for (let i = 0; i < csi.coinPubs.length; i++) { const coin = await tx.coins.get(csi.coinPubs[i]); if (!coin) { throw Error("coin allocated for payment doesn't exist anymore"); } + const denom = await ws.getDenomInfo( + ws, + tx, + coin.exchangeBaseUrl, + coin.denomPubHash, + ); + checkDbInvariant(!!denom); const coinAvailability = await tx.coinAvailability.get([ coin.exchangeBaseUrl, coin.denomPubHash, @@ -116,7 +126,7 @@ export async function spendCoins( checkDbInvariant(!!coinAvailability); const contrib = csi.contributions[i]; if (coin.status !== CoinStatus.Fresh) { - const alloc = coin.allocation; + const alloc = coin.spendAllocation; if (!alloc) { continue; } @@ -131,15 +141,18 @@ export async function spendCoins( continue; } coin.status = CoinStatus.Dormant; - coin.allocation = { + coin.spendAllocation = { id: csi.allocationId, amount: Amounts.stringify(contrib), }; - const remaining = Amounts.sub(coin.currentAmount, contrib); + const remaining = Amounts.sub(denom.value, contrib); if (remaining.saturated) { throw Error("not enough remaining balance on coin for payment"); } - coin.currentAmount = remaining.amount; + refreshCoinPubs.push({ + amount: remaining.amount, + coinPub: coin.coinPub, + }); checkDbInvariant(!!coinAvailability); if (coinAvailability.freshCoinCount === 0) { throw Error( @@ -150,9 +163,6 @@ export async function spendCoins( await tx.coins.put(coin); await tx.coinAvailability.put(coinAvailability); } - const refreshCoinPubs = csi.coinPubs.map((x) => ({ - coinPub: x, - })); await ws.refreshOps.createRefreshGroup( ws, tx, diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index 6b14b60c6..2b0ea1f96 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -40,7 +40,8 @@ import { codecForMerchantPayResponse, codecForProposal, CoinDepositPermission, - CoinPublicKey, + CoinRefreshRequest, + CoinStatus, ConfirmPayResult, ConfirmPayResultType, ContractTerms, @@ -78,7 +79,6 @@ import { AllowedExchangeInfo, BackupProviderStateTag, CoinRecord, - CoinStatus, DenominationRecord, PurchaseRecord, PurchaseStatus, @@ -2084,7 +2084,7 @@ async function applySuccessfulRefund( denominations: typeof WalletStoresV1.denominations; }>, p: PurchaseRecord, - refreshCoinsMap: Record, + refreshCoinsMap: Record, r: MerchantCoinRefundSuccessStatus, ): Promise { // FIXME: check signature before storing it as valid! @@ -2102,31 +2102,23 @@ async function applySuccessfulRefund( if (!denom) { throw Error("inconsistent database"); } - refreshCoinsMap[coin.coinPub] = { coinPub: coin.coinPub }; const refundAmount = Amounts.parseOrThrow(r.refund_amount); const refundFee = denom.fees.feeRefund; + const amountLeft = Amounts.sub(refundAmount, refundFee).amount; coin.status = CoinStatus.Dormant; - coin.currentAmount = Amounts.add(coin.currentAmount, refundAmount).amount; - coin.currentAmount = Amounts.sub(coin.currentAmount, refundFee).amount; - logger.trace(`coin amount after is ${Amounts.stringify(coin.currentAmount)}`); await tx.coins.put(coin); const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl .iter(coin.exchangeBaseUrl) .toArray(); - - const amountLeft = Amounts.sub( - Amounts.add(coin.currentAmount, Amounts.parseOrThrow(r.refund_amount)) - .amount, - denom.fees.feeRefund, - ).amount; - const totalRefreshCostBound = getTotalRefreshCost( allDenoms, DenominationRecord.toDenomInfo(denom), amountLeft, ); + refreshCoinsMap[coin.coinPub] = { coinPub: coin.coinPub, amount: amountLeft }; + p.refunds[refundKey] = { type: RefundState.Applied, obtainedTime: AbsoluteTime.toTimestamp(AbsoluteTime.now()), @@ -2167,9 +2159,9 @@ async function storePendingRefund( .iter(coin.exchangeBaseUrl) .toArray(); + // Refunded amount after fees. const amountLeft = Amounts.sub( - Amounts.add(coin.currentAmount, Amounts.parseOrThrow(r.refund_amount)) - .amount, + Amounts.parseOrThrow(r.refund_amount), denom.fees.feeRefund, ).amount; @@ -2197,7 +2189,7 @@ async function storeFailedRefund( denominations: typeof WalletStoresV1.denominations; }>, p: PurchaseRecord, - refreshCoinsMap: Record, + refreshCoinsMap: Record, r: MerchantCoinRefundFailureStatus, ): Promise { const refundKey = getRefundKey(r); @@ -2221,8 +2213,7 @@ async function storeFailedRefund( .toArray(); const amountLeft = Amounts.sub( - Amounts.add(coin.currentAmount, Amounts.parseOrThrow(r.refund_amount)) - .amount, + Amounts.parseOrThrow(r.refund_amount), denom.fees.feeRefund, ).amount; @@ -2246,6 +2237,7 @@ async function storeFailedRefund( if (p.purchaseStatus === PurchaseStatus.AbortingWithRefund) { // Refund failed because the merchant didn't even try to deposit // the coin yet, so we try to refresh. + // FIXME: Is this case tested?! if (r.exchange_code === TalerErrorCode.EXCHANGE_REFUND_DEPOSIT_NOT_FOUND) { const coin = await tx.coins.get(r.coin_pub); if (!coin) { @@ -2271,14 +2263,11 @@ async function storeFailedRefund( contrib = payCoinSelection.coinContributions[i]; } } - if (contrib) { - coin.currentAmount = Amounts.add(coin.currentAmount, contrib).amount; - coin.currentAmount = Amounts.sub( - coin.currentAmount, - denom.fees.feeRefund, - ).amount; - } - refreshCoinsMap[coin.coinPub] = { coinPub: coin.coinPub }; + // FIXME: Is this case tested?! + refreshCoinsMap[coin.coinPub] = { + coinPub: coin.coinPub, + amount: amountLeft, + }; await tx.coins.put(coin); } } @@ -2308,7 +2297,7 @@ async function acceptRefunds( return; } - const refreshCoinsMap: Record = {}; + const refreshCoinsMap: Record = {}; for (const refundStatus of refunds) { const refundKey = getRefundKey(refundStatus); @@ -2350,6 +2339,7 @@ async function acceptRefunds( } const refreshCoinsPubs = Object.values(refreshCoinsMap); + logger.info(`refreshCoinMap ${j2s(refreshCoinsMap)}`); if (refreshCoinsPubs.length > 0) { await createRefreshGroup( ws, diff --git a/packages/taler-wallet-core/src/operations/pay-peer.ts b/packages/taler-wallet-core/src/operations/pay-peer.ts index ffc49c24c..3b65fba6b 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer.ts @@ -36,6 +36,7 @@ import { codecForAmountString, codecForAny, codecForExchangeGetContractResponse, + CoinStatus, constructPayPullUri, constructPayPushUri, ContractTermsUtil, @@ -63,17 +64,16 @@ import { WalletAccountMergeFlags, } from "@gnu-taler/taler-util"; import { - CoinStatus, - WithdrawalGroupStatus, + ReserveRecord, WalletStoresV1, + WithdrawalGroupStatus, WithdrawalRecordType, - ReserveRecord, } from "../db.js"; import { InternalWalletState } from "../internal-wallet-state.js"; +import { makeTransactionId, spendCoins } from "../operations/common.js"; import { readSuccessResponseJsonOrThrow } from "../util/http.js"; import { checkDbInvariant } from "../util/invariants.js"; import { GetReadOnlyAccess } from "../util/query.js"; -import { spendCoins, makeTransactionId } from "../operations/common.js"; import { updateExchangeFromUrl } from "./exchanges.js"; import { internalCreateWithdrawalGroup } from "./withdraw.js"; diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts index ff6bb4efc..d3bcde048 100644 --- a/packages/taler-wallet-core/src/operations/recoup.ts +++ b/packages/taler-wallet-core/src/operations/recoup.ts @@ -28,6 +28,7 @@ import { Amounts, codecForRecoupConfirmation, codecForReserveStatus, + CoinStatus, encodeCrock, getRandomBytes, j2s, @@ -40,7 +41,6 @@ import { import { CoinRecord, CoinSourceType, - CoinStatus, RecoupGroupRecord, RefreshCoinSource, WalletStoresV1, @@ -50,6 +50,7 @@ import { } from "../db.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { readSuccessResponseJsonOrThrow } from "../util/http.js"; +import { checkDbInvariant } from "../util/invariants.js"; import { GetReadWriteAccess } from "../util/query.js"; import { OperationAttemptResult, @@ -180,8 +181,6 @@ async function recoupWithdrawCoin( return; } updatedCoin.status = CoinStatus.Dormant; - const currency = updatedCoin.currentAmount.currency; - updatedCoin.currentAmount = Amounts.getZero(currency); await tx.coins.put(updatedCoin); await putGroupAsFinished(ws, tx, recoupGroup, coinIdx); }); @@ -265,16 +264,25 @@ async function recoupRefreshCoin( logger.warn("refresh old coin for recoup not found"); return; } - revokedCoin.status = CoinStatus.Dormant; - oldCoin.currentAmount = Amounts.add( - oldCoin.currentAmount, - recoupGroup.oldAmountPerCoin[coinIdx], - ).amount; - logger.trace( - "recoup: setting old coin amount to", - Amounts.stringify(oldCoin.currentAmount), + const oldCoinDenom = await ws.getDenomInfo( + ws, + tx, + oldCoin.exchangeBaseUrl, + oldCoin.denomPubHash, ); - recoupGroup.scheduleRefreshCoins.push(oldCoin.coinPub); + const revokedCoinDenom = await ws.getDenomInfo( + ws, + tx, + revokedCoin.exchangeBaseUrl, + revokedCoin.denomPubHash, + ); + checkDbInvariant(!!oldCoinDenom); + checkDbInvariant(!!revokedCoinDenom); + revokedCoin.status = CoinStatus.Dormant; + recoupGroup.scheduleRefreshCoins.push({ + coinPub: oldCoin.coinPub, + amount: Amounts.sub(oldCoinDenom.value, revokedCoinDenom.value).amount, + }); await tx.coins.put(revokedCoin); await tx.coins.put(oldCoin); await putGroupAsFinished(ws, tx, recoupGroup, coinIdx); @@ -410,7 +418,7 @@ export async function processRecoupGroupHandler( const refreshGroupId = await createRefreshGroup( ws, tx, - rg2.scheduleRefreshCoins.map((x) => ({ coinPub: x })), + rg2.scheduleRefreshCoins, RefreshReason.Recoup, ); processRefreshGroup(ws, refreshGroupId.refreshGroupId).catch((e) => { @@ -442,8 +450,6 @@ export async function createRecoupGroup( timestampFinished: undefined, timestampStarted: TalerProtocolTimestamp.now(), recoupFinishedPerCoin: coinPubs.map(() => false), - // Will be populated later - oldAmountPerCoin: [], scheduleRefreshCoins: [], }; @@ -454,12 +460,6 @@ export async function createRecoupGroup( await putGroupAsFinished(ws, tx, recoupGroup, coinIdx); continue; } - if (Amounts.isZero(coin.currentAmount)) { - await putGroupAsFinished(ws, tx, recoupGroup, coinIdx); - continue; - } - recoupGroup.oldAmountPerCoin[coinIdx] = coin.currentAmount; - coin.currentAmount = Amounts.getZero(coin.currentAmount.currency); await tx.coins.put(coin); } diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index 83ab32f20..c7d2c320e 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -23,8 +23,9 @@ import { amountToPretty, codecForExchangeMeltResponse, codecForExchangeRevealResponse, - CoinPublicKey, CoinPublicKeyString, + CoinRefreshRequest, + CoinStatus, DenominationInfo, DenomKeyType, Duration, @@ -55,9 +56,7 @@ import { CryptoApiStoppedError } from "../crypto/workers/cryptoDispatcher.js"; import { CoinRecord, CoinSourceType, - CoinStatus, DenominationRecord, - OperationStatus, RefreshCoinStatus, RefreshGroupRecord, RefreshOperationStatus, @@ -672,7 +671,6 @@ async function refreshReveal( blindingKey: pc.blindingKey, coinPriv: pc.coinPriv, coinPub: pc.coinPub, - currentAmount: ncd.value, denomPubHash: ncd.denomPubHash, denomSig, exchangeBaseUrl: oldCoin.exchangeBaseUrl, @@ -684,7 +682,7 @@ async function refreshReveal( coinEvHash: pc.coinEvHash, maxAge: pc.maxAge, ageCommitmentProof: pc.ageCommitmentProof, - allocation: undefined, + spendAllocation: undefined, }; coins.push(coin); @@ -845,7 +843,7 @@ export async function createRefreshGroup( refreshGroups: typeof WalletStoresV1.refreshGroups; coinAvailability: typeof WalletStoresV1.coinAvailability; }>, - oldCoinPubs: CoinPublicKey[], + oldCoinPubs: CoinRefreshRequest[], reason: RefreshReason, ): Promise { const refreshGroupId = encodeCrock(getRandomBytes(32)); @@ -908,9 +906,8 @@ export async function createRefreshGroup( default: assertUnreachable(coin.status); } - const refreshAmount = coin.currentAmount; + const refreshAmount = ocp.amount; inputPerCoin.push(refreshAmount); - coin.currentAmount = Amounts.getZero(refreshAmount.currency); await tx.coins.put(coin); const denoms = await getDenoms(coin.exchangeBaseUrl); const cost = getTotalRefreshCost(denoms, denom, refreshAmount); @@ -1008,7 +1005,7 @@ export async function autoRefresh( const coins = await tx.coins.indexes.byBaseUrl .iter(exchangeBaseUrl) .toArray(); - const refreshCoins: CoinPublicKey[] = []; + const refreshCoins: CoinRefreshRequest[] = []; for (const coin of coins) { if (coin.status !== CoinStatus.Fresh) { continue; @@ -1023,7 +1020,14 @@ export async function autoRefresh( } const executeThreshold = getAutoRefreshExecuteThreshold(denom); if (AbsoluteTime.isExpired(executeThreshold)) { - refreshCoins.push(coin); + refreshCoins.push({ + coinPub: coin.coinPub, + amount: { + value: denom.amountVal, + fraction: denom.amountFrac, + currency: denom.currency, + }, + }); } else { const checkThreshold = getAutoRefreshCheckThreshold(denom); minCheckThreshold = AbsoluteTime.min( diff --git a/packages/taler-wallet-core/src/operations/tip.ts b/packages/taler-wallet-core/src/operations/tip.ts index b74e1182a..f98d69e26 100644 --- a/packages/taler-wallet-core/src/operations/tip.ts +++ b/packages/taler-wallet-core/src/operations/tip.ts @@ -24,6 +24,7 @@ import { BlindedDenominationSignature, codecForMerchantTipResponseV2, codecForTipPickupGetResponse, + CoinStatus, DenomKeyType, encodeCrock, getRandomBytes, @@ -41,7 +42,6 @@ import { DerivedTipPlanchet } from "../crypto/cryptoTypes.js"; import { CoinRecord, CoinSourceType, - CoinStatus, DenominationRecord, TipRecord, } from "../db.js"; @@ -311,7 +311,6 @@ export async function processTip( coinIndex: i, walletTipId: walletTipId, }, - currentAmount: DenominationRecord.getValue(denom), denomPubHash: denom.denomPubHash, denomSig: { cipher: DenomKeyType.Rsa, rsa_signature: denomSigRsa.sig }, exchangeBaseUrl: tipRecord.exchangeBaseUrl, @@ -319,7 +318,7 @@ export async function processTip( coinEvHash: planchet.coinEvHash, maxAge: AgeRestriction.AGE_UNRESTRICTED, ageCommitmentProof: planchet.ageCommitmentProof, - allocation: undefined, + spendAllocation: undefined, }); } diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index c7ff4161a..1e7f982bc 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -540,7 +540,6 @@ function buildTransactionForTip( /** * For a set of refund with the same executionTime. - * */ interface MergedRefundInfo { executionTime: TalerProtocolTimestamp; @@ -556,7 +555,7 @@ function mergeRefundByExecutionTime( const refundByExecTime = rs.reduce((prev, refund) => { const key = `${refund.executionTime.t_s}`; - //refunds counts if applied + // refunds count if applied const effective = refund.type === RefundState.Applied ? Amounts.sub( @@ -582,7 +581,10 @@ function mergeRefundByExecutionTime( v.amountAppliedEffective, effective, ).amount; - v.amountAppliedRaw = Amounts.add(v.amountAppliedRaw).amount; + v.amountAppliedRaw = Amounts.add( + v.amountAppliedRaw, + refund.refundAmount, + ).amount; v.firstTimestamp = TalerProtocolTimestamp.min( v.firstTimestamp, refund.obtainedTime, diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index a258c5d76..d7627e6cf 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -36,6 +36,7 @@ import { codecForWithdrawBatchResponse, codecForWithdrawOperationStatusResponse, codecForWithdrawResponse, + CoinStatus, DenomKeyType, DenomSelectionState, Duration, @@ -57,7 +58,6 @@ import { TransactionType, UnblindedSignature, URL, - VersionMatchResult, WithdrawBatchResponse, WithdrawResponse, WithdrawUriInfoResponse, @@ -66,10 +66,8 @@ import { EddsaKeypair } from "../crypto/cryptoImplementation.js"; import { CoinRecord, CoinSourceType, - CoinStatus, DenominationRecord, DenominationVerificationStatus, - ExchangeTosRecord, PlanchetRecord, PlanchetStatus, WalletStoresV1, @@ -736,7 +734,6 @@ async function processPlanchetVerifyAndStoreCoin( blindingKey: planchet.blindingKey, coinPriv: planchet.coinPriv, coinPub: planchet.coinPub, - currentAmount: denomInfo.value, denomPubHash: planchet.denomPubHash, denomSig, coinEvHash: planchet.coinEvHash, @@ -750,7 +747,7 @@ async function processPlanchetVerifyAndStoreCoin( }, maxAge: planchet.maxAge, ageCommitmentProof: planchet.ageCommitmentProof, - allocation: undefined, + spendAllocation: undefined, }; const planchetCoinPub = planchet.coinPub; -- cgit v1.2.3