all retryInfo function in the same namespace, adding missing retryInfo increment
This commit is contained in:
parent
d3a857743d
commit
c67d0bff1d
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
HttpStatusCode,
|
||||
j2s,
|
||||
Logger,
|
||||
notEmpty,
|
||||
PreparePayResultType,
|
||||
RecoveryLoadRequest,
|
||||
RecoveryMergeStrategy,
|
||||
TalerErrorDetail,
|
||||
AbsoluteTime,
|
||||
URL,
|
||||
WalletBackupContentV1,
|
||||
TalerProtocolTimestamp,
|
||||
} 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,
|
||||
ConfirmPayResultType, decodeCrock, DenomKeyType,
|
||||
durationFromSpec, eddsaGetPublic,
|
||||
EddsaKeyPair,
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
hash,
|
||||
rsaBlind,
|
||||
stringToBytes,
|
||||
hash, hashDenomPub,
|
||||
HttpStatusCode,
|
||||
j2s, kdf, Logger,
|
||||
notEmpty,
|
||||
PreparePayResultType,
|
||||
RecoveryLoadRequest,
|
||||
RecoveryMergeStrategy, rsaBlind, secretbox, secretbox_open, stringToBytes, TalerErrorDetail, TalerProtocolTimestamp, URL,
|
||||
WalletBackupContentV1
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { CryptoDispatcher } from "../../crypto/workers/cryptoDispatcher.js";
|
||||
import { gunzipSync, gzipSync } from "fflate";
|
||||
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.
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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: [],
|
||||
|
@ -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 {
|
||||
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";
|
||||
import {
|
||||
readSuccessResponseJsonOrThrow,
|
||||
readUnexpectedResponseDetails,
|
||||
} from "../util/http.js";
|
||||
import { checkDbInvariant } from "../util/invariants.js";
|
||||
import { Logger } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
resetRetryInfo,
|
||||
RetryInfo,
|
||||
updateRetryInfoTimeout,
|
||||
} from "../util/retries.js";
|
||||
import {
|
||||
Duration,
|
||||
durationFromSpec,
|
||||
durationMul,
|
||||
AbsoluteTime,
|
||||
URL,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { updateExchangeFromUrl } from "./exchanges.js";
|
||||
import { TalerError } from "../errors.js";
|
||||
import {
|
||||
DenomInfo,
|
||||
EXCHANGE_COINS_LOCK,
|
||||
InternalWalletState,
|
||||
InternalWalletState
|
||||
} from "../internal-wallet-state.js";
|
||||
import {
|
||||
isWithdrawableDenom,
|
||||
selectWithdrawalDenominations,
|
||||
} from "./withdraw.js";
|
||||
import {
|
||||
DerivedRefreshSession,
|
||||
RefreshNewDenomInfo,
|
||||
} from "../crypto/cryptoTypes.js";
|
||||
readSuccessResponseJsonOrThrow,
|
||||
readUnexpectedResponseDetails
|
||||
} from "../util/http.js";
|
||||
import { checkDbInvariant } from "../util/invariants.js";
|
||||
import { GetReadWriteAccess } from "../util/query.js";
|
||||
import {
|
||||
RetryInfo
|
||||
} from "../util/retries.js";
|
||||
import { guardOperationException } from "./common.js";
|
||||
import { CryptoApiStoppedError } from "../crypto/workers/cryptoDispatcher.js";
|
||||
import { TalerCryptoInterface } from "../crypto/cryptoImplementation.js";
|
||||
import { TalerError } from "../errors.js";
|
||||
import { updateExchangeFromUrl } from "./exchanges.js";
|
||||
import {
|
||||
isWithdrawableDenom,
|
||||
selectWithdrawalDenominations
|
||||
} from "./withdraw.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(),
|
||||
|
@ -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, {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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" };
|
||||
}
|
||||
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 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),
|
||||
};
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user