reset retry counter when forcing operations
This commit is contained in:
parent
b68b52e95c
commit
396bb61db7
@ -20,7 +20,6 @@ import {
|
|||||||
KeysJson,
|
KeysJson,
|
||||||
Denomination,
|
Denomination,
|
||||||
ExchangeWireJson,
|
ExchangeWireJson,
|
||||||
WireFeesJson,
|
|
||||||
} from "../talerTypes";
|
} from "../talerTypes";
|
||||||
import { getTimestampNow, OperationError } from "../walletTypes";
|
import { getTimestampNow, OperationError } from "../walletTypes";
|
||||||
import {
|
import {
|
||||||
@ -313,11 +312,11 @@ async function updateExchangeWithWireInfo(
|
|||||||
export async function updateExchangeFromUrl(
|
export async function updateExchangeFromUrl(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
force: boolean = false,
|
forceNow: boolean = false,
|
||||||
): Promise<ExchangeRecord> {
|
): Promise<ExchangeRecord> {
|
||||||
const onOpErr = (e: OperationError) => setExchangeError(ws, baseUrl, e);
|
const onOpErr = (e: OperationError) => setExchangeError(ws, baseUrl, e);
|
||||||
return await guardOperationException(
|
return await guardOperationException(
|
||||||
() => updateExchangeFromUrlImpl(ws, baseUrl, force),
|
() => updateExchangeFromUrlImpl(ws, baseUrl, forceNow),
|
||||||
onOpErr,
|
onOpErr,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -330,7 +329,7 @@ export async function updateExchangeFromUrl(
|
|||||||
async function updateExchangeFromUrlImpl(
|
async function updateExchangeFromUrlImpl(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
force: boolean = false,
|
forceNow: boolean = false,
|
||||||
): Promise<ExchangeRecord> {
|
): Promise<ExchangeRecord> {
|
||||||
const now = getTimestampNow();
|
const now = getTimestampNow();
|
||||||
baseUrl = canonicalizeBaseUrl(baseUrl);
|
baseUrl = canonicalizeBaseUrl(baseUrl);
|
||||||
@ -353,10 +352,10 @@ async function updateExchangeFromUrlImpl(
|
|||||||
if (!rec) {
|
if (!rec) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rec.updateStatus != ExchangeUpdateStatus.FETCH_KEYS && !force) {
|
if (rec.updateStatus != ExchangeUpdateStatus.FETCH_KEYS && !forceNow) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rec.updateStatus != ExchangeUpdateStatus.FETCH_KEYS && force) {
|
if (rec.updateStatus != ExchangeUpdateStatus.FETCH_KEYS && forceNow) {
|
||||||
rec.updateReason = "forced";
|
rec.updateReason = "forced";
|
||||||
}
|
}
|
||||||
rec.updateStarted = now;
|
rec.updateStarted = now;
|
||||||
|
@ -67,7 +67,11 @@ import {
|
|||||||
} from "../util/helpers";
|
} from "../util/helpers";
|
||||||
import { Logger } from "../util/logging";
|
import { Logger } from "../util/logging";
|
||||||
import { InternalWalletState } from "./state";
|
import { InternalWalletState } from "./state";
|
||||||
import { parsePayUri, parseRefundUri, getOrderDownloadUrl } from "../util/taleruri";
|
import {
|
||||||
|
parsePayUri,
|
||||||
|
parseRefundUri,
|
||||||
|
getOrderDownloadUrl,
|
||||||
|
} from "../util/taleruri";
|
||||||
import { getTotalRefreshCost, refresh } from "./refresh";
|
import { getTotalRefreshCost, refresh } from "./refresh";
|
||||||
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto";
|
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto";
|
||||||
import { guardOperationException } from "./errors";
|
import { guardOperationException } from "./errors";
|
||||||
@ -540,19 +544,37 @@ async function incrementPurchaseApplyRefundRetry(
|
|||||||
export async function processDownloadProposal(
|
export async function processDownloadProposal(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
|
forceNow: boolean = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const onOpErr = (err: OperationError) =>
|
const onOpErr = (err: OperationError) =>
|
||||||
incrementProposalRetry(ws, proposalId, err);
|
incrementProposalRetry(ws, proposalId, err);
|
||||||
await guardOperationException(
|
await guardOperationException(
|
||||||
() => processDownloadProposalImpl(ws, proposalId),
|
() => processDownloadProposalImpl(ws, proposalId, forceNow),
|
||||||
onOpErr,
|
onOpErr,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function resetDownloadProposalRetry(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
proposalId: string,
|
||||||
|
) {
|
||||||
|
await oneShotMutate(ws.db, Stores.proposals, proposalId, (x) => {
|
||||||
|
if (x.retryInfo.active) {
|
||||||
|
x.retryInfo = initRetryInfo();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async function processDownloadProposalImpl(
|
async function processDownloadProposalImpl(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
|
forceNow: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
if (forceNow) {
|
||||||
|
await resetDownloadProposalRetry(ws, proposalId);
|
||||||
|
}
|
||||||
const proposal = await oneShotGet(ws.db, Stores.proposals, proposalId);
|
const proposal = await oneShotGet(ws.db, Stores.proposals, proposalId);
|
||||||
if (!proposal) {
|
if (!proposal) {
|
||||||
return;
|
return;
|
||||||
@ -560,8 +582,10 @@ async function processDownloadProposalImpl(
|
|||||||
if (proposal.proposalStatus != ProposalStatus.DOWNLOADING) {
|
if (proposal.proposalStatus != ProposalStatus.DOWNLOADING) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parsedUrl = new URL(getOrderDownloadUrl(proposal.merchantBaseUrl, proposal.orderId));
|
const parsedUrl = new URL(
|
||||||
|
getOrderDownloadUrl(proposal.merchantBaseUrl, proposal.orderId),
|
||||||
|
);
|
||||||
parsedUrl.searchParams.set("nonce", proposal.noncePub);
|
parsedUrl.searchParams.set("nonce", proposal.noncePub);
|
||||||
const urlWithNonce = parsedUrl.href;
|
const urlWithNonce = parsedUrl.href;
|
||||||
console.log("downloading contract from '" + urlWithNonce + "'");
|
console.log("downloading contract from '" + urlWithNonce + "'");
|
||||||
@ -714,12 +738,16 @@ export async function submitPay(
|
|||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
const ar = purchase.contractTerms.auto_refund;
|
const ar = purchase.contractTerms.auto_refund;
|
||||||
if (ar) {
|
if (ar) {
|
||||||
|
console.log("auto_refund present");
|
||||||
const autoRefundDelay = extractTalerDuration(ar);
|
const autoRefundDelay = extractTalerDuration(ar);
|
||||||
|
console.log("auto_refund valid", autoRefundDelay);
|
||||||
if (autoRefundDelay) {
|
if (autoRefundDelay) {
|
||||||
purchase.refundStatusRequested = true;
|
purchase.refundStatusRequested = true;
|
||||||
|
purchase.refundStatusRetryInfo = initRetryInfo();
|
||||||
|
purchase.lastRefundStatusError = undefined;
|
||||||
purchase.autoRefundDeadline = {
|
purchase.autoRefundDeadline = {
|
||||||
t_ms: getTimestampNow().t_ms + autoRefundDelay.d_ms,
|
t_ms: getTimestampNow().t_ms + autoRefundDelay.d_ms,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1091,7 +1119,10 @@ async function acceptRefundResponse(
|
|||||||
let queryDone = true;
|
let queryDone = true;
|
||||||
|
|
||||||
if (numNewRefunds === 0) {
|
if (numNewRefunds === 0) {
|
||||||
if (p.autoRefundDeadline && p.autoRefundDeadline.t_ms < getTimestampNow().t_ms) {
|
if (
|
||||||
|
p.autoRefundDeadline &&
|
||||||
|
p.autoRefundDeadline.t_ms > getTimestampNow().t_ms
|
||||||
|
) {
|
||||||
queryDone = false;
|
queryDone = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1101,12 +1132,14 @@ async function acceptRefundResponse(
|
|||||||
p.lastRefundStatusError = undefined;
|
p.lastRefundStatusError = undefined;
|
||||||
p.refundStatusRetryInfo = initRetryInfo();
|
p.refundStatusRetryInfo = initRetryInfo();
|
||||||
p.refundStatusRequested = false;
|
p.refundStatusRequested = false;
|
||||||
|
console.log("refund query done");
|
||||||
} else {
|
} else {
|
||||||
// No error, but we need to try again!
|
// No error, but we need to try again!
|
||||||
p.lastRefundStatusTimestamp = getTimestampNow();
|
p.lastRefundStatusTimestamp = getTimestampNow();
|
||||||
p.refundStatusRetryInfo.retryCounter++;
|
p.refundStatusRetryInfo.retryCounter++;
|
||||||
updateRetryInfoTimeout(p.refundStatusRetryInfo);
|
updateRetryInfoTimeout(p.refundStatusRetryInfo);
|
||||||
p.lastRefundStatusError = undefined;
|
p.lastRefundStatusError = undefined;
|
||||||
|
console.log("refund query not done");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numNewRefunds) {
|
if (numNewRefunds) {
|
||||||
@ -1137,8 +1170,6 @@ async function startRefundQuery(
|
|||||||
console.log("no purchase found for refund URL");
|
console.log("no purchase found for refund URL");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (p.refundStatusRequested) {
|
|
||||||
}
|
|
||||||
p.refundStatusRequested = true;
|
p.refundStatusRequested = true;
|
||||||
p.lastRefundStatusError = undefined;
|
p.lastRefundStatusError = undefined;
|
||||||
p.refundStatusRetryInfo = initRetryInfo();
|
p.refundStatusRetryInfo = initRetryInfo();
|
||||||
@ -1193,19 +1224,36 @@ export async function applyRefund(
|
|||||||
export async function processPurchasePay(
|
export async function processPurchasePay(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
|
forceNow: boolean = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const onOpErr = (e: OperationError) =>
|
const onOpErr = (e: OperationError) =>
|
||||||
incrementPurchasePayRetry(ws, proposalId, e);
|
incrementPurchasePayRetry(ws, proposalId, e);
|
||||||
await guardOperationException(
|
await guardOperationException(
|
||||||
() => processPurchasePayImpl(ws, proposalId),
|
() => processPurchasePayImpl(ws, proposalId, forceNow),
|
||||||
onOpErr,
|
onOpErr,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function resetPurchasePayRetry(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
proposalId: string,
|
||||||
|
) {
|
||||||
|
await oneShotMutate(ws.db, Stores.purchases, proposalId, (x) => {
|
||||||
|
if (x.payRetryInfo.active) {
|
||||||
|
x.payRetryInfo = initRetryInfo();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function processPurchasePayImpl(
|
async function processPurchasePayImpl(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
|
forceNow: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
if (forceNow) {
|
||||||
|
await resetPurchasePayRetry(ws, proposalId);
|
||||||
|
}
|
||||||
const purchase = await oneShotGet(ws.db, Stores.purchases, proposalId);
|
const purchase = await oneShotGet(ws.db, Stores.purchases, proposalId);
|
||||||
if (!purchase) {
|
if (!purchase) {
|
||||||
return;
|
return;
|
||||||
@ -1220,19 +1268,34 @@ async function processPurchasePayImpl(
|
|||||||
export async function processPurchaseQueryRefund(
|
export async function processPurchaseQueryRefund(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
|
forceNow: boolean = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const onOpErr = (e: OperationError) =>
|
const onOpErr = (e: OperationError) =>
|
||||||
incrementPurchaseQueryRefundRetry(ws, proposalId, e);
|
incrementPurchaseQueryRefundRetry(ws, proposalId, e);
|
||||||
await guardOperationException(
|
await guardOperationException(
|
||||||
() => processPurchaseQueryRefundImpl(ws, proposalId),
|
() => processPurchaseQueryRefundImpl(ws, proposalId, forceNow),
|
||||||
onOpErr,
|
onOpErr,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function resetPurchaseQueryRefundRetry(ws: InternalWalletState, proposalId: string) {
|
||||||
|
await oneShotMutate(ws.db, Stores.purchases, proposalId, x => {
|
||||||
|
if (x.refundStatusRetryInfo.active) {
|
||||||
|
x.refundStatusRetryInfo = initRetryInfo();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function processPurchaseQueryRefundImpl(
|
async function processPurchaseQueryRefundImpl(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
|
forceNow: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
if (forceNow) {
|
||||||
|
await resetPurchaseQueryRefundRetry(ws, proposalId);
|
||||||
|
}
|
||||||
const purchase = await oneShotGet(ws.db, Stores.purchases, proposalId);
|
const purchase = await oneShotGet(ws.db, Stores.purchases, proposalId);
|
||||||
if (!purchase) {
|
if (!purchase) {
|
||||||
return;
|
return;
|
||||||
@ -1262,19 +1325,33 @@ async function processPurchaseQueryRefundImpl(
|
|||||||
export async function processPurchaseApplyRefund(
|
export async function processPurchaseApplyRefund(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
|
forceNow: boolean = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const onOpErr = (e: OperationError) =>
|
const onOpErr = (e: OperationError) =>
|
||||||
incrementPurchaseApplyRefundRetry(ws, proposalId, e);
|
incrementPurchaseApplyRefundRetry(ws, proposalId, e);
|
||||||
await guardOperationException(
|
await guardOperationException(
|
||||||
() => processPurchaseApplyRefundImpl(ws, proposalId),
|
() => processPurchaseApplyRefundImpl(ws, proposalId, forceNow),
|
||||||
onOpErr,
|
onOpErr,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function resetPurchaseApplyRefundRetry(ws: InternalWalletState, proposalId: string) {
|
||||||
|
await oneShotMutate(ws.db, Stores.purchases, proposalId, x => {
|
||||||
|
if (x.refundApplyRetryInfo.active) {
|
||||||
|
x.refundApplyRetryInfo = initRetryInfo();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function processPurchaseApplyRefundImpl(
|
async function processPurchaseApplyRefundImpl(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
|
forceNow: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
if (forceNow) {
|
||||||
|
await resetPurchaseApplyRefundRetry(ws, proposalId);
|
||||||
|
}
|
||||||
const purchase = await oneShotGet(ws.db, Stores.purchases, proposalId);
|
const purchase = await oneShotGet(ws.db, Stores.purchases, proposalId);
|
||||||
if (!purchase) {
|
if (!purchase) {
|
||||||
console.error("not submitting refunds, payment not found:");
|
console.error("not submitting refunds, payment not found:");
|
||||||
|
@ -38,7 +38,11 @@ import { InternalWalletState } from "./state";
|
|||||||
import { Logger } from "../util/logging";
|
import { Logger } from "../util/logging";
|
||||||
import { getWithdrawDenomList } from "./withdraw";
|
import { getWithdrawDenomList } from "./withdraw";
|
||||||
import { updateExchangeFromUrl } from "./exchanges";
|
import { updateExchangeFromUrl } from "./exchanges";
|
||||||
import { getTimestampNow, OperationError, NotificationType } from "../walletTypes";
|
import {
|
||||||
|
getTimestampNow,
|
||||||
|
OperationError,
|
||||||
|
NotificationType,
|
||||||
|
} from "../walletTypes";
|
||||||
import { guardOperationException } from "./errors";
|
import { guardOperationException } from "./errors";
|
||||||
|
|
||||||
const logger = new Logger("refresh.ts");
|
const logger = new Logger("refresh.ts");
|
||||||
@ -315,25 +319,41 @@ async function incrementRefreshRetry(
|
|||||||
ws.notify({ type: NotificationType.RefreshOperationError });
|
ws.notify({ type: NotificationType.RefreshOperationError });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function processRefreshSession(
|
export async function processRefreshSession(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
refreshSessionId: string,
|
refreshSessionId: string,
|
||||||
|
forceNow: boolean = false,
|
||||||
) {
|
) {
|
||||||
return ws.memoProcessRefresh.memo(refreshSessionId, async () => {
|
return ws.memoProcessRefresh.memo(refreshSessionId, async () => {
|
||||||
const onOpErr = (e: OperationError) =>
|
const onOpErr = (e: OperationError) =>
|
||||||
incrementRefreshRetry(ws, refreshSessionId, e);
|
incrementRefreshRetry(ws, refreshSessionId, e);
|
||||||
return guardOperationException(
|
return guardOperationException(
|
||||||
() => processRefreshSessionImpl(ws, refreshSessionId),
|
() => processRefreshSessionImpl(ws, refreshSessionId, forceNow),
|
||||||
onOpErr,
|
onOpErr,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function resetRefreshSessionRetry(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
refreshSessionId: string,
|
||||||
|
) {
|
||||||
|
await oneShotMutate(ws.db, Stores.refresh, refreshSessionId, (x) => {
|
||||||
|
if (x.retryInfo.active) {
|
||||||
|
x.retryInfo = initRetryInfo();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function processRefreshSessionImpl(
|
async function processRefreshSessionImpl(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
refreshSessionId: string,
|
refreshSessionId: string,
|
||||||
|
forceNow: boolean,
|
||||||
) {
|
) {
|
||||||
|
if (forceNow) {
|
||||||
|
await resetRefreshSessionRetry(ws, refreshSessionId);
|
||||||
|
}
|
||||||
const refreshSession = await oneShotGet(
|
const refreshSession = await oneShotGet(
|
||||||
ws.db,
|
ws.db,
|
||||||
Stores.refresh,
|
Stores.refresh,
|
||||||
@ -413,7 +433,7 @@ export async function refresh(
|
|||||||
x.status = CoinStatus.Dormant;
|
x.status = CoinStatus.Dormant;
|
||||||
return x;
|
return x;
|
||||||
});
|
});
|
||||||
ws.notify( { type: NotificationType.RefreshRefused });
|
ws.notify({ type: NotificationType.RefreshRefused });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,7 +470,7 @@ export async function refresh(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
logger.info(`created refresh session ${refreshSession.refreshSessionId}`);
|
logger.info(`created refresh session ${refreshSession.refreshSessionId}`);
|
||||||
ws.notify( { type: NotificationType.RefreshStarted });
|
ws.notify({ type: NotificationType.RefreshStarted });
|
||||||
|
|
||||||
await processRefreshSession(ws, refreshSession.refreshSessionId);
|
await processRefreshSession(ws, refreshSession.refreshSessionId);
|
||||||
}
|
}
|
||||||
|
@ -128,15 +128,32 @@ async function incrementTipRetry(
|
|||||||
export async function processTip(
|
export async function processTip(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
tipId: string,
|
tipId: string,
|
||||||
|
forceNow: boolean = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const onOpErr = (e: OperationError) => incrementTipRetry(ws, tipId, e);
|
const onOpErr = (e: OperationError) => incrementTipRetry(ws, tipId, e);
|
||||||
await guardOperationException(() => processTipImpl(ws, tipId), onOpErr);
|
await guardOperationException(() => processTipImpl(ws, tipId, forceNow), onOpErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resetTipRetry(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
tipId: string,
|
||||||
|
): Promise<void> {
|
||||||
|
await oneShotMutate(ws.db, Stores.tips, tipId, (x) => {
|
||||||
|
if (x.retryInfo.active) {
|
||||||
|
x.retryInfo = initRetryInfo();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processTipImpl(
|
async function processTipImpl(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
tipId: string,
|
tipId: string,
|
||||||
|
forceNow: boolean,
|
||||||
) {
|
) {
|
||||||
|
if (forceNow) {
|
||||||
|
await resetTipRetry(ws, tipId);
|
||||||
|
}
|
||||||
let tipRecord = await oneShotGet(ws.db, Stores.tips, tipId);
|
let tipRecord = await oneShotGet(ws.db, Stores.tips, tipId);
|
||||||
if (!tipRecord) {
|
if (!tipRecord) {
|
||||||
return;
|
return;
|
||||||
|
@ -45,6 +45,7 @@ import {
|
|||||||
oneShotIterIndex,
|
oneShotIterIndex,
|
||||||
oneShotGetIndexed,
|
oneShotGetIndexed,
|
||||||
runWithWriteTransaction,
|
runWithWriteTransaction,
|
||||||
|
oneShotMutate,
|
||||||
} from "../util/query";
|
} from "../util/query";
|
||||||
import {
|
import {
|
||||||
updateExchangeFromUrl,
|
updateExchangeFromUrl,
|
||||||
@ -516,20 +517,37 @@ async function incrementWithdrawalRetry(
|
|||||||
export async function processWithdrawSession(
|
export async function processWithdrawSession(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
withdrawalSessionId: string,
|
withdrawalSessionId: string,
|
||||||
|
forceNow: boolean = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const onOpErr = (e: OperationError) =>
|
const onOpErr = (e: OperationError) =>
|
||||||
incrementWithdrawalRetry(ws, withdrawalSessionId, e);
|
incrementWithdrawalRetry(ws, withdrawalSessionId, e);
|
||||||
await guardOperationException(
|
await guardOperationException(
|
||||||
() => processWithdrawSessionImpl(ws, withdrawalSessionId),
|
() => processWithdrawSessionImpl(ws, withdrawalSessionId, forceNow),
|
||||||
onOpErr,
|
onOpErr,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processWithdrawSessionImpl(
|
async function resetWithdrawSessionRetry(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
withdrawalSessionId: string,
|
withdrawalSessionId: string,
|
||||||
|
) {
|
||||||
|
await oneShotMutate(ws.db, Stores.withdrawalSession, withdrawalSessionId, (x) => {
|
||||||
|
if (x.retryInfo.active) {
|
||||||
|
x.retryInfo = initRetryInfo();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processWithdrawSessionImpl(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
withdrawalSessionId: string,
|
||||||
|
forceNow: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
logger.trace("processing withdraw session", withdrawalSessionId);
|
logger.trace("processing withdraw session", withdrawalSessionId);
|
||||||
|
if (forceNow) {
|
||||||
|
await resetWithdrawSessionRetry(ws, withdrawalSessionId);
|
||||||
|
}
|
||||||
const withdrawalSession = await oneShotGet(
|
const withdrawalSession = await oneShotGet(
|
||||||
ws.db,
|
ws.db,
|
||||||
Stores.withdrawalSession,
|
Stores.withdrawalSession,
|
||||||
|
@ -191,34 +191,34 @@ export class Wallet {
|
|||||||
await refresh(this.ws, pending.coinPub);
|
await refresh(this.ws, pending.coinPub);
|
||||||
break;
|
break;
|
||||||
case "exchange-update":
|
case "exchange-update":
|
||||||
await updateExchangeFromUrl(this.ws, pending.exchangeBaseUrl);
|
await updateExchangeFromUrl(this.ws, pending.exchangeBaseUrl, forceNow);
|
||||||
break;
|
break;
|
||||||
case "refresh":
|
case "refresh":
|
||||||
await processRefreshSession(this.ws, pending.refreshSessionId);
|
await processRefreshSession(this.ws, pending.refreshSessionId, forceNow);
|
||||||
break;
|
break;
|
||||||
case "reserve":
|
case "reserve":
|
||||||
await processReserve(this.ws, pending.reservePub, forceNow);
|
await processReserve(this.ws, pending.reservePub, forceNow);
|
||||||
break;
|
break;
|
||||||
case "withdraw":
|
case "withdraw":
|
||||||
await processWithdrawSession(this.ws, pending.withdrawSessionId);
|
await processWithdrawSession(this.ws, pending.withdrawSessionId, forceNow);
|
||||||
break;
|
break;
|
||||||
case "proposal-choice":
|
case "proposal-choice":
|
||||||
// Nothing to do, user needs to accept/reject
|
// Nothing to do, user needs to accept/reject
|
||||||
break;
|
break;
|
||||||
case "proposal-download":
|
case "proposal-download":
|
||||||
await processDownloadProposal(this.ws, pending.proposalId);
|
await processDownloadProposal(this.ws, pending.proposalId, forceNow);
|
||||||
break;
|
break;
|
||||||
case "tip":
|
case "tip":
|
||||||
await processTip(this.ws, pending.tipId);
|
await processTip(this.ws, pending.tipId, forceNow);
|
||||||
break;
|
break;
|
||||||
case "pay":
|
case "pay":
|
||||||
await processPurchasePay(this.ws, pending.proposalId);
|
await processPurchasePay(this.ws, pending.proposalId, forceNow);
|
||||||
break;
|
break;
|
||||||
case "refund-query":
|
case "refund-query":
|
||||||
await processPurchaseQueryRefund(this.ws, pending.proposalId);
|
await processPurchaseQueryRefund(this.ws, pending.proposalId, forceNow);
|
||||||
break;
|
break;
|
||||||
case "refund-apply":
|
case "refund-apply":
|
||||||
await processPurchaseApplyRefund(this.ws, pending.proposalId);
|
await processPurchaseApplyRefund(this.ws, pending.proposalId, forceNow);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assertUnreachable(pending);
|
assertUnreachable(pending);
|
||||||
|
Loading…
Reference in New Issue
Block a user