From cb2fbc7610bed39b98c2fdb18941a22ad6df81b3 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 16 Mar 2020 17:46:57 +0530 Subject: fix another withdrawal state machine bug, add 'show-reserve' to advanced CLI --- src/headless/taler-wallet-cli.ts | 14 +++++++++- src/operations/reserves.ts | 57 ++++++++++++++++++++++------------------ src/wallet.ts | 4 +++ 3 files changed, 48 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/headless/taler-wallet-cli.ts b/src/headless/taler-wallet-cli.ts index 2a1040630..4518d601e 100644 --- a/src/headless/taler-wallet-cli.ts +++ b/src/headless/taler-wallet-cli.ts @@ -374,7 +374,7 @@ advancedCli }); }); - advancedCli +advancedCli .subcommand("updateReserve", "update-reserve", { help: "Update reserve status.", }) @@ -386,6 +386,18 @@ advancedCli }); }); +advancedCli + .subcommand("updateReserve", "show-reserve", { + help: "Show the current reserve status.", + }) + .requiredArgument("reservePub", clk.STRING) + .action(async args => { + await withWallet(args, async wallet => { + const r = await wallet.getReserve(args.updateReserve.reservePub); + console.log("updated reserve:", JSON.stringify(r, undefined, 2)); + }); + }); + const testCli = walletCli.subcommand("testingArgs", "testing", { help: "Subcommands for testing GNU Taler deployments.", }); diff --git a/src/operations/reserves.ts b/src/operations/reserves.ts index d19d069af..0daad8cc1 100644 --- a/src/operations/reserves.ts +++ b/src/operations/reserves.ts @@ -41,7 +41,10 @@ import { getExchangeTrust, getExchangePaytoUri, } from "./exchanges"; -import { WithdrawOperationStatusResponse, codecForWithdrawOperationStatusResponse } from "../types/talerTypes"; +import { + WithdrawOperationStatusResponse, + codecForWithdrawOperationStatusResponse, +} from "../types/talerTypes"; import { assertUnreachable } from "../util/assertUnreachable"; import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto"; import { randomBytes } from "../crypto/primitives/nacl-fast"; @@ -61,11 +64,7 @@ import { getTimestampNow } from "../util/time"; const logger = new Logger("reserves.ts"); - -async function resetReserveRetry( - ws: InternalWalletState, - reservePub: string, -) { +async function resetReserveRetry(ws: InternalWalletState, reservePub: string) { await ws.db.mutate(Stores.reserves, reservePub, x => { if (x.retryInfo.active) { x.retryInfo = initRetryInfo(); @@ -209,7 +208,7 @@ export async function forceQueryReserve( ws: InternalWalletState, reservePub: string, ): Promise { - await ws.db.runWithWriteTransaction([Stores.reserves], async (tx) => { + await ws.db.runWithWriteTransaction([Stores.reserves], async tx => { const reserve = await tx.get(Stores.reserves, reservePub); if (!reserve) { return; @@ -226,7 +225,6 @@ export async function forceQueryReserve( reserve.reserveStatus = ReserveRecordStatus.QUERYING_STATUS; reserve.retryInfo = initRetryInfo(); await tx.put(Stores.reserves, reserve); - }); await processReserve(ws, reservePub, true); } @@ -331,7 +329,9 @@ async function processReserveBankStatusImpl( `unexpected status ${statusResp.status} for bank status query`, ); } - status = codecForWithdrawOperationStatusResponse().decode(await statusResp.json()); + status = codecForWithdrawOperationStatusResponse().decode( + await statusResp.json(), + ); } catch (e) { throw e; } @@ -436,7 +436,7 @@ async function updateReserve( resp = await ws.http.get(reqUrl.href); console.log("got reserves/${RESERVE_PUB} response", await resp.json()); if (resp.status === 404) { - const m = "reserve not known to the exchange yet" + const m = "reserve not known to the exchange yet"; throw new OperationFailedError({ type: "waiting", message: m, @@ -492,17 +492,17 @@ async function updateReserve( await tx.put(Stores.reserveUpdatedEvents, reserveUpdate); r.reserveStatus = ReserveRecordStatus.WITHDRAWING; } else { - const expectedBalance = Amounts.sub( - r.amountWithdrawAllocated, - r.amountWithdrawCompleted, + const expectedBalance = Amounts.add( + r.amountWithdrawRemaining, + Amounts.sub(r.amountWithdrawAllocated, r.amountWithdrawCompleted) + .amount, ); const cmp = Amounts.cmp(balance, expectedBalance.amount); if (cmp == 0) { // Nothing changed, go back to sleep! r.reserveStatus = ReserveRecordStatus.DORMANT; - return; } - if (cmp > 0) { + else if (cmp > 0) { const extra = Amounts.sub(balance, expectedBalance.amount).amount; r.amountWithdrawRemaining = Amounts.add( r.amountWithdrawRemaining, @@ -513,23 +513,28 @@ async function updateReserve( // We're missing some money. r.reserveStatus = ReserveRecordStatus.DORMANT; } - const reserveUpdate: ReserveUpdatedEventRecord = { - reservePub: r.reservePub, - timestamp: getTimestampNow(), - amountReserveBalance: Amounts.toString(balance), - amountExpected: Amounts.toString(expectedBalance.amount), - newHistoryTransactions, - reserveUpdateId, - }; - await tx.put(Stores.reserveUpdatedEvents, reserveUpdate); + if (r.reserveStatus !== ReserveRecordStatus.DORMANT) { + const reserveUpdate: ReserveUpdatedEventRecord = { + reservePub: r.reservePub, + timestamp: getTimestampNow(), + amountReserveBalance: Amounts.toString(balance), + amountExpected: Amounts.toString(expectedBalance.amount), + newHistoryTransactions, + reserveUpdateId, + }; + await tx.put(Stores.reserveUpdatedEvents, reserveUpdate); + } } r.lastSuccessfulStatusQuery = getTimestampNow(); - r.retryInfo = initRetryInfo(); + if (r.reserveStatus == ReserveRecordStatus.DORMANT) { + r.retryInfo = initRetryInfo(false); + } else { + r.retryInfo = initRetryInfo(); + } r.reserveTransactions = reserveInfo.history; await tx.put(Stores.reserves, r); }, ); - console.log("updated reserve"); ws.notify({ type: NotificationType.ReserveUpdated }); } diff --git a/src/wallet.ts b/src/wallet.ts index 291143761..6245941a1 100644 --- a/src/wallet.ts +++ b/src/wallet.ts @@ -720,6 +720,10 @@ export class Wallet { return await this.ws.db.get(Stores.reserves, reservePub); } + async getReserve(reservePub: string): Promise { + return await this.ws.db.get(Stores.reserves, reservePub); + } + async refuseProposal(proposalId: string): Promise { return refuseProposal(this.ws, proposalId); } -- cgit v1.2.3