include (pending) wallet balance in pending ops response
This commit is contained in:
parent
7c7d3e001e
commit
4e76edf129
@ -18,7 +18,7 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { WalletBalance, WalletBalanceEntry } from "../types/walletTypes";
|
import { WalletBalance, WalletBalanceEntry } from "../types/walletTypes";
|
||||||
import { Database } from "../util/query";
|
import { Database, TransactionHandle } from "../util/query";
|
||||||
import { InternalWalletState } from "./state";
|
import { InternalWalletState } from "./state";
|
||||||
import { Stores, TipRecord, CoinStatus } from "../types/dbTypes";
|
import { Stores, TipRecord, CoinStatus } from "../types/dbTypes";
|
||||||
import * as Amounts from "../util/amounts";
|
import * as Amounts from "../util/amounts";
|
||||||
@ -28,12 +28,13 @@ import { Logger } from "../util/logging";
|
|||||||
const logger = new Logger("withdraw.ts");
|
const logger = new Logger("withdraw.ts");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get detailed balance information, sliced by exchange and by currency.
|
* Get balance information.
|
||||||
*/
|
*/
|
||||||
export async function getBalances(
|
export async function getBalancesInsideTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
|
tx: TransactionHandle,
|
||||||
): Promise<WalletBalance> {
|
): Promise<WalletBalance> {
|
||||||
logger.trace("starting to compute balance");
|
|
||||||
/**
|
/**
|
||||||
* Add amount to a balance field, both for
|
* Add amount to a balance field, both for
|
||||||
* the slicing by exchange and currency.
|
* the slicing by exchange and currency.
|
||||||
@ -73,9 +74,6 @@ export async function getBalances(
|
|||||||
byExchange: {},
|
byExchange: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
await ws.db.runWithReadTransaction(
|
|
||||||
[Stores.coins, Stores.refreshGroups, Stores.reserves, Stores.purchases, Stores.withdrawalSession],
|
|
||||||
async tx => {
|
|
||||||
await tx.iter(Stores.coins).forEach(c => {
|
await tx.iter(Stores.coins).forEach(c => {
|
||||||
if (c.suspended) {
|
if (c.suspended) {
|
||||||
return;
|
return;
|
||||||
@ -119,12 +117,7 @@ export async function getBalances(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addTo(
|
addTo(balanceStore, "pendingIncoming", w, wds.exchangeBaseUrl);
|
||||||
balanceStore,
|
|
||||||
"pendingIncoming",
|
|
||||||
w,
|
|
||||||
wds.exchangeBaseUrl,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.iter(Stores.purchases).forEach(t => {
|
await tx.iter(Stores.purchases).forEach(t => {
|
||||||
@ -140,9 +133,26 @@ export async function getBalances(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
logger.trace("computed balances:", balanceStore);
|
|
||||||
return balanceStore;
|
return balanceStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get detailed balance information, sliced by exchange and by currency.
|
||||||
|
*/
|
||||||
|
export async function getBalances(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
): Promise<WalletBalance> {
|
||||||
|
logger.trace("starting to compute balance");
|
||||||
|
|
||||||
|
return await ws.db.runWithReadTransaction([
|
||||||
|
Stores.coins,
|
||||||
|
Stores.refreshGroups,
|
||||||
|
Stores.reserves,
|
||||||
|
Stores.purchases,
|
||||||
|
Stores.withdrawalSession,
|
||||||
|
],
|
||||||
|
async tx => {
|
||||||
|
return getBalancesInsideTransaction(ws, tx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -28,9 +28,16 @@ import {
|
|||||||
PendingOperationType,
|
PendingOperationType,
|
||||||
ExchangeUpdateOperationStage,
|
ExchangeUpdateOperationStage,
|
||||||
} from "../types/pending";
|
} from "../types/pending";
|
||||||
import { Duration, getTimestampNow, Timestamp, getDurationRemaining, durationMin } from "../util/time";
|
import {
|
||||||
|
Duration,
|
||||||
|
getTimestampNow,
|
||||||
|
Timestamp,
|
||||||
|
getDurationRemaining,
|
||||||
|
durationMin,
|
||||||
|
} from "../util/time";
|
||||||
import { TransactionHandle } from "../util/query";
|
import { TransactionHandle } from "../util/query";
|
||||||
import { InternalWalletState } from "./state";
|
import { InternalWalletState } from "./state";
|
||||||
|
import { getBalances, getBalancesInsideTransaction } from "./balance";
|
||||||
|
|
||||||
function updateRetryDelay(
|
function updateRetryDelay(
|
||||||
oldDelay: Duration,
|
oldDelay: Duration,
|
||||||
@ -400,15 +407,10 @@ async function gatherPurchasePending(
|
|||||||
|
|
||||||
export async function getPendingOperations(
|
export async function getPendingOperations(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
onlyDue: boolean = false,
|
{ onlyDue = false } = {},
|
||||||
): Promise<PendingOperationsResponse> {
|
): Promise<PendingOperationsResponse> {
|
||||||
const resp: PendingOperationsResponse = {
|
|
||||||
nextRetryDelay: { d_ms: Number.MAX_SAFE_INTEGER },
|
|
||||||
onlyDue: onlyDue,
|
|
||||||
pendingOperations: [],
|
|
||||||
};
|
|
||||||
const now = getTimestampNow();
|
const now = getTimestampNow();
|
||||||
await ws.db.runWithReadTransaction(
|
return await ws.db.runWithReadTransaction(
|
||||||
[
|
[
|
||||||
Stores.exchanges,
|
Stores.exchanges,
|
||||||
Stores.reserves,
|
Stores.reserves,
|
||||||
@ -420,6 +422,13 @@ export async function getPendingOperations(
|
|||||||
Stores.purchases,
|
Stores.purchases,
|
||||||
],
|
],
|
||||||
async tx => {
|
async tx => {
|
||||||
|
const walletBalance = await getBalancesInsideTransaction(ws, tx);
|
||||||
|
const resp: PendingOperationsResponse = {
|
||||||
|
nextRetryDelay: { d_ms: Number.MAX_SAFE_INTEGER },
|
||||||
|
onlyDue: onlyDue,
|
||||||
|
walletBalance,
|
||||||
|
pendingOperations: [],
|
||||||
|
};
|
||||||
await gatherExchangePending(tx, now, resp, onlyDue);
|
await gatherExchangePending(tx, now, resp, onlyDue);
|
||||||
await gatherReservePending(tx, now, resp, onlyDue);
|
await gatherReservePending(tx, now, resp, onlyDue);
|
||||||
await gatherRefreshPending(tx, now, resp, onlyDue);
|
await gatherRefreshPending(tx, now, resp, onlyDue);
|
||||||
@ -427,7 +436,7 @@ export async function getPendingOperations(
|
|||||||
await gatherProposalPending(tx, now, resp, onlyDue);
|
await gatherProposalPending(tx, now, resp, onlyDue);
|
||||||
await gatherTipPending(tx, now, resp, onlyDue);
|
await gatherTipPending(tx, now, resp, onlyDue);
|
||||||
await gatherPurchasePending(tx, now, resp, onlyDue);
|
await gatherPurchasePending(tx, now, resp, onlyDue);
|
||||||
|
return resp;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return resp;
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { OperationError } from "./walletTypes";
|
import { OperationError, WalletBalance } from "./walletTypes";
|
||||||
import { WithdrawalSource, RetryInfo, ReserveRecordStatus } from "./dbTypes";
|
import { WithdrawalSource, RetryInfo, ReserveRecordStatus } from "./dbTypes";
|
||||||
import { Timestamp, Duration } from "../util/time";
|
import { Timestamp, Duration } from "../util/time";
|
||||||
|
|
||||||
@ -231,7 +231,19 @@ export interface PendingOperationInfoCommon {
|
|||||||
* Response returned from the pending operations API.
|
* Response returned from the pending operations API.
|
||||||
*/
|
*/
|
||||||
export interface PendingOperationsResponse {
|
export interface PendingOperationsResponse {
|
||||||
|
/**
|
||||||
|
* List of pending operations.
|
||||||
|
*/
|
||||||
pendingOperations: PendingOperationInfo[];
|
pendingOperations: PendingOperationInfo[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current wallet balance, including pending balances.
|
||||||
|
*/
|
||||||
|
walletBalance: WalletBalance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When is the next pending operation due to be re-tried?
|
||||||
|
*/
|
||||||
nextRetryDelay: Duration;
|
nextRetryDelay: Duration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,7 +82,10 @@ import {
|
|||||||
getExchangePaytoUri,
|
getExchangePaytoUri,
|
||||||
acceptExchangeTermsOfService,
|
acceptExchangeTermsOfService,
|
||||||
} from "./operations/exchanges";
|
} from "./operations/exchanges";
|
||||||
import { processReserve, createTalerWithdrawReserve } from "./operations/reserves";
|
import {
|
||||||
|
processReserve,
|
||||||
|
createTalerWithdrawReserve,
|
||||||
|
} from "./operations/reserves";
|
||||||
|
|
||||||
import { InternalWalletState } from "./operations/state";
|
import { InternalWalletState } from "./operations/state";
|
||||||
import { createReserve, confirmReserve } from "./operations/reserves";
|
import { createReserve, confirmReserve } from "./operations/reserves";
|
||||||
@ -111,7 +114,6 @@ import {
|
|||||||
} from "./operations/refund";
|
} from "./operations/refund";
|
||||||
import { durationMin, Duration } from "./util/time";
|
import { durationMin, Duration } from "./util/time";
|
||||||
|
|
||||||
|
|
||||||
const builtinCurrencies: CurrencyRecord[] = [
|
const builtinCurrencies: CurrencyRecord[] = [
|
||||||
{
|
{
|
||||||
auditors: [
|
auditors: [
|
||||||
@ -225,7 +227,7 @@ export class Wallet {
|
|||||||
*/
|
*/
|
||||||
public async runPending(forceNow: boolean = false): Promise<void> {
|
public async runPending(forceNow: boolean = false): Promise<void> {
|
||||||
const onlyDue = !forceNow;
|
const onlyDue = !forceNow;
|
||||||
const pendingOpsResponse = await this.getPendingOperations(onlyDue);
|
const pendingOpsResponse = await this.getPendingOperations({ onlyDue });
|
||||||
for (const p of pendingOpsResponse.pendingOperations) {
|
for (const p of pendingOpsResponse.pendingOperations) {
|
||||||
try {
|
try {
|
||||||
await this.processOnePendingOperation(p, forceNow);
|
await this.processOnePendingOperation(p, forceNow);
|
||||||
@ -304,10 +306,10 @@ export class Wallet {
|
|||||||
private async runRetryLoopImpl(): Promise<void> {
|
private async runRetryLoopImpl(): Promise<void> {
|
||||||
while (!this.stopped) {
|
while (!this.stopped) {
|
||||||
console.log("running wallet retry loop iteration");
|
console.log("running wallet retry loop iteration");
|
||||||
let pending = await this.getPendingOperations(true);
|
let pending = await this.getPendingOperations({ onlyDue: true });
|
||||||
console.log("pending ops", JSON.stringify(pending, undefined, 2));
|
console.log("pending ops", JSON.stringify(pending, undefined, 2));
|
||||||
if (pending.pendingOperations.length === 0) {
|
if (pending.pendingOperations.length === 0) {
|
||||||
const allPending = await this.getPendingOperations(false);
|
const allPending = await this.getPendingOperations({ onlyDue: false });
|
||||||
let numPending = 0;
|
let numPending = 0;
|
||||||
let numGivingLiveness = 0;
|
let numGivingLiveness = 0;
|
||||||
for (const p of allPending.pendingOperations) {
|
for (const p of allPending.pendingOperations) {
|
||||||
@ -524,11 +526,11 @@ export class Wallet {
|
|||||||
return getHistory(this.ws, historyQuery);
|
return getHistory(this.ws, historyQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPendingOperations(
|
async getPendingOperations({ onlyDue = false } = {}): Promise<
|
||||||
onlyDue: boolean = false,
|
PendingOperationsResponse
|
||||||
): Promise<PendingOperationsResponse> {
|
> {
|
||||||
return this.ws.memoGetPending.memo(() =>
|
return this.ws.memoGetPending.memo(() =>
|
||||||
getPendingOperations(this.ws, onlyDue),
|
getPendingOperations(this.ws, { onlyDue }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,7 +704,11 @@ export class Wallet {
|
|||||||
selectedExchange: string,
|
selectedExchange: string,
|
||||||
): Promise<AcceptWithdrawalResponse> {
|
): Promise<AcceptWithdrawalResponse> {
|
||||||
try {
|
try {
|
||||||
return createTalerWithdrawReserve(this.ws, talerWithdrawUri, selectedExchange);
|
return createTalerWithdrawReserve(
|
||||||
|
this.ws,
|
||||||
|
talerWithdrawUri,
|
||||||
|
selectedExchange,
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
this.latch.trigger();
|
this.latch.trigger();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user