diff options
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r-- | packages/taler-wallet-core/src/db.ts | 7 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/denominations.ts | 5 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/exchanges.ts | 11 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet-api-types.ts | 13 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 25 |
5 files changed, 58 insertions, 3 deletions
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 14621c2d5..b59efe034 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -486,6 +486,13 @@ export interface DenominationRecord { isRevoked: boolean; /** + * If set to true, the exchange announced that the private key for this + * denomination is lost. Thus it can't be used to sign new coins + * during withdrawal/refresh/..., but the coins can still be spent. + */ + isLost?: boolean; + + /** * Base URL of the exchange. */ exchangeBaseUrl: string; diff --git a/packages/taler-wallet-core/src/denominations.ts b/packages/taler-wallet-core/src/denominations.ts index a539918de..d41307d5d 100644 --- a/packages/taler-wallet-core/src/denominations.ts +++ b/packages/taler-wallet-core/src/denominations.ts @@ -24,7 +24,6 @@ import { AmountString, DenominationInfo, Duration, - durationFromSpec, FeeDescription, FeeDescriptionPair, TalerProtocolTimestamp, @@ -471,10 +470,10 @@ export function isWithdrawableDenom( } else { lastPossibleWithdraw = AbsoluteTime.subtractDuraction( withdrawExpire, - durationFromSpec({ minutes: 5 }), + Duration.fromSpec({ minutes: 5 }), ); } const remaining = Duration.getRemaining(lastPossibleWithdraw, now); const stillOkay = remaining.d_ms !== 0; - return started && stillOkay && !d.isRevoked && d.isOffered; + return started && stillOkay && !d.isRevoked && d.isOffered && !d.isLost; } diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts index 335caff62..c44178de8 100644 --- a/packages/taler-wallet-core/src/exchanges.ts +++ b/packages/taler-wallet-core/src/exchanges.ts @@ -779,6 +779,7 @@ async function downloadExchangeKeysInfo( exchangeMasterPub: exchangeKeysJsonUnchecked.master_public_key, isOffered: true, isRevoked: false, + isLost: denomIn.lost ?? false, value: Amounts.stringify(value), currency: value.currency, stampExpireDeposit: timestampProtocolToDb( @@ -1432,6 +1433,16 @@ export async function updateExchangeFromUrlHandler( ]); if (oldDenom) { // FIXME: Do consistency check, report to auditor if necessary. + // See https://bugs.taler.net/n/8594 + + // Mark lost denominations as lost. + if (currentDenom.isLost && !oldDenom.isLost) { + logger.warn( + `marking denomination ${currentDenom.denomPubHash} of ${exchangeBaseUrl} as lost`, + ); + oldDenom.isLost = true; + await tx.denominations.put(currentDenom); + } } else { await tx.denominations.put(currentDenom); } diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index ace702e88..4f4b24b62 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -117,6 +117,8 @@ import { StoredBackupList, TestPayArgs, TestPayResult, + TestingGetDenomStatsRequest, + TestingGetDenomStatsResponse, TestingListTasksForTransactionRequest, TestingListTasksForTransactionsResponse, TestingSetTimetravelRequest, @@ -255,6 +257,7 @@ export enum WalletApiOperation { RemoveGlobalCurrencyAuditor = "removeGlobalCurrencyAuditor", ListAssociatedRefreshes = "listAssociatedRefreshes", TestingListTaskForTransaction = "testingListTasksForTransaction", + TestingGetDenomStats = "testingGetDenomStats", } // group: Initialization @@ -1114,6 +1117,15 @@ export type TestingWaitTransactionStateOp = { }; /** + * Get stats about an exchange denomination. + */ +export type TestingGetDenomStatsOp = { + op: WalletApiOperation.TestingGetDenomStats; + request: TestingGetDenomStatsRequest; + response: TestingGetDenomStatsResponse; +}; + +/** * Set a coin as (un-)suspended. * Suspended coins won't be used for payments. */ @@ -1238,6 +1250,7 @@ export type WalletOperations = { [WalletApiOperation.RemoveGlobalCurrencyExchange]: RemoveGlobalCurrencyExchangeOp; [WalletApiOperation.ListAssociatedRefreshes]: ListAssociatedRefreshesOp; [WalletApiOperation.TestingListTaskForTransaction]: TestingListTasksForTransactionOp; + [WalletApiOperation.TestingGetDenomStats]: TestingGetDenomStatsOp; }; export type WalletCoreRequestType< diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 8c9eee009..46f58ec81 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -57,6 +57,7 @@ import { TalerErrorCode, TalerProtocolTimestamp, TalerUriAction, + TestingGetDenomStatsResponse, TestingListTasksForTransactionsResponse, TestingWaitTransactionRequest, TimerAPI, @@ -126,6 +127,7 @@ import { codecForStartRefundQueryRequest, codecForSuspendTransaction, codecForTestPayArgs, + codecForTestingGetDenomStatsRequest, codecForTestingListTasksForTransactionRequest, codecForTestingSetTimetravelRequest, codecForTransactionByIdRequest, @@ -799,6 +801,29 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( }); return {}; } + case WalletApiOperation.TestingGetDenomStats: { + const req = codecForTestingGetDenomStatsRequest().decode(payload); + const denomStats: TestingGetDenomStatsResponse = { + numKnown: 0, + numLost: 0, + numOffered: 0, + }; + await wex.db.runReadOnlyTx(["denominations"], async (tx) => { + const denoms = await tx.denominations.indexes.byExchangeBaseUrl.getAll( + req.exchangeBaseUrl, + ); + for (const d of denoms) { + denomStats.numKnown++; + if (d.isOffered) { + denomStats.numOffered++; + } + if (d.isLost) { + denomStats.numLost++; + } + } + }); + return denomStats; + } case WalletApiOperation.ListExchanges: { return await listExchanges(wex); } |