From 828e65b0eba66b7c999d9867396797a239449a6d Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 23 Aug 2021 22:28:36 +0200 Subject: fix un-offered denom situation, test case almost works --- .../taler-wallet-core/src/operations/exchanges.ts | 43 ++++++++++++++++++++-- packages/taler-wallet-core/src/operations/pay.ts | 6 +++ .../src/operations/transactions.ts | 2 +- .../taler-wallet-core/src/operations/withdraw.ts | 17 +++++++-- 4 files changed, 59 insertions(+), 9 deletions(-) (limited to 'packages/taler-wallet-core/src/operations') diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 0670c8a61..23459de92 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -153,6 +153,9 @@ async function downloadExchangeWithTermsOfService( return { tosText, tosEtag }; } +/** + * Get exchange details from the database. + */ export async function getExchangeDetails( tx: GetReadOnlyAccess<{ exchanges: typeof WalletStoresV1.exchanges; @@ -320,6 +323,7 @@ interface ExchangeKeysDownloadResult { reserveClosingDelay: Duration; expiry: Timestamp; recoup: Recoup[]; + listIssueDate: Timestamp; } /** @@ -392,6 +396,7 @@ async function downloadKeysInfo( minDuration: durationFromSpec({ hours: 1 }), }), recoup: exchangeKeysJson.recoup ?? [], + listIssueDate: exchangeKeysJson.list_issue_date, }; } @@ -508,9 +513,9 @@ async function updateExchangeFromUrlImpl( r.lastError = undefined; r.retryInfo = initRetryInfo(); r.lastUpdate = getTimestampNow(); - (r.nextUpdate = keysInfo.expiry), - // New denominations might be available. - (r.nextRefreshCheck = getTimestampNow()); + r.nextUpdate = keysInfo.expiry; + // New denominations might be available. + r.nextRefreshCheck = getTimestampNow(); r.detailsPointer = { currency: details.currency, masterPublicKey: details.masterPublicKey, @@ -521,17 +526,47 @@ async function updateExchangeFromUrlImpl( await tx.exchangeDetails.put(details); logger.trace("updating denominations in database"); + const currentDenomSet = new Set( + keysInfo.currentDenominations.map((x) => x.denomPubHash), + ); for (const currentDenom of keysInfo.currentDenominations) { const oldDenom = await tx.denominations.get([ baseUrl, currentDenom.denomPubHash, ]); if (oldDenom) { - // FIXME: Do consistency check + // FIXME: Do consistency check, report to auditor if necessary. } else { await tx.denominations.put(currentDenom); } } + + // Update list issue date for all denominations, + // and mark non-offered denominations as such. + await tx.denominations.indexes.byExchangeBaseUrl + .iter(r.baseUrl) + .forEachAsync(async (x) => { + if (!currentDenomSet.has(x.denomPubHash)) { + // FIXME: Here, an auditor report should be created, unless + // the denomination is really legally expired. + if (x.isOffered) { + x.isOffered = false; + logger.info( + `setting denomination ${x.denomPubHash} to offered=false`, + ); + } + } else { + x.listIssueDate = keysInfo.listIssueDate; + if (!x.isOffered) { + x.isOffered = true; + logger.info( + `setting denomination ${x.denomPubHash} to offered=true`, + ); + } + } + await tx.denominations.put(x); + }); + logger.trace("done updating denominations in database"); // Handle recoup diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts index 54049feb2..a201e6f8d 100644 --- a/packages/taler-wallet-core/src/operations/pay.ts +++ b/packages/taler-wallet-core/src/operations/pay.ts @@ -211,6 +211,12 @@ function isSpendableCoin(coin: CoinRecord, denom: DenominationRecord): boolean { if (coin.suspended) { return false; } + if (denom.isRevoked) { + return false; + } + if (!denom.isOffered) { + return false; + } if (coin.status !== CoinStatus.Fresh) { return false; } diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index a07551e82..a21dbe8b8 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -505,7 +505,7 @@ export async function deleteTransaction( const purchase = await tx.purchases.get(proposalId); if (purchase) { found = true; - await tx.proposals.delete(proposalId); + await tx.purchases.delete(proposalId); } if (found) { await tx.tombstones.put({ diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 81c35c17b..521cfa113 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -158,8 +158,8 @@ interface ExchangeWithdrawDetails { } /** - * Check if a denom is withdrawable based on the expiration time - * and revocation state. + * Check if a denom is withdrawable based on the expiration time, + * revocation and offered state. */ export function isWithdrawableDenom(d: DenominationRecord): boolean { const now = getTimestampNow(); @@ -175,7 +175,7 @@ export function isWithdrawableDenom(d: DenominationRecord): boolean { } const remaining = getDurationRemaining(lastPossibleWithdraw, now); const stillOkay = remaining.d_ms !== 0; - return started && stillOkay && !d.isRevoked; + return started && stillOkay && !d.isRevoked && d.isOffered; } /** @@ -230,6 +230,14 @@ export function selectWithdrawalDenominations( } } + if (logger.shouldLogTrace()) { + logger.trace(`selected withdrawal denoms for ${Amounts.stringify(totalCoinValue)}`); + for (const sd of selectedDenoms) { + logger.trace(`denom_pub_hash=${sd.denom.denomPubHash}, count=${sd.count}`); + } + logger.trace("(end of withdrawal denom list)"); + } + return { selectedDenoms, totalCoinValue, @@ -306,7 +314,8 @@ export async function getCandidateWithdrawalDenoms( return await ws.db .mktx((x) => ({ denominations: x.denominations })) .runReadOnly(async (tx) => { - return tx.denominations.indexes.byExchangeBaseUrl.getAll(exchangeBaseUrl); + const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl.getAll(exchangeBaseUrl); + return allDenoms.filter(isWithdrawableDenom); }); } -- cgit v1.2.3