wallet-core: use numeric status field to allow range queries
This commit is contained in:
parent
5d31803c92
commit
7d6bcd42ea
@ -62,6 +62,8 @@ import { Event, IDBDatabase } from "@gnu-taler/idb-bridge";
|
|||||||
* will have an index.
|
* will have an index.
|
||||||
* - Amounts are stored as strings, except when they are needed for
|
* - Amounts are stored as strings, except when they are needed for
|
||||||
* indexing.
|
* indexing.
|
||||||
|
* - Every record that has a corresponding transaction item must have
|
||||||
|
* an index for a mandatory timestamp field.
|
||||||
* - Optional fields should be avoided, use "T | undefined" instead.
|
* - Optional fields should be avoided, use "T | undefined" instead.
|
||||||
*
|
*
|
||||||
* @author Florian Dold <dold@taler.net>
|
* @author Florian Dold <dold@taler.net>
|
||||||
@ -94,38 +96,45 @@ export const CURRENT_DB_CONFIG_KEY = "currentMainDbName";
|
|||||||
*/
|
*/
|
||||||
export const WALLET_DB_MINOR_VERSION = 1;
|
export const WALLET_DB_MINOR_VERSION = 1;
|
||||||
|
|
||||||
|
export namespace OperationStatusRange {
|
||||||
|
export const ACTIVE_START = 10;
|
||||||
|
export const ACTIVE_END = 29;
|
||||||
|
export const DORMANT_START = 40;
|
||||||
|
export const DORMANT_END = 59;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status of a withdrawal.
|
* Status of a withdrawal.
|
||||||
*/
|
*/
|
||||||
export enum ReserveRecordStatus {
|
export enum WithdrawalGroupStatus {
|
||||||
/**
|
/**
|
||||||
* Reserve must be registered with the bank.
|
* Reserve must be registered with the bank.
|
||||||
*/
|
*/
|
||||||
RegisteringBank = "registering-bank",
|
RegisteringBank = OperationStatusRange.ACTIVE_START,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We've registered reserve's information with the bank
|
* We've registered reserve's information with the bank
|
||||||
* and are now waiting for the user to confirm the withdraw
|
* and are now waiting for the user to confirm the withdraw
|
||||||
* with the bank (typically 2nd factor auth).
|
* with the bank (typically 2nd factor auth).
|
||||||
*/
|
*/
|
||||||
WaitConfirmBank = "wait-confirm-bank",
|
WaitConfirmBank = OperationStatusRange.ACTIVE_START + 1,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Querying reserve status with the exchange.
|
* Querying reserve status with the exchange.
|
||||||
*/
|
*/
|
||||||
QueryingStatus = "querying-status",
|
QueryingStatus = OperationStatusRange.ACTIVE_START + 2,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The corresponding withdraw record has been created.
|
* The corresponding withdraw record has been created.
|
||||||
* No further processing is done, unless explicitly requested
|
* No further processing is done, unless explicitly requested
|
||||||
* by the user.
|
* by the user.
|
||||||
*/
|
*/
|
||||||
Dormant = "dormant",
|
Finished = OperationStatusRange.DORMANT_START,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bank aborted the withdrawal.
|
* The bank aborted the withdrawal.
|
||||||
*/
|
*/
|
||||||
BankAborted = "bank-aborted",
|
BankAborted = OperationStatusRange.DORMANT_START + 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1354,20 +1363,12 @@ export interface WithdrawalGroupRecord {
|
|||||||
*/
|
*/
|
||||||
timestampFinish?: TalerProtocolTimestamp;
|
timestampFinish?: TalerProtocolTimestamp;
|
||||||
|
|
||||||
/**
|
|
||||||
* Operation status of the withdrawal group.
|
|
||||||
* Used for indexing in the database.
|
|
||||||
*
|
|
||||||
* FIXME: Redundant with reserveStatus
|
|
||||||
*/
|
|
||||||
operationStatus: OperationStatus;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current status of the reserve.
|
* Current status of the reserve.
|
||||||
*
|
*
|
||||||
* FIXME: Wrong name!
|
* FIXME: Wrong name!
|
||||||
*/
|
*/
|
||||||
reserveStatus: ReserveRecordStatus;
|
status: WithdrawalGroupStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Amount that was sent by the user to fund the reserve.
|
* Amount that was sent by the user to fund the reserve.
|
||||||
@ -1947,7 +1948,7 @@ export const WalletStoresV1 = {
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
byReservePub: describeIndex("byReservePub", "reservePub"),
|
byReservePub: describeIndex("byReservePub", "reservePub"),
|
||||||
byStatus: describeIndex("byStatus", "operationStatus"),
|
byStatus: describeIndex("byStatus", "status"),
|
||||||
byTalerWithdrawUri: describeIndex(
|
byTalerWithdrawUri: describeIndex(
|
||||||
"byTalerWithdrawUri",
|
"byTalerWithdrawUri",
|
||||||
"wgInfo.bankInfo.talerWithdrawUri",
|
"wgInfo.bankInfo.talerWithdrawUri",
|
||||||
|
@ -71,6 +71,7 @@ import {
|
|||||||
RefreshCoinStatus,
|
RefreshCoinStatus,
|
||||||
RefundState,
|
RefundState,
|
||||||
WALLET_BACKUP_STATE_KEY,
|
WALLET_BACKUP_STATE_KEY,
|
||||||
|
WithdrawalGroupStatus,
|
||||||
WithdrawalRecordType,
|
WithdrawalRecordType,
|
||||||
} from "../../db.js";
|
} from "../../db.js";
|
||||||
import { InternalWalletState } from "../../internal-wallet-state.js";
|
import { InternalWalletState } from "../../internal-wallet-state.js";
|
||||||
@ -167,8 +168,9 @@ export async function exportBackup(
|
|||||||
instructed_amount: Amounts.stringify(wg.instructedAmount),
|
instructed_amount: Amounts.stringify(wg.instructedAmount),
|
||||||
reserve_priv: wg.reservePriv,
|
reserve_priv: wg.reservePriv,
|
||||||
restrict_age: wg.restrictAge,
|
restrict_age: wg.restrictAge,
|
||||||
|
// FIXME: proper status conversion!
|
||||||
operation_status:
|
operation_status:
|
||||||
wg.operationStatus == OperationStatus.Finished
|
wg.status == WithdrawalGroupStatus.Finished
|
||||||
? BackupOperationStatus.Finished
|
? BackupOperationStatus.Finished
|
||||||
: BackupOperationStatus.Pending,
|
: BackupOperationStatus.Pending,
|
||||||
selected_denoms_uid: wg.denomSelUid,
|
selected_denoms_uid: wg.denomSelUid,
|
||||||
|
@ -52,7 +52,7 @@ import {
|
|||||||
RefreshSessionRecord,
|
RefreshSessionRecord,
|
||||||
RefundState,
|
RefundState,
|
||||||
ReserveBankInfo,
|
ReserveBankInfo,
|
||||||
ReserveRecordStatus,
|
WithdrawalGroupStatus,
|
||||||
WalletContractData,
|
WalletContractData,
|
||||||
WalletRefundItem,
|
WalletRefundItem,
|
||||||
WalletStoresV1,
|
WalletStoresV1,
|
||||||
@ -531,9 +531,6 @@ export async function importBackup(
|
|||||||
exchangeBaseUrl: backupWg.exchange_base_url,
|
exchangeBaseUrl: backupWg.exchange_base_url,
|
||||||
instructedAmount: Amounts.parseOrThrow(backupWg.instructed_amount),
|
instructedAmount: Amounts.parseOrThrow(backupWg.instructed_amount),
|
||||||
secretSeed: backupWg.secret_seed,
|
secretSeed: backupWg.secret_seed,
|
||||||
operationStatus: backupWg.timestamp_finish
|
|
||||||
? OperationStatus.Finished
|
|
||||||
: OperationStatus.Pending,
|
|
||||||
denomsSel: await getDenomSelStateFromBackup(
|
denomsSel: await getDenomSelStateFromBackup(
|
||||||
tx,
|
tx,
|
||||||
backupWg.exchange_base_url,
|
backupWg.exchange_base_url,
|
||||||
@ -545,9 +542,9 @@ export async function importBackup(
|
|||||||
),
|
),
|
||||||
reservePriv: backupWg.reserve_priv,
|
reservePriv: backupWg.reserve_priv,
|
||||||
reservePub,
|
reservePub,
|
||||||
reserveStatus: backupWg.timestamp_finish
|
status: backupWg.timestamp_finish
|
||||||
? ReserveRecordStatus.Dormant
|
? WithdrawalGroupStatus.Finished
|
||||||
: ReserveRecordStatus.QueryingStatus, // FIXME!
|
: WithdrawalGroupStatus.QueryingStatus, // FIXME!
|
||||||
timestampStart: backupWg.timestamp_created,
|
timestampStart: backupWg.timestamp_created,
|
||||||
wgInfo,
|
wgInfo,
|
||||||
restrictAge: backupWg.restrict_age,
|
restrictAge: backupWg.restrict_age,
|
||||||
|
@ -65,7 +65,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
CoinStatus,
|
CoinStatus,
|
||||||
MergeReserveInfo,
|
MergeReserveInfo,
|
||||||
ReserveRecordStatus,
|
WithdrawalGroupStatus,
|
||||||
WalletStoresV1,
|
WalletStoresV1,
|
||||||
WithdrawalRecordType,
|
WithdrawalRecordType,
|
||||||
} from "../db.js";
|
} from "../db.js";
|
||||||
@ -544,7 +544,7 @@ export async function acceptPeerPushPayment(
|
|||||||
contractTerms: peerInc.contractTerms,
|
contractTerms: peerInc.contractTerms,
|
||||||
},
|
},
|
||||||
exchangeBaseUrl: peerInc.exchangeBaseUrl,
|
exchangeBaseUrl: peerInc.exchangeBaseUrl,
|
||||||
reserveStatus: ReserveRecordStatus.QueryingStatus,
|
reserveStatus: WithdrawalGroupStatus.QueryingStatus,
|
||||||
reserveKeyPair: {
|
reserveKeyPair: {
|
||||||
priv: mergeReserveInfo.reservePriv,
|
priv: mergeReserveInfo.reservePriv,
|
||||||
pub: mergeReserveInfo.reservePub,
|
pub: mergeReserveInfo.reservePub,
|
||||||
@ -828,7 +828,7 @@ export async function initiatePeerRequestForPay(
|
|||||||
contractPriv: econtractResp.contractPriv,
|
contractPriv: econtractResp.contractPriv,
|
||||||
},
|
},
|
||||||
exchangeBaseUrl: req.exchangeBaseUrl,
|
exchangeBaseUrl: req.exchangeBaseUrl,
|
||||||
reserveStatus: ReserveRecordStatus.QueryingStatus,
|
reserveStatus: WithdrawalGroupStatus.QueryingStatus,
|
||||||
reserveKeyPair: {
|
reserveKeyPair: {
|
||||||
priv: mergeReserveInfo.reservePriv,
|
priv: mergeReserveInfo.reservePriv,
|
||||||
pub: mergeReserveInfo.reservePub,
|
pub: mergeReserveInfo.reservePub,
|
||||||
|
@ -28,6 +28,9 @@ import {
|
|||||||
BackupProviderStateTag,
|
BackupProviderStateTag,
|
||||||
RefreshCoinStatus,
|
RefreshCoinStatus,
|
||||||
OperationStatus,
|
OperationStatus,
|
||||||
|
WithdrawalGroupRecord,
|
||||||
|
WithdrawalGroupStatus,
|
||||||
|
OperationStatusRange,
|
||||||
} from "../db.js";
|
} from "../db.js";
|
||||||
import {
|
import {
|
||||||
PendingOperationsResponse,
|
PendingOperationsResponse,
|
||||||
@ -38,6 +41,7 @@ import { InternalWalletState } from "../internal-wallet-state.js";
|
|||||||
import { GetReadOnlyAccess } from "../util/query.js";
|
import { GetReadOnlyAccess } from "../util/query.js";
|
||||||
import { RetryTags } from "../util/retries.js";
|
import { RetryTags } from "../util/retries.js";
|
||||||
import { Wallet } from "../wallet.js";
|
import { Wallet } from "../wallet.js";
|
||||||
|
import { GlobalIDB } from "@gnu-taler/idb-bridge";
|
||||||
|
|
||||||
async function gatherExchangePending(
|
async function gatherExchangePending(
|
||||||
tx: GetReadOnlyAccess<{
|
tx: GetReadOnlyAccess<{
|
||||||
@ -120,7 +124,10 @@ async function gatherWithdrawalPending(
|
|||||||
resp: PendingOperationsResponse,
|
resp: PendingOperationsResponse,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const wsrs = await tx.withdrawalGroups.indexes.byStatus.getAll(
|
const wsrs = await tx.withdrawalGroups.indexes.byStatus.getAll(
|
||||||
OperationStatus.Pending,
|
GlobalIDB.KeyRange.bound(
|
||||||
|
OperationStatusRange.ACTIVE_START,
|
||||||
|
OperationStatusRange.ACTIVE_END,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
for (const wsr of wsrs) {
|
for (const wsr of wsrs) {
|
||||||
if (wsr.timestampFinish) {
|
if (wsr.timestampFinish) {
|
||||||
|
@ -44,7 +44,7 @@ import {
|
|||||||
CoinStatus,
|
CoinStatus,
|
||||||
RecoupGroupRecord,
|
RecoupGroupRecord,
|
||||||
RefreshCoinSource,
|
RefreshCoinSource,
|
||||||
ReserveRecordStatus,
|
WithdrawalGroupStatus,
|
||||||
WalletStoresV1,
|
WalletStoresV1,
|
||||||
WithdrawalRecordType,
|
WithdrawalRecordType,
|
||||||
WithdrawCoinSource,
|
WithdrawCoinSource,
|
||||||
@ -382,7 +382,7 @@ export async function processRecoupGroupHandler(
|
|||||||
await internalCreateWithdrawalGroup(ws, {
|
await internalCreateWithdrawalGroup(ws, {
|
||||||
amount: Amounts.parseOrThrow(result.balance),
|
amount: Amounts.parseOrThrow(result.balance),
|
||||||
exchangeBaseUrl: recoupGroup.exchangeBaseUrl,
|
exchangeBaseUrl: recoupGroup.exchangeBaseUrl,
|
||||||
reserveStatus: ReserveRecordStatus.QueryingStatus,
|
reserveStatus: WithdrawalGroupStatus.QueryingStatus,
|
||||||
reserveKeyPair: {
|
reserveKeyPair: {
|
||||||
pub: reservePub,
|
pub: reservePub,
|
||||||
priv: reservePrivMap[reservePub],
|
priv: reservePrivMap[reservePub],
|
||||||
|
@ -31,11 +31,9 @@ import {
|
|||||||
TalerProtocolTimestamp,
|
TalerProtocolTimestamp,
|
||||||
Transaction,
|
Transaction,
|
||||||
TransactionByIdRequest,
|
TransactionByIdRequest,
|
||||||
TransactionRefund,
|
|
||||||
TransactionsRequest,
|
TransactionsRequest,
|
||||||
TransactionsResponse,
|
TransactionsResponse,
|
||||||
TransactionType,
|
TransactionType,
|
||||||
WithdrawalDetails,
|
|
||||||
WithdrawalType,
|
WithdrawalType,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import {
|
import {
|
||||||
|
@ -71,7 +71,7 @@ import {
|
|||||||
ExchangeRecord,
|
ExchangeRecord,
|
||||||
OperationStatus,
|
OperationStatus,
|
||||||
PlanchetRecord,
|
PlanchetRecord,
|
||||||
ReserveRecordStatus,
|
WithdrawalGroupStatus,
|
||||||
WalletStoresV1,
|
WalletStoresV1,
|
||||||
WgInfo,
|
WgInfo,
|
||||||
WithdrawalGroupRecord,
|
WithdrawalGroupRecord,
|
||||||
@ -91,7 +91,11 @@ import {
|
|||||||
readSuccessResponseJsonOrThrow,
|
readSuccessResponseJsonOrThrow,
|
||||||
throwUnexpectedRequestError,
|
throwUnexpectedRequestError,
|
||||||
} from "../util/http.js";
|
} from "../util/http.js";
|
||||||
import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
|
import {
|
||||||
|
checkDbInvariant,
|
||||||
|
checkLogicInvariant,
|
||||||
|
InvariantViolatedError,
|
||||||
|
} from "../util/invariants.js";
|
||||||
import { DbAccess, GetReadOnlyAccess } from "../util/query.js";
|
import { DbAccess, GetReadOnlyAccess } from "../util/query.js";
|
||||||
import {
|
import {
|
||||||
OperationAttemptResult,
|
OperationAttemptResult,
|
||||||
@ -962,7 +966,7 @@ async function queryReserve(
|
|||||||
withdrawalGroupId,
|
withdrawalGroupId,
|
||||||
});
|
});
|
||||||
checkDbInvariant(!!withdrawalGroup);
|
checkDbInvariant(!!withdrawalGroup);
|
||||||
if (withdrawalGroup.reserveStatus !== ReserveRecordStatus.QueryingStatus) {
|
if (withdrawalGroup.status !== WithdrawalGroupStatus.QueryingStatus) {
|
||||||
return { ready: true };
|
return { ready: true };
|
||||||
}
|
}
|
||||||
const reservePub = withdrawalGroup.reservePub;
|
const reservePub = withdrawalGroup.reservePub;
|
||||||
@ -1010,7 +1014,7 @@ async function queryReserve(
|
|||||||
logger.warn(`withdrawal group ${withdrawalGroupId} not found`);
|
logger.warn(`withdrawal group ${withdrawalGroupId} not found`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wg.reserveStatus = ReserveRecordStatus.Dormant;
|
wg.status = WithdrawalGroupStatus.Finished;
|
||||||
await tx.withdrawalGroups.put(wg);
|
await tx.withdrawalGroups.put(wg);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1039,13 +1043,13 @@ export async function processWithdrawalGroup(
|
|||||||
throw Error(`withdrawal group ${withdrawalGroupId} not found`);
|
throw Error(`withdrawal group ${withdrawalGroupId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (withdrawalGroup.reserveStatus) {
|
switch (withdrawalGroup.status) {
|
||||||
case ReserveRecordStatus.RegisteringBank:
|
case WithdrawalGroupStatus.RegisteringBank:
|
||||||
await processReserveBankStatus(ws, withdrawalGroupId);
|
await processReserveBankStatus(ws, withdrawalGroupId);
|
||||||
return await processWithdrawalGroup(ws, withdrawalGroupId, {
|
return await processWithdrawalGroup(ws, withdrawalGroupId, {
|
||||||
forceNow: true,
|
forceNow: true,
|
||||||
});
|
});
|
||||||
case ReserveRecordStatus.QueryingStatus: {
|
case WithdrawalGroupStatus.QueryingStatus: {
|
||||||
const res = await queryReserve(ws, withdrawalGroupId);
|
const res = await queryReserve(ws, withdrawalGroupId);
|
||||||
if (res.ready) {
|
if (res.ready) {
|
||||||
return await processWithdrawalGroup(ws, withdrawalGroupId, {
|
return await processWithdrawalGroup(ws, withdrawalGroupId, {
|
||||||
@ -1057,7 +1061,7 @@ export async function processWithdrawalGroup(
|
|||||||
result: undefined,
|
result: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case ReserveRecordStatus.WaitConfirmBank: {
|
case WithdrawalGroupStatus.WaitConfirmBank: {
|
||||||
const res = await processReserveBankStatus(ws, withdrawalGroupId);
|
const res = await processReserveBankStatus(ws, withdrawalGroupId);
|
||||||
switch (res.status) {
|
switch (res.status) {
|
||||||
case BankStatusResultCode.Aborted:
|
case BankStatusResultCode.Aborted:
|
||||||
@ -1075,23 +1079,20 @@ export async function processWithdrawalGroup(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ReserveRecordStatus.BankAborted: {
|
case WithdrawalGroupStatus.BankAborted: {
|
||||||
// FIXME
|
// FIXME
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Pending,
|
type: OperationAttemptResultType.Pending,
|
||||||
result: undefined,
|
result: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case ReserveRecordStatus.Dormant:
|
case WithdrawalGroupStatus.Finished:
|
||||||
// We can try to withdraw, nothing needs to be done with the reserve.
|
// We can try to withdraw, nothing needs to be done with the reserve.
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.warn(
|
throw new InvariantViolatedError(
|
||||||
"unknown reserve record status:",
|
`unknown reserve record status: ${withdrawalGroup.status}`,
|
||||||
withdrawalGroup.reserveStatus,
|
|
||||||
);
|
);
|
||||||
assertUnreachable(withdrawalGroup.reserveStatus);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await ws.exchangeOps.updateExchangeFromUrl(
|
await ws.exchangeOps.updateExchangeFromUrl(
|
||||||
@ -1108,7 +1109,7 @@ export async function processWithdrawalGroup(
|
|||||||
if (!wg) {
|
if (!wg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wg.operationStatus = OperationStatus.Finished;
|
wg.status = WithdrawalGroupStatus.Finished;
|
||||||
wg.timestampFinish = TalerProtocolTimestamp.now();
|
wg.timestampFinish = TalerProtocolTimestamp.now();
|
||||||
await tx.withdrawalGroups.put(wg);
|
await tx.withdrawalGroups.put(wg);
|
||||||
});
|
});
|
||||||
@ -1192,7 +1193,7 @@ export async function processWithdrawalGroup(
|
|||||||
if (wg.timestampFinish === undefined && numFinished === numTotalCoins) {
|
if (wg.timestampFinish === undefined && numFinished === numTotalCoins) {
|
||||||
finishedForFirstTime = true;
|
finishedForFirstTime = true;
|
||||||
wg.timestampFinish = TalerProtocolTimestamp.now();
|
wg.timestampFinish = TalerProtocolTimestamp.now();
|
||||||
wg.operationStatus = OperationStatus.Finished;
|
wg.status = WithdrawalGroupStatus.Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
await tx.withdrawalGroups.put(wg);
|
await tx.withdrawalGroups.put(wg);
|
||||||
@ -1508,9 +1509,9 @@ async function registerReserveWithBank(
|
|||||||
.runReadOnly(async (tx) => {
|
.runReadOnly(async (tx) => {
|
||||||
return await tx.withdrawalGroups.get(withdrawalGroupId);
|
return await tx.withdrawalGroups.get(withdrawalGroupId);
|
||||||
});
|
});
|
||||||
switch (withdrawalGroup?.reserveStatus) {
|
switch (withdrawalGroup?.status) {
|
||||||
case ReserveRecordStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.WaitConfirmBank:
|
||||||
case ReserveRecordStatus.RegisteringBank:
|
case WithdrawalGroupStatus.RegisteringBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1544,9 +1545,9 @@ async function registerReserveWithBank(
|
|||||||
if (!r) {
|
if (!r) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (r.reserveStatus) {
|
switch (r.status) {
|
||||||
case ReserveRecordStatus.RegisteringBank:
|
case WithdrawalGroupStatus.RegisteringBank:
|
||||||
case ReserveRecordStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.WaitConfirmBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1557,8 +1558,7 @@ async function registerReserveWithBank(
|
|||||||
r.wgInfo.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toTimestamp(
|
r.wgInfo.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toTimestamp(
|
||||||
AbsoluteTime.now(),
|
AbsoluteTime.now(),
|
||||||
);
|
);
|
||||||
r.reserveStatus = ReserveRecordStatus.WaitConfirmBank;
|
r.status = WithdrawalGroupStatus.WaitConfirmBank;
|
||||||
r.operationStatus = OperationStatus.Pending;
|
|
||||||
await tx.withdrawalGroups.put(r);
|
await tx.withdrawalGroups.put(r);
|
||||||
});
|
});
|
||||||
ws.notify({ type: NotificationType.ReserveRegisteredWithBank });
|
ws.notify({ type: NotificationType.ReserveRegisteredWithBank });
|
||||||
@ -1575,9 +1575,9 @@ async function processReserveBankStatus(
|
|||||||
const withdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, {
|
const withdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, {
|
||||||
withdrawalGroupId,
|
withdrawalGroupId,
|
||||||
});
|
});
|
||||||
switch (withdrawalGroup?.reserveStatus) {
|
switch (withdrawalGroup?.status) {
|
||||||
case ReserveRecordStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.WaitConfirmBank:
|
||||||
case ReserveRecordStatus.RegisteringBank:
|
case WithdrawalGroupStatus.RegisteringBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
@ -1616,9 +1616,9 @@ async function processReserveBankStatus(
|
|||||||
if (!r) {
|
if (!r) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (r.reserveStatus) {
|
switch (r.status) {
|
||||||
case ReserveRecordStatus.RegisteringBank:
|
case WithdrawalGroupStatus.RegisteringBank:
|
||||||
case ReserveRecordStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.WaitConfirmBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1628,8 +1628,7 @@ async function processReserveBankStatus(
|
|||||||
}
|
}
|
||||||
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
|
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
|
||||||
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
||||||
r.reserveStatus = ReserveRecordStatus.BankAborted;
|
r.status = WithdrawalGroupStatus.BankAborted;
|
||||||
r.operationStatus = OperationStatus.Finished;
|
|
||||||
await tx.withdrawalGroups.put(r);
|
await tx.withdrawalGroups.put(r);
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
@ -1644,7 +1643,7 @@ async function processReserveBankStatus(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Why do we do this?!
|
// FIXME: Why do we do this?!
|
||||||
if (withdrawalGroup.reserveStatus === ReserveRecordStatus.RegisteringBank) {
|
if (withdrawalGroup.status === WithdrawalGroupStatus.RegisteringBank) {
|
||||||
await registerReserveWithBank(ws, withdrawalGroupId);
|
await registerReserveWithBank(ws, withdrawalGroupId);
|
||||||
return await processReserveBankStatus(ws, withdrawalGroupId);
|
return await processReserveBankStatus(ws, withdrawalGroupId);
|
||||||
}
|
}
|
||||||
@ -1657,9 +1656,9 @@ async function processReserveBankStatus(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Re-check reserve status within transaction
|
// Re-check reserve status within transaction
|
||||||
switch (r.reserveStatus) {
|
switch (r.status) {
|
||||||
case ReserveRecordStatus.RegisteringBank:
|
case WithdrawalGroupStatus.RegisteringBank:
|
||||||
case ReserveRecordStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.WaitConfirmBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1671,8 +1670,7 @@ async function processReserveBankStatus(
|
|||||||
logger.info("withdrawal: transfer confirmed by bank.");
|
logger.info("withdrawal: transfer confirmed by bank.");
|
||||||
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
|
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
|
||||||
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
||||||
r.reserveStatus = ReserveRecordStatus.QueryingStatus;
|
r.status = WithdrawalGroupStatus.QueryingStatus;
|
||||||
r.operationStatus = OperationStatus.Pending;
|
|
||||||
} else {
|
} else {
|
||||||
logger.info("withdrawal: transfer not yet confirmed by bank");
|
logger.info("withdrawal: transfer not yet confirmed by bank");
|
||||||
r.wgInfo.bankInfo.confirmUrl = status.confirm_transfer_url;
|
r.wgInfo.bankInfo.confirmUrl = status.confirm_transfer_url;
|
||||||
@ -1689,7 +1687,7 @@ async function processReserveBankStatus(
|
|||||||
export async function internalCreateWithdrawalGroup(
|
export async function internalCreateWithdrawalGroup(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
args: {
|
args: {
|
||||||
reserveStatus: ReserveRecordStatus;
|
reserveStatus: WithdrawalGroupStatus;
|
||||||
amount: AmountJson;
|
amount: AmountJson;
|
||||||
exchangeBaseUrl: string;
|
exchangeBaseUrl: string;
|
||||||
forcedDenomSel?: ForcedDenomSel;
|
forcedDenomSel?: ForcedDenomSel;
|
||||||
@ -1728,12 +1726,11 @@ export async function internalCreateWithdrawalGroup(
|
|||||||
exchangeBaseUrl: canonExchange,
|
exchangeBaseUrl: canonExchange,
|
||||||
instructedAmount: amount,
|
instructedAmount: amount,
|
||||||
timestampStart: now,
|
timestampStart: now,
|
||||||
operationStatus: OperationStatus.Pending,
|
|
||||||
rawWithdrawalAmount: initialDenomSel.totalWithdrawCost,
|
rawWithdrawalAmount: initialDenomSel.totalWithdrawCost,
|
||||||
secretSeed,
|
secretSeed,
|
||||||
reservePriv: reserveKeyPair.priv,
|
reservePriv: reserveKeyPair.priv,
|
||||||
reservePub: reserveKeyPair.pub,
|
reservePub: reserveKeyPair.pub,
|
||||||
reserveStatus: args.reserveStatus,
|
status: args.reserveStatus,
|
||||||
withdrawalGroupId,
|
withdrawalGroupId,
|
||||||
restrictAge: args.restrictAge,
|
restrictAge: args.restrictAge,
|
||||||
senderWire: undefined,
|
senderWire: undefined,
|
||||||
@ -1839,7 +1836,7 @@ export async function acceptWithdrawalFromUri(
|
|||||||
},
|
},
|
||||||
restrictAge: req.restrictAge,
|
restrictAge: req.restrictAge,
|
||||||
forcedDenomSel: req.forcedDenomSel,
|
forcedDenomSel: req.forcedDenomSel,
|
||||||
reserveStatus: ReserveRecordStatus.RegisteringBank,
|
reserveStatus: WithdrawalGroupStatus.RegisteringBank,
|
||||||
});
|
});
|
||||||
|
|
||||||
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
||||||
@ -1850,9 +1847,7 @@ export async function acceptWithdrawalFromUri(
|
|||||||
const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, {
|
const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, {
|
||||||
withdrawalGroupId,
|
withdrawalGroupId,
|
||||||
});
|
});
|
||||||
if (
|
if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.BankAborted) {
|
||||||
processedWithdrawalGroup?.reserveStatus === ReserveRecordStatus.BankAborted
|
|
||||||
) {
|
|
||||||
throw TalerError.fromDetail(
|
throw TalerError.fromDetail(
|
||||||
TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK,
|
TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK,
|
||||||
{},
|
{},
|
||||||
@ -1898,7 +1893,7 @@ export async function createManualWithdrawal(
|
|||||||
exchangeBaseUrl: req.exchangeBaseUrl,
|
exchangeBaseUrl: req.exchangeBaseUrl,
|
||||||
forcedDenomSel: req.forcedDenomSel,
|
forcedDenomSel: req.forcedDenomSel,
|
||||||
restrictAge: req.restrictAge,
|
restrictAge: req.restrictAge,
|
||||||
reserveStatus: ReserveRecordStatus.QueryingStatus,
|
reserveStatus: WithdrawalGroupStatus.QueryingStatus,
|
||||||
});
|
});
|
||||||
|
|
||||||
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
||||||
|
@ -14,6 +14,13 @@
|
|||||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export class InvariantViolatedError extends Error {
|
||||||
|
constructor(message?: string) {
|
||||||
|
super(message);
|
||||||
|
Object.setPrototypeOf(this, InvariantViolatedError.prototype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helpers for invariants.
|
* Helpers for invariants.
|
||||||
*/
|
*/
|
||||||
|
@ -36,8 +36,6 @@ import {
|
|||||||
IDBKeyRange,
|
IDBKeyRange,
|
||||||
} from "@gnu-taler/idb-bridge";
|
} from "@gnu-taler/idb-bridge";
|
||||||
import { Logger } from "@gnu-taler/taler-util";
|
import { Logger } from "@gnu-taler/taler-util";
|
||||||
import { performanceNow } from "./timer.js";
|
|
||||||
import { access } from "fs";
|
|
||||||
|
|
||||||
const logger = new Logger("query.ts");
|
const logger = new Logger("query.ts");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user