wallet-core: reset reserve retry when resetting withdrawal retry
This commit is contained in:
parent
38d8239f93
commit
c493a3069e
@ -65,6 +65,14 @@ export interface MerchantOperations {
|
||||
): Promise<MerchantInfo>;
|
||||
}
|
||||
|
||||
export interface ReserveOperations {
|
||||
processReserve(
|
||||
ws: InternalWalletState,
|
||||
reservePub: string,
|
||||
forceNow?: boolean,
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for exchange-related operations.
|
||||
*/
|
||||
@ -152,6 +160,7 @@ export interface InternalWalletState {
|
||||
exchangeOps: ExchangeOperations;
|
||||
recoupOps: RecoupOperations;
|
||||
merchantOps: MerchantOperations;
|
||||
reserveOps: ReserveOperations;
|
||||
|
||||
db: DbAccess<typeof WalletStoresV1>;
|
||||
http: HttpRequestLibrary;
|
||||
|
@ -15,35 +15,63 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
AcceptWithdrawalResponse, addPaytoQueryParams, Amounts, canonicalizeBaseUrl, codecForBankWithdrawalOperationPostResponse,
|
||||
AcceptWithdrawalResponse,
|
||||
addPaytoQueryParams,
|
||||
Amounts,
|
||||
canonicalizeBaseUrl,
|
||||
codecForBankWithdrawalOperationPostResponse,
|
||||
codecForReserveStatus,
|
||||
codecForWithdrawOperationStatusResponse, CreateReserveRequest,
|
||||
CreateReserveResponse, Duration,
|
||||
codecForWithdrawOperationStatusResponse,
|
||||
CreateReserveRequest,
|
||||
CreateReserveResponse,
|
||||
Duration,
|
||||
durationMax,
|
||||
durationMin, encodeCrock, getRandomBytes, getTimestampNow, Logger, NotificationType, randomBytes, ReserveTransactionType,
|
||||
TalerErrorCode, TalerErrorDetails, URL
|
||||
durationMin,
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
getTimestampNow,
|
||||
Logger,
|
||||
NotificationType,
|
||||
randomBytes,
|
||||
ReserveTransactionType,
|
||||
TalerErrorCode,
|
||||
TalerErrorDetails,
|
||||
URL,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { InternalWalletState } from "../common.js";
|
||||
import {
|
||||
ReserveBankInfo,
|
||||
ReserveRecord, ReserveRecordStatus, WalletStoresV1, WithdrawalGroupRecord
|
||||
ReserveRecord,
|
||||
ReserveRecordStatus,
|
||||
WalletStoresV1,
|
||||
WithdrawalGroupRecord,
|
||||
} from "../db.js";
|
||||
import { guardOperationException, OperationFailedError } from "../errors.js";
|
||||
import { assertUnreachable } from "../util/assertUnreachable.js";
|
||||
import {
|
||||
readSuccessResponseJsonOrErrorCode,
|
||||
readSuccessResponseJsonOrThrow,
|
||||
throwUnexpectedRequestError
|
||||
throwUnexpectedRequestError,
|
||||
} from "../util/http.js";
|
||||
import { GetReadOnlyAccess } from "../util/query.js";
|
||||
import {
|
||||
getRetryDuration, initRetryInfo, updateRetryInfoTimeout
|
||||
getRetryDuration,
|
||||
initRetryInfo,
|
||||
updateRetryInfoTimeout,
|
||||
} from "../util/retries.js";
|
||||
import {
|
||||
getExchangeDetails, getExchangePaytoUri, getExchangeTrust, updateExchangeFromUrl
|
||||
getExchangeDetails,
|
||||
getExchangePaytoUri,
|
||||
getExchangeTrust,
|
||||
updateExchangeFromUrl,
|
||||
} from "./exchanges.js";
|
||||
import {
|
||||
denomSelectionInfoToState, getBankWithdrawalInfo, getCandidateWithdrawalDenoms, processWithdrawGroup, selectWithdrawalDenominations, updateWithdrawalDenoms
|
||||
denomSelectionInfoToState,
|
||||
getBankWithdrawalInfo,
|
||||
getCandidateWithdrawalDenoms,
|
||||
processWithdrawGroup,
|
||||
selectWithdrawalDenominations,
|
||||
updateWithdrawalDenoms,
|
||||
} from "./withdraw.js";
|
||||
|
||||
const logger = new Logger("reserves.ts");
|
||||
@ -617,7 +645,8 @@ async function updateReserve(
|
||||
logger.trace(
|
||||
`Remaining unclaimed amount in reseve is ${Amounts.stringify(
|
||||
remainingAmount,
|
||||
)} and can be withdrawn with ${denomSelInfo.selectedDenoms.length
|
||||
)} and can be withdrawn with ${
|
||||
denomSelInfo.selectedDenoms.length
|
||||
} coins`,
|
||||
);
|
||||
|
||||
|
@ -19,12 +19,25 @@
|
||||
*/
|
||||
import {
|
||||
AmountJson,
|
||||
Amounts, OrderShortInfo, PaymentStatus, timestampCmp, Transaction, TransactionsRequest,
|
||||
TransactionsResponse, TransactionType, WithdrawalDetails, WithdrawalType
|
||||
Amounts,
|
||||
Logger,
|
||||
OrderShortInfo,
|
||||
PaymentStatus,
|
||||
timestampCmp,
|
||||
Transaction,
|
||||
TransactionsRequest,
|
||||
TransactionsResponse,
|
||||
TransactionType,
|
||||
WithdrawalDetails,
|
||||
WithdrawalType,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { InternalWalletState } from "../common.js";
|
||||
import {
|
||||
AbortStatus, RefundState, ReserveRecord, ReserveRecordStatus, WalletRefundItem
|
||||
AbortStatus,
|
||||
RefundState,
|
||||
ReserveRecord,
|
||||
ReserveRecordStatus,
|
||||
WalletRefundItem,
|
||||
} from "../db.js";
|
||||
import { processDepositGroup } from "./deposits.js";
|
||||
import { getExchangeDetails } from "./exchanges.js";
|
||||
@ -34,6 +47,8 @@ import { getFundingPaytoUris } from "./reserves.js";
|
||||
import { processTip } from "./tip.js";
|
||||
import { processWithdrawGroup } from "./withdraw.js";
|
||||
|
||||
const logger = new Logger("taler-wallet-core:transactions.ts");
|
||||
|
||||
/**
|
||||
* Create an event ID from the type and the primary key for the event.
|
||||
*/
|
||||
@ -404,13 +419,6 @@ export enum TombstoneTag {
|
||||
DeleteRefund = "delete-refund",
|
||||
}
|
||||
|
||||
export async function retryTransactionNow(
|
||||
ws: InternalWalletState,
|
||||
transactionId: string,
|
||||
): Promise<void> {
|
||||
const [type, ...rest] = transactionId.split(":");
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediately retry the underlying operation
|
||||
* of a transaction.
|
||||
@ -419,6 +427,8 @@ export async function retryTransaction(
|
||||
ws: InternalWalletState,
|
||||
transactionId: string,
|
||||
): Promise<void> {
|
||||
logger.info(`retrying transaction ${transactionId}`);
|
||||
|
||||
const [type, ...rest] = transactionId.split(":");
|
||||
|
||||
switch (type) {
|
||||
|
@ -854,7 +854,10 @@ async function resetWithdrawalGroupRetry(
|
||||
withdrawalGroupId: string,
|
||||
): Promise<void> {
|
||||
await ws.db
|
||||
.mktx((x) => ({ withdrawalGroups: x.withdrawalGroups }))
|
||||
.mktx((x) => ({
|
||||
withdrawalGroups: x.withdrawalGroups,
|
||||
reserves: x.reserves,
|
||||
}))
|
||||
.runReadWrite(async (tx) => {
|
||||
const x = await tx.withdrawalGroups.get(withdrawalGroupId);
|
||||
if (x) {
|
||||
@ -879,9 +882,27 @@ async function processWithdrawGroupImpl(
|
||||
return tx.withdrawalGroups.get(withdrawalGroupId);
|
||||
});
|
||||
if (!withdrawalGroup) {
|
||||
logger.trace("withdraw session doesn't exist");
|
||||
// Withdrawal group doesn't exist yet, but reserve might exist
|
||||
// (and reference the yet to be created withdrawal group)
|
||||
const reservePub = await ws.db
|
||||
.mktx((x) => ({ reserves: x.reserves }))
|
||||
.runReadOnly(async (tx) => {
|
||||
const r = await tx.reserves.indexes.byInitialWithdrawalGroupId.get(
|
||||
withdrawalGroupId,
|
||||
);
|
||||
if (r) {
|
||||
return r.reservePub;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
if (!reservePub) {
|
||||
logger.warn(
|
||||
"withdrawal group doesn't exist (and reserve doesn't exist either)",
|
||||
);
|
||||
return;
|
||||
}
|
||||
return await ws.reserveOps.processReserve(ws, reservePub, forceNow);
|
||||
}
|
||||
|
||||
await ws.exchangeOps.updateExchangeFromUrl(
|
||||
ws,
|
||||
|
@ -103,6 +103,7 @@ import {
|
||||
MerchantOperations,
|
||||
NotificationListener,
|
||||
RecoupOperations,
|
||||
ReserveOperations,
|
||||
} from "./common.js";
|
||||
import {
|
||||
runIntegrationTest,
|
||||
@ -1122,6 +1123,10 @@ class InternalWalletStateImpl implements InternalWalletState {
|
||||
getMerchantInfo: getMerchantInfo,
|
||||
};
|
||||
|
||||
reserveOps: ReserveOperations = {
|
||||
processReserve: processReserve,
|
||||
}
|
||||
|
||||
/**
|
||||
* Promises that are waiting for a particular resource.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user