gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 03/03: all retryInfo function in the same namespace,


From: gnunet
Subject: [taler-wallet-core] 03/03: all retryInfo function in the same namespace, adding missing retryInfo increment
Date: Wed, 18 May 2022 19:42:03 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

commit c67d0bff1daa35d380d1d71b94428a5026b56450
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed May 18 14:41:51 2022 -0300

    all retryInfo function in the same namespace, adding missing retryInfo 
increment
---
 packages/taler-wallet-core/src/bank-api-client.ts  |  5 +-
 .../src/operations/backup/import.ts                | 68 ++++++----------
 .../src/operations/backup/index.ts                 | 73 +++++++-----------
 .../taler-wallet-core/src/operations/deposits.ts   |  6 +-
 .../taler-wallet-core/src/operations/exchanges.ts  |  9 ++-
 packages/taler-wallet-core/src/operations/pay.ts   | 22 +++---
 .../taler-wallet-core/src/operations/recoup.ts     | 36 ++++-----
 .../taler-wallet-core/src/operations/refresh.ts    | 90 +++++++++-------------
 .../taler-wallet-core/src/operations/refund.ts     | 40 ++++------
 .../taler-wallet-core/src/operations/reserves.ts   | 23 +++---
 packages/taler-wallet-core/src/operations/tip.ts   | 53 ++++---------
 .../taler-wallet-core/src/operations/withdraw.ts   | 15 ++--
 packages/taler-wallet-core/src/util/retries.ts     | 61 +++++++--------
 packages/taler-wallet-core/src/wallet.ts           |  7 +-
 14 files changed, 205 insertions(+), 303 deletions(-)

diff --git a/packages/taler-wallet-core/src/bank-api-client.ts 
b/packages/taler-wallet-core/src/bank-api-client.ts
index 14bf0717..fb859ece 100644
--- a/packages/taler-wallet-core/src/bank-api-client.ts
+++ b/packages/taler-wallet-core/src/bank-api-client.ts
@@ -120,7 +120,10 @@ export namespace BankApi {
       if (respJson.paytoUri) {
         paytoUri = respJson.paytoUri;
       }
-    } catch (e) {}
+    } catch (e) {
+      logger.error("error trying to parse json from response", e);
+      throw TalerError.fromException(e);
+    }
     return {
       password,
       username,
diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts 
b/packages/taler-wallet-core/src/operations/backup/import.ts
index a0a603ca..16a88fe7 100644
--- a/packages/taler-wallet-core/src/operations/backup/import.ts
+++ b/packages/taler-wallet-core/src/operations/backup/import.ts
@@ -15,54 +15,30 @@
  */
 
 import {
-  BackupPurchase,
   AmountJson,
-  Amounts,
-  BackupDenomSel,
-  WalletBackupContentV1,
-  BackupCoinSourceType,
-  BackupProposalStatus,
-  codecForContractTerms,
-  BackupRefundState,
-  RefreshReason,
-  BackupRefreshReason,
-  DenomKeyType,
-  AbsoluteTime,
-  TalerProtocolTimestamp,
+  Amounts, BackupCoinSourceType, BackupDenomSel, BackupProposalStatus,
+  BackupPurchase, BackupRefreshReason, BackupRefundState, 
codecForContractTerms,
+  DenomKeyType, j2s, Logger, RefreshReason, TalerProtocolTimestamp,
+  WalletBackupContentV1
 } from "@gnu-taler/taler-util";
 import {
-  WalletContractData,
-  DenomSelectionState,
-  DenominationVerificationStatus,
-  CoinSource,
+  AbortStatus, CoinSource,
   CoinSourceType,
-  CoinStatus,
-  ReserveBankInfo,
-  ReserveRecordStatus,
-  ProposalDownload,
-  ProposalStatus,
-  WalletRefundItem,
-  RefundState,
-  AbortStatus,
-  RefreshSessionRecord,
-  WireInfo,
-  WalletStoresV1,
-  RefreshCoinStatus,
-  OperationStatus,
+  CoinStatus, DenominationVerificationStatus, DenomSelectionState, 
OperationStatus, ProposalDownload,
+  ProposalStatus, RefreshCoinStatus, RefreshSessionRecord, RefundState, 
ReserveBankInfo,
+  ReserveRecordStatus, WalletContractData, WalletRefundItem, WalletStoresV1, 
WireInfo
 } from "../../db.js";
+import { InternalWalletState } from "../../internal-wallet-state.js";
 import { PayCoinSelection } from "../../util/coinSelection.js";
-import { j2s } from "@gnu-taler/taler-util";
 import {
   checkDbInvariant,
-  checkLogicInvariant,
+  checkLogicInvariant
 } from "../../util/invariants.js";
-import { Logger } from "@gnu-taler/taler-util";
-import { resetRetryInfo } from "../../util/retries.js";
-import { InternalWalletState } from "../../internal-wallet-state.js";
-import { provideBackupState } from "./state.js";
-import { makeEventId, TombstoneTag } from "../transactions.js";
-import { getExchangeDetails } from "../exchanges.js";
 import { GetReadOnlyAccess, GetReadWriteAccess } from "../../util/query.js";
+import { RetryInfo } from "../../util/retries.js";
+import { getExchangeDetails } from "../exchanges.js";
+import { makeEventId, TombstoneTag } from "../transactions.js";
+import { provideBackupState } from "./state.js";
 
 const logger = new Logger("operations/backup/import.ts");
 
@@ -276,7 +252,7 @@ export async function importBackup(
             protocolVersionRange: backupExchange.protocol_version_range,
           },
           permanent: true,
-          retryInfo: resetRetryInfo(),
+          retryInfo: RetryInfo.reset(),
           lastUpdate: undefined,
           nextUpdate: TalerProtocolTimestamp.now(),
           nextRefreshCheck: TalerProtocolTimestamp.now(),
@@ -464,7 +440,7 @@ export async function importBackup(
               timestampReserveInfoPosted:
                 backupReserve.bank_info?.timestamp_reserve_info_posted,
               senderWire: backupReserve.sender_wire,
-              retryInfo: resetRetryInfo(),
+              retryInfo: RetryInfo.reset(),
               lastError: undefined,
               initialWithdrawalGroupId:
                 backupReserve.initial_withdrawal_group_id,
@@ -505,7 +481,7 @@ export async function importBackup(
                   backupWg.raw_withdrawal_amount,
                 ),
                 reservePub,
-                retryInfo: resetRetryInfo(),
+                retryInfo: RetryInfo.reset(),
                 secretSeed: backupWg.secret_seed,
                 timestampStart: backupWg.timestamp_created,
                 timestampFinish: backupWg.timestamp_finish,
@@ -618,7 +594,7 @@ export async function importBackup(
               cryptoComp.proposalNoncePrivToPub[backupProposal.nonce_priv],
             proposalId: backupProposal.proposal_id,
             repurchaseProposalId: backupProposal.repurchase_proposal_id,
-            retryInfo: resetRetryInfo(),
+            retryInfo: RetryInfo.reset(),
             download,
             proposalStatus,
           });
@@ -753,7 +729,7 @@ export async function importBackup(
               cryptoComp.proposalNoncePrivToPub[backupPurchase.nonce_priv],
             lastPayError: undefined,
             autoRefundDeadline: TalerProtocolTimestamp.never(),
-            refundStatusRetryInfo: resetRetryInfo(),
+            refundStatusRetryInfo: RetryInfo.reset(),
             lastRefundStatusError: undefined,
             refundAwaiting: undefined,
             timestampAccept: backupPurchase.timestamp_accept,
@@ -764,7 +740,7 @@ export async function importBackup(
             lastSessionId: undefined,
             abortStatus,
             // FIXME!
-            payRetryInfo: resetRetryInfo(),
+            payRetryInfo: RetryInfo.reset(),
             download,
             paymentSubmitPending:
               !backupPurchase.timestamp_first_successful_pay,
@@ -865,7 +841,7 @@ export async function importBackup(
               Amounts.parseOrThrow(x.estimated_output_amount),
             ),
             refreshSessionPerCoin,
-            retryInfo: resetRetryInfo(),
+            retryInfo: RetryInfo.reset(),
           });
         }
       }
@@ -891,7 +867,7 @@ export async function importBackup(
             merchantBaseUrl: backupTip.exchange_base_url,
             merchantTipId: backupTip.merchant_tip_id,
             pickedUpTimestamp: backupTip.timestamp_finished,
-            retryInfo: resetRetryInfo(),
+            retryInfo: RetryInfo.reset(),
             secretSeed: backupTip.secret_seed,
             tipAmountEffective: denomsSel.totalCoinValue,
             tipAmountRaw: Amounts.parseOrThrow(backupTip.tip_amount_raw),
diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts 
b/packages/taler-wallet-core/src/operations/backup/index.ts
index 0b2bd7b8..69ba1ddb 100644
--- a/packages/taler-wallet-core/src/operations/backup/index.ts
+++ b/packages/taler-wallet-core/src/operations/backup/index.ts
@@ -25,10 +25,9 @@
  * Imports.
  */
 import {
-  AmountString,
+  AbsoluteTime, AmountString,
   BackupRecovery,
-  buildCodecForObject,
-  canonicalizeBaseUrl,
+  buildCodecForObject, bytesToString, canonicalizeBaseUrl,
   canonicalJson,
   Codec,
   codecForAmountString,
@@ -37,39 +36,22 @@ import {
   codecForNumber,
   codecForString,
   codecOptional,
-  ConfirmPayResultType,
-  DenomKeyType,
-  durationFromSpec,
-  hashDenomPub,
+  ConfirmPayResultType, decodeCrock, DenomKeyType,
+  durationFromSpec, eddsaGetPublic,
+  EddsaKeyPair,
+  encodeCrock,
+  getRandomBytes,
+  hash, hashDenomPub,
   HttpStatusCode,
-  j2s,
-  Logger,
+  j2s, kdf, Logger,
   notEmpty,
   PreparePayResultType,
   RecoveryLoadRequest,
-  RecoveryMergeStrategy,
-  TalerErrorDetail,
-  AbsoluteTime,
-  URL,
-  WalletBackupContentV1,
-  TalerProtocolTimestamp,
+  RecoveryMergeStrategy, rsaBlind, secretbox, secretbox_open, stringToBytes, 
TalerErrorDetail, TalerProtocolTimestamp, URL,
+  WalletBackupContentV1
 } from "@gnu-taler/taler-util";
 import { gunzipSync, gzipSync } from "fflate";
-import { InternalWalletState } from "../../internal-wallet-state.js";
-import { kdf } from "@gnu-taler/taler-util";
-import { secretbox, secretbox_open } from "@gnu-taler/taler-util";
-import {
-  bytesToString,
-  decodeCrock,
-  eddsaGetPublic,
-  EddsaKeyPair,
-  encodeCrock,
-  getRandomBytes,
-  hash,
-  rsaBlind,
-  stringToBytes,
-} from "@gnu-taler/taler-util";
-import { CryptoDispatcher } from "../../crypto/workers/cryptoDispatcher.js";
+import { TalerCryptoInterface } from "../../crypto/cryptoImplementation.js";
 import {
   BackupProviderRecord,
   BackupProviderState,
@@ -78,28 +60,28 @@ import {
   ConfigRecord,
   WalletBackupConfState,
   WalletStoresV1,
-  WALLET_BACKUP_STATE_KEY,
+  WALLET_BACKUP_STATE_KEY
 } from "../../db.js";
+import { InternalWalletState } from "../../internal-wallet-state.js";
 import {
   readSuccessResponseJsonOrThrow,
-  readTalerErrorResponse,
+  readTalerErrorResponse
 } from "../../util/http.js";
 import {
   checkDbInvariant,
-  checkLogicInvariant,
+  checkLogicInvariant
 } from "../../util/invariants.js";
 import { GetReadWriteAccess } from "../../util/query.js";
-import { resetRetryInfo, updateRetryInfoTimeout } from "../../util/retries.js";
+import { RetryInfo } from "../../util/retries.js";
+import { guardOperationException } from "../common.js";
 import {
   checkPaymentByProposalId,
   confirmPay,
-  preparePayForUri,
+  preparePayForUri
 } from "../pay.js";
 import { exportBackup } from "./export.js";
 import { BackupCryptoPrecomputedData, importBackup } from "./import.js";
 import { getWalletBackupState, provideBackupState } from "./state.js";
-import { guardOperationException } from "../common.js";
-import { TalerCryptoInterface } from "../../crypto/cryptoImplementation.js";
 
 const logger = new Logger("operations/backup.ts");
 
@@ -309,8 +291,8 @@ async function runBackupCycleForProvider(
       "if-none-match": newHash,
       ...(provider.lastBackupHash
         ? {
-            "if-match": provider.lastBackupHash,
-          }
+          "if-match": provider.lastBackupHash,
+        }
         : {}),
     },
   });
@@ -344,7 +326,7 @@ async function runBackupCycleForProvider(
     }
     const res = await preparePayForUri(ws, talerUri);
     let proposalId = res.proposalId;
-    let doPay: boolean = false;
+    let doPay = false;
     switch (res.status) {
       case PreparePayResultType.InsufficientBalance:
         // FIXME: record in provider state!
@@ -434,7 +416,7 @@ async function runBackupCycleForProvider(
         // FIXME:  Allocate error code for this situation?
         prov.state = {
           tag: BackupProviderStateTag.Retrying,
-          retryInfo: resetRetryInfo(),
+          retryInfo: RetryInfo.reset(),
         };
         await tx.backupProvider.put(prov);
       });
@@ -472,13 +454,12 @@ async function incrementBackupRetryInTx(
     return;
   }
   if (pr.state.tag === BackupProviderStateTag.Retrying) {
-    pr.state.retryInfo.retryCounter++;
     pr.state.lastError = err;
-    updateRetryInfoTimeout(pr.state.retryInfo);
+    pr.state.retryInfo = RetryInfo.increment(pr.state.retryInfo);
   } else if (pr.state.tag === BackupProviderStateTag.Ready) {
     pr.state = {
       tag: BackupProviderStateTag.Retrying,
-      retryInfo: resetRetryInfo(),
+      retryInfo: RetryInfo.reset(),
       lastError: err,
     };
   }
@@ -685,7 +666,9 @@ export async function addBackupProvider(
     });
 }
 
-export async function restoreFromRecoverySecret(): Promise<void> {}
+export async function restoreFromRecoverySecret(): Promise<void> {
+  return;
+}
 
 /**
  * Information about one provider.
diff --git a/packages/taler-wallet-core/src/operations/deposits.ts 
b/packages/taler-wallet-core/src/operations/deposits.ts
index 2f5f9aa1..27460849 100644
--- a/packages/taler-wallet-core/src/operations/deposits.ts
+++ b/packages/taler-wallet-core/src/operations/deposits.ts
@@ -47,7 +47,7 @@ import { DepositGroupRecord, OperationStatus, WireFee } from 
"../db.js";
 import { InternalWalletState } from "../internal-wallet-state.js";
 import { PayCoinSelection, selectPayCoins } from "../util/coinSelection.js";
 import { readSuccessResponseJsonOrThrow } from "../util/http.js";
-import { resetRetryInfo, RetryInfo } from "../util/retries.js";
+import { RetryInfo } from "../util/retries.js";
 import { guardOperationException } from "./common.js";
 import { getExchangeDetails } from "./exchanges.js";
 import {
@@ -85,7 +85,7 @@ async function setupDepositGroupRetry(
         return;
       }
       if (options.resetRetry) {
-        x.retryInfo = resetRetryInfo();
+        x.retryInfo = RetryInfo.reset();
       } else {
         x.retryInfo = RetryInfo.increment(x.retryInfo);
       }
@@ -599,7 +599,7 @@ export async function createDepositGroup(
       payto_uri: req.depositPaytoUri,
       salt: wireSalt,
     },
-    retryInfo: resetRetryInfo(),
+    retryInfo: RetryInfo.reset(),
     operationStatus: OperationStatus.Pending,
     lastError: undefined,
   };
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts 
b/packages/taler-wallet-core/src/operations/exchanges.ts
index 72cbdc15..b10505b2 100644
--- a/packages/taler-wallet-core/src/operations/exchanges.ts
+++ b/packages/taler-wallet-core/src/operations/exchanges.ts
@@ -63,7 +63,7 @@ import {
   readSuccessResponseTextOrThrow,
 } from "../util/http.js";
 import { DbAccess, GetReadOnlyAccess } from "../util/query.js";
-import { resetRetryInfo, RetryInfo } from "../util/retries.js";
+import { RetryInfo } from "../util/retries.js";
 import {
   WALLET_CACHE_BREAKER_CLIENT_VERSION,
   WALLET_EXCHANGE_PROTOCOL_VERSION,
@@ -116,6 +116,9 @@ async function reportExchangeUpdateError(
       if (!exchange) {
         return;
       }
+      if (!exchange.retryInfo) {
+        logger.reportBreak();
+      }
       exchange.lastError = err;
       await tx.exchanges.put(exchange);
     });
@@ -137,7 +140,7 @@ async function setupExchangeUpdateRetry(
         return;
       }
       if (options.reset) {
-        exchange.retryInfo = resetRetryInfo();
+        exchange.retryInfo = RetryInfo.reset();
       } else {
         exchange.retryInfo = RetryInfo.increment(exchange.retryInfo);
       }
@@ -399,7 +402,7 @@ async function provideExchangeRecord(
         const r: ExchangeRecord = {
           permanent: true,
           baseUrl: baseUrl,
-          retryInfo: resetRetryInfo(),
+          retryInfo: RetryInfo.reset(),
           detailsPointer: undefined,
           lastUpdate: undefined,
           nextUpdate: AbsoluteTime.toTimestamp(now),
diff --git a/packages/taler-wallet-core/src/operations/pay.ts 
b/packages/taler-wallet-core/src/operations/pay.ts
index 325d07bd..ceba7ef8 100644
--- a/packages/taler-wallet-core/src/operations/pay.ts
+++ b/packages/taler-wallet-core/src/operations/pay.ts
@@ -97,10 +97,7 @@ import {
 } from "../util/http.js";
 import { GetReadWriteAccess } from "../util/query.js";
 import {
-  getRetryDuration,
-  resetRetryInfo,
   RetryInfo,
-  updateRetryInfoTimeout,
 } from "../util/retries.js";
 import { getExchangeDetails } from "./exchanges.js";
 import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
@@ -438,8 +435,8 @@ async function recordConfirmPay(
     proposalId: proposal.proposalId,
     lastPayError: undefined,
     lastRefundStatusError: undefined,
-    payRetryInfo: resetRetryInfo(),
-    refundStatusRetryInfo: resetRetryInfo(),
+    payRetryInfo: RetryInfo.reset(),
+    refundStatusRetryInfo: RetryInfo.reset(),
     refundQueryRequested: false,
     timestampFirstSuccessfulPay: undefined,
     autoRefundDeadline: undefined,
@@ -494,6 +491,7 @@ async function reportProposalError(
         logger.error(
           `Asked to report an error for a proposal (${proposalId}) that is not 
active (no retryInfo)`,
         );
+        logger.reportBreak();
         return;
       }
       pr.lastError = err;
@@ -517,7 +515,7 @@ async function setupProposalRetry(
         return;
       }
       if (options.reset) {
-        pr.retryInfo = resetRetryInfo();
+        pr.retryInfo = RetryInfo.reset();
       } else {
         pr.retryInfo = RetryInfo.increment(pr.retryInfo);
       }
@@ -541,7 +539,7 @@ async function setupPurchasePayRetry(
         return;
       }
       if (options.reset) {
-        p.payRetryInfo = resetRetryInfo();
+        p.payRetryInfo = RetryInfo.reset();
       } else {
         p.payRetryInfo = RetryInfo.increment(p.payRetryInfo);
       }
@@ -610,7 +608,7 @@ async function failProposalPermanently(
 function getProposalRequestTimeout(proposal: ProposalRecord): Duration {
   return durationMax(
     { d_ms: 60000 },
-    durationMin({ d_ms: 5000 }, getRetryDuration(proposal.retryInfo)),
+    durationMin({ d_ms: 5000 }, RetryInfo.getDuration(proposal.retryInfo)),
   );
 }
 
@@ -938,7 +936,7 @@ async function startDownloadProposal(
     proposalId: proposalId,
     proposalStatus: ProposalStatus.Downloading,
     repurchaseProposalId: undefined,
-    retryInfo: resetRetryInfo(),
+    retryInfo: RetryInfo.reset(),
     lastError: undefined,
     downloadSessionId: sessionId,
   };
@@ -986,14 +984,14 @@ async function storeFirstPaySuccess(
       purchase.paymentSubmitPending = false;
       purchase.lastPayError = undefined;
       purchase.lastSessionId = sessionId;
-      purchase.payRetryInfo = resetRetryInfo();
+      purchase.payRetryInfo = RetryInfo.reset();
       purchase.merchantPaySig = paySig;
       const protoAr = purchase.download.contractData.autoRefund;
       if (protoAr) {
         const ar = Duration.fromTalerProtocolDuration(protoAr);
         logger.info("auto_refund present");
         purchase.refundQueryRequested = true;
-        purchase.refundStatusRetryInfo = resetRetryInfo();
+        purchase.refundStatusRetryInfo = RetryInfo.reset();
         purchase.lastRefundStatusError = undefined;
         purchase.autoRefundDeadline = AbsoluteTime.toTimestamp(
           AbsoluteTime.addDuration(AbsoluteTime.now(), ar),
@@ -1023,7 +1021,7 @@ async function storePayReplaySuccess(
       }
       purchase.paymentSubmitPending = false;
       purchase.lastPayError = undefined;
-      purchase.payRetryInfo = resetRetryInfo();
+      purchase.payRetryInfo = RetryInfo.reset();
       purchase.lastSessionId = sessionId;
       await tx.purchases.put(purchase);
     });
diff --git a/packages/taler-wallet-core/src/operations/recoup.ts 
b/packages/taler-wallet-core/src/operations/recoup.ts
index 4fac2ec1..d36a1028 100644
--- a/packages/taler-wallet-core/src/operations/recoup.ts
+++ b/packages/taler-wallet-core/src/operations/recoup.ts
@@ -26,38 +26,28 @@
  */
 import {
   Amounts,
-  codecForRecoupConfirmation,
-  j2s,
-  NotificationType,
+  codecForRecoupConfirmation, encodeCrock, getRandomBytes, j2s, Logger, 
NotificationType,
   RefreshReason,
   TalerErrorDetail,
-  TalerProtocolTimestamp,
+  TalerProtocolTimestamp, URL
 } from "@gnu-taler/taler-util";
-import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
 import {
   CoinRecord,
   CoinSourceType,
-  CoinStatus,
-  RecoupGroupRecord,
+  CoinStatus, OperationStatus, RecoupGroupRecord,
   RefreshCoinSource,
-  ReserveRecordStatus,
-  WithdrawCoinSource,
-  WalletStoresV1,
-  OperationStatus,
+  ReserveRecordStatus, WalletStoresV1, WithdrawCoinSource
 } from "../db.js";
-
+import { InternalWalletState } from "../internal-wallet-state.js";
 import { readSuccessResponseJsonOrThrow } from "../util/http.js";
-import { Logger, URL } from "@gnu-taler/taler-util";
+import { GetReadWriteAccess } from "../util/query.js";
 import {
-  resetRetryInfo,
-  RetryInfo,
-  updateRetryInfoTimeout,
+  RetryInfo
 } from "../util/retries.js";
+import { guardOperationException } from "./common.js";
 import { createRefreshGroup, processRefreshGroup } from "./refresh.js";
 import { getReserveRequestTimeout, processReserve } from "./reserves.js";
-import { InternalWalletState } from "../internal-wallet-state.js";
-import { GetReadWriteAccess } from "../util/query.js";
-import { guardOperationException } from "./common.js";
+
 
 const logger = new Logger("operations/recoup.ts");
 
@@ -78,7 +68,7 @@ async function setupRecoupRetry(
         return;
       }
       if (options.reset) {
-        r.retryInfo = resetRetryInfo();
+        r.retryInfo = RetryInfo.reset();
       } else {
         r.retryInfo = RetryInfo.increment(r.retryInfo);
       }
@@ -139,7 +129,7 @@ async function putGroupAsFinished(
   if (allFinished) {
     logger.info("all recoups of recoup group are finished");
     recoupGroup.timestampFinished = TalerProtocolTimestamp.now();
-    recoupGroup.retryInfo = resetRetryInfo();
+    recoupGroup.retryInfo = RetryInfo.reset();
     recoupGroup.lastError = undefined;
     if (recoupGroup.scheduleRefreshCoins.length > 0) {
       const refreshGroupId = await createRefreshGroup(
@@ -278,7 +268,7 @@ async function recoupWithdrawCoin(
       const currency = updatedCoin.currentAmount.currency;
       updatedCoin.currentAmount = Amounts.getZero(currency);
       updatedReserve.reserveStatus = ReserveRecordStatus.QueryingStatus;
-      updatedReserve.retryInfo = resetRetryInfo();
+      updatedReserve.retryInfo = RetryInfo.reset();
       updatedReserve.operationStatus = OperationStatus.Pending;
       await tx.coins.put(updatedCoin);
       await tx.reserves.put(updatedReserve);
@@ -482,7 +472,7 @@ export async function createRecoupGroup(
     lastError: undefined,
     timestampFinished: undefined,
     timestampStarted: TalerProtocolTimestamp.now(),
-    retryInfo: resetRetryInfo(),
+    retryInfo: RetryInfo.reset(),
     recoupFinishedPerCoin: coinPubs.map(() => false),
     // Will be populated later
     oldAmountPerCoin: [],
diff --git a/packages/taler-wallet-core/src/operations/refresh.ts 
b/packages/taler-wallet-core/src/operations/refresh.ts
index 21567611..ce8fd003 100644
--- a/packages/taler-wallet-core/src/operations/refresh.ts
+++ b/packages/taler-wallet-core/src/operations/refresh.ts
@@ -15,20 +15,28 @@
  */
 
 import {
-  AgeCommitment,
-  AgeRestriction,
-  CoinPublicKeyString,
-  DenomKeyType,
-  encodeCrock,
+  AbsoluteTime, AgeCommitment,
+  AgeRestriction, AmountJson, Amounts, amountToPretty, 
codecForExchangeMeltResponse,
+  codecForExchangeRevealResponse,
+  CoinPublicKey, CoinPublicKeyString,
+  DenomKeyType, Duration,
+  durationFromSpec,
+  durationMul, encodeCrock,
   ExchangeMeltRequest,
-  ExchangeProtocolVersion,
-  ExchangeRefreshRevealRequest,
-  getRandomBytes,
+  ExchangeProtocolVersion, ExchangeRefreshRevealRequest, fnutil, 
getRandomBytes,
   HashCodeString,
   HttpStatusCode,
-  j2s,
-  TalerProtocolTimestamp,
+  j2s, Logger, NotificationType,
+  RefreshGroupId,
+  RefreshReason,
+  TalerErrorDetail, TalerProtocolTimestamp, URL
 } from "@gnu-taler/taler-util";
+import { TalerCryptoInterface } from "../crypto/cryptoImplementation.js";
+import {
+  DerivedRefreshSession,
+  RefreshNewDenomInfo
+} from "../crypto/cryptoTypes.js";
+import { CryptoApiStoppedError } from "../crypto/workers/cryptoDispatcher.js";
 import {
   CoinRecord,
   CoinSourceType,
@@ -37,57 +45,29 @@ import {
   OperationStatus,
   RefreshCoinStatus,
   RefreshGroupRecord,
-  WalletStoresV1,
+  WalletStoresV1
 } from "../db.js";
+import { TalerError } from "../errors.js";
 import {
-  codecForExchangeMeltResponse,
-  codecForExchangeRevealResponse,
-  CoinPublicKey,
-  fnutil,
-  NotificationType,
-  RefreshGroupId,
-  RefreshReason,
-  TalerErrorDetail,
-} from "@gnu-taler/taler-util";
-import { AmountJson, Amounts } from "@gnu-taler/taler-util";
-import { amountToPretty } from "@gnu-taler/taler-util";
+  DenomInfo,
+  EXCHANGE_COINS_LOCK,
+  InternalWalletState
+} from "../internal-wallet-state.js";
 import {
   readSuccessResponseJsonOrThrow,
-  readUnexpectedResponseDetails,
+  readUnexpectedResponseDetails
 } from "../util/http.js";
 import { checkDbInvariant } from "../util/invariants.js";
-import { Logger } from "@gnu-taler/taler-util";
+import { GetReadWriteAccess } from "../util/query.js";
 import {
-  resetRetryInfo,
-  RetryInfo,
-  updateRetryInfoTimeout,
+  RetryInfo
 } from "../util/retries.js";
-import {
-  Duration,
-  durationFromSpec,
-  durationMul,
-  AbsoluteTime,
-  URL,
-} from "@gnu-taler/taler-util";
+import { guardOperationException } from "./common.js";
 import { updateExchangeFromUrl } from "./exchanges.js";
-import {
-  DenomInfo,
-  EXCHANGE_COINS_LOCK,
-  InternalWalletState,
-} from "../internal-wallet-state.js";
 import {
   isWithdrawableDenom,
-  selectWithdrawalDenominations,
+  selectWithdrawalDenominations
 } from "./withdraw.js";
-import {
-  DerivedRefreshSession,
-  RefreshNewDenomInfo,
-} from "../crypto/cryptoTypes.js";
-import { GetReadWriteAccess } from "../util/query.js";
-import { guardOperationException } from "./common.js";
-import { CryptoApiStoppedError } from "../crypto/workers/cryptoDispatcher.js";
-import { TalerCryptoInterface } from "../crypto/cryptoImplementation.js";
-import { TalerError } from "../errors.js";
 
 const logger = new Logger("refresh.ts");
 
@@ -129,22 +109,22 @@ export function getTotalRefreshCost(
 }
 
 function updateGroupStatus(rg: RefreshGroupRecord): void {
-  let allDone = fnutil.all(
+  const allDone = fnutil.all(
     rg.statusPerCoin,
     (x) => x === RefreshCoinStatus.Finished || x === RefreshCoinStatus.Frozen,
   );
-  let anyFrozen = fnutil.any(
+  const anyFrozen = fnutil.any(
     rg.statusPerCoin,
     (x) => x === RefreshCoinStatus.Frozen,
   );
   if (allDone) {
     if (anyFrozen) {
       rg.frozen = true;
-      rg.retryInfo = resetRetryInfo();
+      rg.retryInfo = RetryInfo.reset();
     } else {
       rg.timestampFinished = AbsoluteTime.toTimestamp(AbsoluteTime.now());
       rg.operationStatus = OperationStatus.Finished;
-      rg.retryInfo = resetRetryInfo();
+      rg.retryInfo = RetryInfo.reset();
     }
   }
 }
@@ -753,7 +733,7 @@ async function setupRefreshRetry(
         return;
       }
       if (options.reset) {
-        r.retryInfo = resetRetryInfo();
+        r.retryInfo = RetryInfo.reset();
       } else {
         r.retryInfo = RetryInfo.increment(r.retryInfo);
       }
@@ -987,7 +967,7 @@ export async function createRefreshGroup(
     reason,
     refreshGroupId,
     refreshSessionPerCoin: oldCoinPubs.map(() => undefined),
-    retryInfo: resetRetryInfo(),
+    retryInfo: RetryInfo.reset(),
     inputPerCoin,
     estimatedOutputPerCoin,
     timestampCreated: TalerProtocolTimestamp.now(),
diff --git a/packages/taler-wallet-core/src/operations/refund.ts 
b/packages/taler-wallet-core/src/operations/refund.ts
index e5ce37a8..186fbf7d 100644
--- a/packages/taler-wallet-core/src/operations/refund.ts
+++ b/packages/taler-wallet-core/src/operations/refund.ts
@@ -25,29 +25,18 @@
  */
 import {
   AbortingCoin,
-  AbortRequest,
-  AmountJson,
+  AbortRequest, AbsoluteTime, AmountJson,
   Amounts,
   ApplyRefundResponse,
   codecForAbortResponse,
-  codecForMerchantOrderRefundPickupResponse,
-  CoinPublicKey,
-  Logger,
+  codecForMerchantOrderRefundPickupResponse, codecForMerchantOrderStatusPaid, 
CoinPublicKey, Duration, Logger,
   MerchantCoinRefundFailureStatus,
   MerchantCoinRefundStatus,
   MerchantCoinRefundSuccessStatus,
   NotificationType,
-  parseRefundUri,
-  RefreshReason,
+  parseRefundUri, PrepareRefundResult, RefreshReason,
   TalerErrorCode,
-  TalerErrorDetail,
-  URL,
-  codecForMerchantOrderStatusPaid,
-  AbsoluteTime,
-  TalerProtocolTimestamp,
-  Duration,
-  PrepareRefundRequest,
-  PrepareRefundResult,
+  TalerErrorDetail, TalerProtocolTimestamp, URL
 } from "@gnu-taler/taler-util";
 import {
   AbortStatus,
@@ -55,19 +44,17 @@ import {
   PurchaseRecord,
   RefundReason,
   RefundState,
-  WalletStoresV1,
+  WalletStoresV1
 } 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 {
-  resetRetryInfo,
-  RetryInfo,
-  updateRetryInfoTimeout,
+  RetryInfo
 } from "../util/retries.js";
-import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
-import { InternalWalletState } from "../internal-wallet-state.js";
 import { guardOperationException } from "./common.js";
+import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
 
 const logger = new Logger("refund.ts");
 
@@ -147,7 +134,7 @@ async function setupPurchaseQueryRefundRetry(
         return;
       }
       if (options.reset) {
-        pr.refundStatusRetryInfo = resetRetryInfo();
+        pr.refundStatusRetryInfo = RetryInfo.reset();
       } else {
         pr.refundStatusRetryInfo = RetryInfo.increment(
           pr.refundStatusRetryInfo,
@@ -500,7 +487,7 @@ async function acceptRefunds(
       if (queryDone) {
         p.timestampLastRefundStatus = now;
         p.lastRefundStatusError = undefined;
-        p.refundStatusRetryInfo = resetRetryInfo();
+        p.refundStatusRetryInfo = RetryInfo.reset();
         p.refundQueryRequested = false;
         if (p.abortStatus === AbortStatus.AbortRefund) {
           p.abortStatus = AbortStatus.AbortFinished;
@@ -509,8 +496,7 @@ async function acceptRefunds(
       } else {
         // No error, but we need to try again!
         p.timestampLastRefundStatus = now;
-        p.refundStatusRetryInfo.retryCounter++;
-        updateRetryInfoTimeout(p.refundStatusRetryInfo);
+        p.refundStatusRetryInfo = RetryInfo.increment(p.refundStatusRetryInfo)
         p.lastRefundStatusError = undefined;
         logger.trace("refund query not done");
       }
@@ -619,7 +605,7 @@ export async function applyRefund(
       }
       p.refundQueryRequested = true;
       p.lastRefundStatusError = undefined;
-      p.refundStatusRetryInfo = resetRetryInfo();
+      p.refundStatusRetryInfo = RetryInfo.reset();
       await tx.purchases.put(p);
       return true;
     });
@@ -892,7 +878,7 @@ export async function abortFailedPayWithRefund(
       purchase.paymentSubmitPending = false;
       purchase.abortStatus = AbortStatus.AbortRefund;
       purchase.lastPayError = undefined;
-      purchase.payRetryInfo = resetRetryInfo();
+      purchase.payRetryInfo = RetryInfo.reset();
       await tx.purchases.put(purchase);
     });
   processPurchaseQueryRefund(ws, proposalId, {
diff --git a/packages/taler-wallet-core/src/operations/reserves.ts 
b/packages/taler-wallet-core/src/operations/reserves.ts
index 8e606bd6..8ee620d9 100644
--- a/packages/taler-wallet-core/src/operations/reserves.ts
+++ b/packages/taler-wallet-core/src/operations/reserves.ts
@@ -58,8 +58,6 @@ import {
 } from "../util/http.js";
 import { GetReadOnlyAccess } from "../util/query.js";
 import {
-  getRetryDuration,
-  resetRetryInfo,
   RetryInfo,
 } from "../util/retries.js";
 import {
@@ -100,7 +98,7 @@ async function setupReserveRetry(
         return;
       }
       if (options.reset) {
-        r.retryInfo = resetRetryInfo();
+        r.retryInfo = RetryInfo.reset();
       } else {
         r.retryInfo = RetryInfo.increment(r.retryInfo);
       }
@@ -196,7 +194,7 @@ export async function createReserve(
     timestampReserveInfoPosted: undefined,
     bankInfo,
     reserveStatus,
-    retryInfo: resetRetryInfo(),
+    retryInfo: RetryInfo.reset(),
     lastError: undefined,
     currency: req.amount.currency,
     operationStatus: OperationStatus.Pending,
@@ -297,7 +295,7 @@ export async function forceQueryReserve(
         case ReserveRecordStatus.Dormant:
           reserve.reserveStatus = ReserveRecordStatus.QueryingStatus;
           reserve.operationStatus = OperationStatus.Pending;
-          reserve.retryInfo = resetRetryInfo();
+          reserve.retryInfo = RetryInfo.reset();
           break;
         default:
           break;
@@ -392,7 +390,7 @@ async function registerReserveWithBank(
       if (!r.bankInfo) {
         throw Error("invariant failed");
       }
-      r.retryInfo = resetRetryInfo();
+      r.retryInfo = RetryInfo.reset();
       await tx.reserves.put(r);
     });
   ws.notify({ type: NotificationType.ReserveRegisteredWithBank });
@@ -402,7 +400,7 @@ async function registerReserveWithBank(
 export function getReserveRequestTimeout(r: ReserveRecord): Duration {
   return durationMax(
     { d_ms: 60000 },
-    durationMin({ d_ms: 5000 }, getRetryDuration(r.retryInfo)),
+    durationMin({ d_ms: 5000 }, RetryInfo.getDuration(r.retryInfo)),
   );
 }
 
@@ -459,7 +457,7 @@ async function processReserveBankStatus(
         r.timestampBankConfirmed = now;
         r.reserveStatus = ReserveRecordStatus.BankAborted;
         r.operationStatus = OperationStatus.Finished;
-        r.retryInfo = resetRetryInfo();
+        r.retryInfo = RetryInfo.reset();
         await tx.reserves.put(r);
       });
     return;
@@ -496,7 +494,7 @@ async function processReserveBankStatus(
         r.timestampBankConfirmed = now;
         r.reserveStatus = ReserveRecordStatus.QueryingStatus;
         r.operationStatus = OperationStatus.Pending;
-        r.retryInfo = resetRetryInfo();
+        r.retryInfo = RetryInfo.reset();
       } else {
         switch (r.reserveStatus) {
           case ReserveRecordStatus.WaitConfirmBank:
@@ -555,7 +553,7 @@ async function updateReserve(
     if (
       resp.status === 404 &&
       result.talerErrorResponse.code ===
-        TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN
+      TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN
     ) {
       ws.notify({
         type: NotificationType.ReserveNotYetFound,
@@ -662,7 +660,7 @@ async function updateReserve(
         reservePub: reserve.reservePub,
         rawWithdrawalAmount: remainingAmount,
         timestampStart: AbsoluteTime.toTimestamp(AbsoluteTime.now()),
-        retryInfo: resetRetryInfo(),
+        retryInfo: RetryInfo.reset(),
         lastError: undefined,
         denomsSel: denomSel,
         secretSeed: encodeCrock(getRandomBytes(64)),
@@ -721,12 +719,13 @@ async function processReserveImpl(
     case ReserveRecordStatus.RegisteringBank:
       await processReserveBankStatus(ws, reservePub);
       return await processReserveImpl(ws, reservePub, { forceNow: true });
-    case ReserveRecordStatus.QueryingStatus:
+    case ReserveRecordStatus.QueryingStatus: {
       const res = await updateReserve(ws, reservePub);
       if (res.ready) {
         return await processReserveImpl(ws, reservePub, { forceNow: true });
       }
       break;
+    }
     case ReserveRecordStatus.Dormant:
       // nothing to do
       break;
diff --git a/packages/taler-wallet-core/src/operations/tip.ts 
b/packages/taler-wallet-core/src/operations/tip.ts
index c0dcae91..da7673f3 100644
--- a/packages/taler-wallet-core/src/operations/tip.ts
+++ b/packages/taler-wallet-core/src/operations/tip.ts
@@ -18,51 +18,30 @@
  * Imports.
  */
 import {
-  PrepareTipResult,
-  parseTipUri,
-  codecForTipPickupGetResponse,
-  Amounts,
-  TalerErrorDetail,
-  NotificationType,
-  TipPlanchetDetail,
-  TalerErrorCode,
-  Logger,
-  URL,
-  DenomKeyType,
-  BlindedDenominationSignature,
-  codecForMerchantTipResponseV2,
-  TalerProtocolTimestamp,
+  Amounts, BlindedDenominationSignature,
+  codecForMerchantTipResponseV2, codecForTipPickupGetResponse, DenomKeyType, 
encodeCrock, getRandomBytes, j2s, Logger, NotificationType, parseTipUri, 
PrepareTipResult, TalerErrorCode, TalerErrorDetail, TalerProtocolTimestamp, 
TipPlanchetDetail, URL
 } from "@gnu-taler/taler-util";
 import { DerivedTipPlanchet } from "../crypto/cryptoTypes.js";
 import {
-  DenominationRecord,
   CoinRecord,
   CoinSourceType,
-  CoinStatus,
-  TipRecord,
+  CoinStatus, DenominationRecord, TipRecord
 } from "../db.js";
-import { j2s } from "@gnu-taler/taler-util";
-import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
-import {
-  resetRetryInfo,
-  RetryInfo,
-  updateRetryInfoTimeout,
-} from "../util/retries.js";
 import { makeErrorDetail } from "../errors.js";
-import { updateExchangeFromUrl } from "./exchanges.js";
 import { InternalWalletState } from "../internal-wallet-state.js";
-import {
-  getExchangeWithdrawalInfo,
-  updateWithdrawalDenoms,
-  getCandidateWithdrawalDenoms,
-  selectWithdrawalDenominations,
-} from "./withdraw.js";
 import {
   getHttpResponseErrorDetails,
-  readSuccessResponseJsonOrThrow,
+  readSuccessResponseJsonOrThrow
 } from "../util/http.js";
-import { encodeCrock, getRandomBytes } from "@gnu-taler/taler-util";
+import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
+import {
+  RetryInfo
+} from "../util/retries.js";
 import { guardOperationException } from "./common.js";
+import { updateExchangeFromUrl } from "./exchanges.js";
+import {
+  getCandidateWithdrawalDenoms, getExchangeWithdrawalInfo, 
selectWithdrawalDenominations, updateWithdrawalDenoms
+} from "./withdraw.js";
 
 const logger = new Logger("operations/tip.ts");
 
@@ -130,7 +109,7 @@ export async function prepareTip(
       createdTimestamp: TalerProtocolTimestamp.now(),
       merchantTipId: res.merchantTipId,
       tipAmountEffective: selectedDenoms.totalCoinValue,
-      retryInfo: resetRetryInfo(),
+      retryInfo: RetryInfo.reset(),
       lastError: undefined,
       denomsSel: selectedDenoms,
       pickedUpTimestamp: undefined,
@@ -202,7 +181,7 @@ async function setupTipRetry(
         return;
       }
       if (options.reset) {
-        t.retryInfo = resetRetryInfo();
+        t.retryInfo = RetryInfo.reset();
       } else {
         t.retryInfo = RetryInfo.increment(t.retryInfo);
       }
@@ -237,7 +216,7 @@ async function resetTipRetry(
     .runReadWrite(async (tx) => {
       const x = await tx.tips.get(tipId);
       if (x) {
-        x.retryInfo = resetRetryInfo();
+        x.retryInfo = RetryInfo.reset();
         await tx.tips.put(x);
       }
     });
@@ -430,7 +409,7 @@ async function processTipImpl(
       }
       tr.pickedUpTimestamp = TalerProtocolTimestamp.now();
       tr.lastError = undefined;
-      tr.retryInfo = resetRetryInfo();
+      tr.retryInfo = RetryInfo.reset();
       await tx.tips.put(tr);
       for (const cr of newCoinRecords) {
         await tx.coins.put(cr);
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts 
b/packages/taler-wallet-core/src/operations/withdraw.ts
index 2edc3ed9..ea9e2233 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -72,7 +72,7 @@ import {
   readSuccessResponseJsonOrThrow,
 } from "../util/http.js";
 import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
-import { resetRetryInfo, RetryInfo } from "../util/retries.js";
+import { RetryInfo } from "../util/retries.js";
 import {
   WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
   WALLET_EXCHANGE_PROTOCOL_VERSION,
@@ -215,7 +215,7 @@ export function selectWithdrawalDenominations(
   for (const d of denoms) {
     let count = 0;
     const cost = Amounts.add(d.value, d.feeWithdraw).amount;
-    for (;;) {
+    for (; ;) {
       if (Amounts.cmp(remaining, cost) < 0) {
         break;
       }
@@ -875,11 +875,10 @@ export async function updateWithdrawalDenoms(
         denom.verificationStatus === DenominationVerificationStatus.Unverified
       ) {
         logger.trace(
-          `Validating denomination (${current + 1}/${
-            denominations.length
+          `Validating denomination (${current + 1}/${denominations.length
           }) signature of ${denom.denomPubHash}`,
         );
-        let valid: boolean = false;
+        let valid = false;
         if (ws.insecureTrustExchange) {
           valid = true;
         } else {
@@ -932,7 +931,7 @@ async function setupWithdrawalRetry(
         return;
       }
       if (options.reset) {
-        wsr.retryInfo = resetRetryInfo();
+        wsr.retryInfo = RetryInfo.reset();
       } else {
         wsr.retryInfo = RetryInfo.increment(wsr.retryInfo);
       }
@@ -1097,7 +1096,7 @@ async function processWithdrawGroupImpl(
         wg.timestampFinish = TalerProtocolTimestamp.now();
         wg.operationStatus = OperationStatus.Finished;
         delete wg.lastError;
-        wg.retryInfo = resetRetryInfo();
+        wg.retryInfo = RetryInfo.reset();
       }
 
       await tx.withdrawalGroups.put(wg);
@@ -1203,7 +1202,7 @@ export async function getExchangeWithdrawalInfo(
     ) {
       console.warn(
         `wallet's support for exchange protocol version 
${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` +
-          `(exchange has ${exchangeDetails.protocolVersion}), checking for 
updates`,
+        `(exchange has ${exchangeDetails.protocolVersion}), checking for 
updates`,
       );
     }
   }
diff --git a/packages/taler-wallet-core/src/util/retries.ts 
b/packages/taler-wallet-core/src/util/retries.ts
index 8b7d6440..965ba033 100644
--- a/packages/taler-wallet-core/src/util/retries.ts
+++ b/packages/taler-wallet-core/src/util/retries.ts
@@ -41,7 +41,7 @@ const defaultRetryPolicy: RetryPolicy = {
   maxTimeout: { d_ms: 6000 },
 };
 
-export function updateRetryInfoTimeout(
+function updateTimeout(
   r: RetryInfo,
   p: RetryPolicy = defaultRetryPolicy,
 ): void {
@@ -65,45 +65,46 @@ export function updateRetryInfoTimeout(
   r.nextRetry = { t_ms: t };
 }
 
-export function getRetryDuration(
-  r: RetryInfo | undefined,
-  p: RetryPolicy = defaultRetryPolicy,
-): Duration {
-  if (!r) {
-    // If we don't have any retry info, run immediately.
-    return { d_ms: 0 };
-  }
-  if (p.backoffDelta.d_ms === "forever") {
-    return { d_ms: "forever" };
+export namespace RetryInfo {
+
+  export function getDuration(
+    r: RetryInfo | undefined,
+    p: RetryPolicy = defaultRetryPolicy,
+  ): Duration {
+    if (!r) {
+      // If we don't have any retry info, run immediately.
+      return { d_ms: 0 };
+    }
+    if (p.backoffDelta.d_ms === "forever") {
+      return { d_ms: "forever" };
+    }
+    const t = p.backoffDelta.d_ms * Math.pow(p.backoffBase, r.retryCounter);
+    return {
+      d_ms: p.maxTimeout.d_ms === "forever" ? t : Math.min(p.maxTimeout.d_ms, 
t),
+    };
   }
-  const t = p.backoffDelta.d_ms * Math.pow(p.backoffBase, r.retryCounter);
-  return {
-    d_ms: p.maxTimeout.d_ms === "forever" ? t : Math.min(p.maxTimeout.d_ms, t),
-  };
-}
 
-export function resetRetryInfo(p: RetryPolicy = defaultRetryPolicy): RetryInfo 
{
-  const now = AbsoluteTime.now();
-  const info = {
-    firstTry: now,
-    nextRetry: now,
-    retryCounter: 0,
-  };
-  updateRetryInfoTimeout(info, p);
-  return info;
-}
+  export function reset(p: RetryPolicy = defaultRetryPolicy): RetryInfo {
+    const now = AbsoluteTime.now();
+    const info = {
+      firstTry: now,
+      nextRetry: now,
+      retryCounter: 0,
+    };
+    updateTimeout(info, p);
+    return info;
+  }
 
-export namespace RetryInfo {
   export function increment(
     r: RetryInfo | undefined,
     p: RetryPolicy = defaultRetryPolicy,
-  ) {
+  ): RetryInfo {
     if (!r) {
-      return resetRetryInfo(p);
+      return reset(p);
     }
     const r2 = { ...r };
     r2.retryCounter++;
-    updateRetryInfoTimeout(r2, p);
+    updateTimeout(r2, p);
     return r2;
   }
 }
diff --git a/packages/taler-wallet-core/src/wallet.ts 
b/packages/taler-wallet-core/src/wallet.ts
index 0590251e..e2d50444 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -335,6 +335,7 @@ async function runTaskLoop(
     let numGivingLiveness = 0;
     let numDue = 0;
     let minDue: AbsoluteTime = AbsoluteTime.never();
+
     for (const p of pending.pendingOperations) {
       minDue = AbsoluteTime.min(minDue, p.timestampDue);
       if (AbsoluteTime.isExpired(p.timestampDue)) {
@@ -683,9 +684,13 @@ async function dumpCoins(ws: InternalWalletState): 
Promise<CoinDumpJson> {
           c.exchangeBaseUrl,
           c.denomPubHash,
         );
+        if (!denomInfo) {
+          console.error("no denomination found for coin")
+          continue;
+        }
         coinsJson.coins.push({
           coin_pub: c.coinPub,
-          denom_pub: denomInfo?.denomPub!,
+          denom_pub: denomInfo.denomPub,
           denom_pub_hash: c.denomPubHash,
           denom_value: Amounts.stringify(denom.value),
           exchange_base_url: c.exchangeBaseUrl,

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]