From c2ee8fd9ab6754275d7423152681236a46cf36a9 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 16 Dec 2019 16:59:09 +0100 Subject: cleanup, avoid some circular deps --- src/operations/exchanges.ts | 2 +- src/operations/reserves.ts | 34 +++++++++++++++++++- src/operations/tip.ts | 78 +++++++++++++++++++++++++++++---------------- src/operations/versions.ts | 32 +++++++++++++++++++ src/operations/withdraw.ts | 42 +++--------------------- 5 files changed, 121 insertions(+), 67 deletions(-) create mode 100644 src/operations/versions.ts (limited to 'src/operations') diff --git a/src/operations/exchanges.ts b/src/operations/exchanges.ts index 871ee1138..d9adc7c52 100644 --- a/src/operations/exchanges.ts +++ b/src/operations/exchanges.ts @@ -15,7 +15,6 @@ */ import { InternalWalletState } from "./state"; -import { WALLET_CACHE_BREAKER_CLIENT_VERSION } from "../wallet"; import { KeysJson, Denomination, ExchangeWireJson } from "../types/talerTypes"; import { getTimestampNow, OperationError } from "../types/walletTypes"; import { @@ -40,6 +39,7 @@ import { OperationFailedAndReportedError, guardOperationException, } from "./errors"; +import { WALLET_CACHE_BREAKER_CLIENT_VERSION } from "./versions"; async function denominationRecordFromKeys( ws: InternalWalletState, diff --git a/src/operations/reserves.ts b/src/operations/reserves.ts index 7b0a6886e..649bf75f2 100644 --- a/src/operations/reserves.ts +++ b/src/operations/reserves.ts @@ -20,6 +20,7 @@ import { getTimestampNow, ConfirmReserveRequest, OperationError, + AcceptWithdrawalResponse, } from "../types/walletTypes"; import { canonicalizeBaseUrl } from "../util/helpers"; import { InternalWalletState } from "./state"; @@ -38,7 +39,7 @@ import { } from "../util/query"; import { Logger } from "../util/logging"; import * as Amounts from "../util/amounts"; -import { updateExchangeFromUrl, getExchangeTrust } from "./exchanges"; +import { updateExchangeFromUrl, getExchangeTrust, getExchangePaytoUri } from "./exchanges"; import { WithdrawOperationStatusResponse } from "../types/talerTypes"; import { assertUnreachable } from "../util/assertUnreachable"; import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto"; @@ -46,6 +47,7 @@ import { randomBytes } from "../crypto/primitives/nacl-fast"; import { getVerifiedWithdrawDenomList, processWithdrawSession, + getBankWithdrawalInfo, } from "./withdraw"; import { guardOperationException, OperationFailedAndReportedError } from "./errors"; import { NotificationType } from "../types/notifications"; @@ -652,3 +654,33 @@ async function depleteReserve( console.trace("withdraw session already existed"); } } + + + +export async function createTalerWithdrawReserve( + ws: InternalWalletState, + talerWithdrawUri: string, + selectedExchange: string, +): Promise { + const withdrawInfo = await getBankWithdrawalInfo(ws, talerWithdrawUri); + const exchangeWire = await getExchangePaytoUri( + ws, + selectedExchange, + withdrawInfo.wireTypes, + ); + const reserve = await createReserve(ws, { + amount: withdrawInfo.amount, + bankWithdrawStatusUrl: withdrawInfo.extractedStatusUrl, + exchange: selectedExchange, + senderWire: withdrawInfo.senderWire, + exchangeWire: exchangeWire, + }); + // We do this here, as the reserve should be registered before we return, + // so that we can redirect the user to the bank's status page. + await processReserveBankStatus(ws, reserve.reservePub); + console.log("acceptWithdrawal: returning"); + return { + reservePub: reserve.reservePub, + confirmTransferUrl: withdrawInfo.confirmTransferUrl, + }; +} \ No newline at end of file diff --git a/src/operations/tip.ts b/src/operations/tip.ts index df4b7990e..76d0df22d 100644 --- a/src/operations/tip.ts +++ b/src/operations/tip.ts @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2019 GNUnet e.V. + (C) 2019 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -14,24 +14,41 @@ GNU Taler; see the file COPYING. If not, see */ - import { InternalWalletState } from "./state"; import { parseTipUri } from "../util/taleruri"; -import { TipStatus, getTimestampNow, OperationError } from "../types/walletTypes"; -import { TipPickupGetResponse, TipPlanchetDetail, TipResponse } from "../types/talerTypes"; +import { + TipStatus, + getTimestampNow, + OperationError, +} from "../types/walletTypes"; +import { + TipPickupGetResponse, + TipPlanchetDetail, + TipResponse, +} from "../types/talerTypes"; import * as Amounts from "../util/amounts"; -import { Stores, PlanchetRecord, WithdrawalSessionRecord, initRetryInfo, updateRetryInfoTimeout } from "../types/dbTypes"; -import { getExchangeWithdrawalInfo, getVerifiedWithdrawDenomList, processWithdrawSession } from "./withdraw"; +import { + Stores, + PlanchetRecord, + WithdrawalSessionRecord, + initRetryInfo, + updateRetryInfoTimeout, +} from "../types/dbTypes"; +import { + getExchangeWithdrawalInfo, + getVerifiedWithdrawDenomList, + processWithdrawSession, +} from "./withdraw"; import { getTalerStampSec, extractTalerStampOrThrow } from "../util/helpers"; import { updateExchangeFromUrl } from "./exchanges"; import { getRandomBytes, encodeCrock } from "../crypto/talerCrypto"; import { guardOperationException } from "./errors"; import { NotificationType } from "../types/notifications"; - export async function getTipStatus( ws: InternalWalletState, - talerTipUri: string): Promise { + talerTipUri: string, +): Promise { const res = parseTipUri(talerTipUri); if (!res) { throw Error("invalid taler://tip URI"); @@ -134,19 +151,22 @@ export async function processTip( forceNow: boolean = false, ): Promise { const onOpErr = (e: OperationError) => incrementTipRetry(ws, tipId, e); - await guardOperationException(() => processTipImpl(ws, tipId, forceNow), onOpErr); + await guardOperationException( + () => processTipImpl(ws, tipId, forceNow), + onOpErr, + ); } async function resetTipRetry( ws: InternalWalletState, tipId: string, ): Promise { - await ws.db.mutate(Stores.tips, tipId, (x) => { + await ws.db.mutate(Stores.tips, tipId, x => { if (x.retryInfo.active) { x.retryInfo = initRetryInfo(); } return x; - }) + }); } async function processTipImpl( @@ -248,7 +268,7 @@ async function processTipImpl( const withdrawalSessionId = encodeCrock(getRandomBytes(32)); const withdrawalSession: WithdrawalSessionRecord = { - denoms: planchets.map((x) => x.denomPub), + denoms: planchets.map(x => x.denomPub), exchangeBaseUrl: tipRecord.exchangeUrl, planchets: planchets, source: { @@ -258,29 +278,31 @@ async function processTipImpl( timestampStart: getTimestampNow(), withdrawSessionId: withdrawalSessionId, rawWithdrawalAmount: tipRecord.amount, - withdrawn: planchets.map((x) => false), - totalCoinValue: Amounts.sum(planchets.map((p) => p.coinValue)).amount, + withdrawn: planchets.map(x => false), + totalCoinValue: Amounts.sum(planchets.map(p => p.coinValue)).amount, lastErrorPerCoin: {}, retryInfo: initRetryInfo(), timestampFinish: undefined, lastError: undefined, }; + await ws.db.runWithWriteTransaction( + [Stores.tips, Stores.withdrawalSession], + async tx => { + const tr = await tx.get(Stores.tips, tipId); + if (!tr) { + return; + } + if (tr.pickedUp) { + return; + } + tr.pickedUp = true; + tr.retryInfo = initRetryInfo(false); - await ws.db.runWithWriteTransaction([Stores.tips, Stores.withdrawalSession], async (tx) => { - const tr = await tx.get(Stores.tips, tipId); - if (!tr) { - return; - } - if (tr.pickedUp) { - return; - } - tr.pickedUp = true; - tr.retryInfo = initRetryInfo(false); - - await tx.put(Stores.tips, tr); - await tx.put(Stores.withdrawalSession, withdrawalSession); - }); + await tx.put(Stores.tips, tr); + await tx.put(Stores.withdrawalSession, withdrawalSession); + }, + ); await processWithdrawSession(ws, withdrawalSessionId); diff --git a/src/operations/versions.ts b/src/operations/versions.ts new file mode 100644 index 000000000..393bdd887 --- /dev/null +++ b/src/operations/versions.ts @@ -0,0 +1,32 @@ +/* + This file is part of GNU Taler + (C) 2019 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * Wallet protocol version spoken with the exchange + * and merchant. + * + * Uses libtool's current:revision:age versioning. + */ +export const WALLET_EXCHANGE_PROTOCOL_VERSION = "6"; + +/** + * Cache breaker that is appended to queries such as /keys and /wire + * to break through caching, if it has been accidentally/badly configured + * by the exchange. + * + * This is only a temporary measure. + */ +export const WALLET_CACHE_BREAKER_CLIENT_VERSION = "3"; \ No newline at end of file diff --git a/src/operations/withdraw.ts b/src/operations/withdraw.ts index 6e7cdf512..38baffa8d 100644 --- a/src/operations/withdraw.ts +++ b/src/operations/withdraw.ts @@ -38,16 +38,11 @@ import { WithdrawOperationStatusResponse } from "../types/talerTypes"; import { InternalWalletState } from "./state"; import { parseWithdrawUri } from "../util/taleruri"; import { Logger } from "../util/logging"; -import { - Database -} from "../util/query"; import { updateExchangeFromUrl, - getExchangePaytoUri, getExchangeTrust, } from "./exchanges"; -import { createReserve, processReserveBankStatus } from "./reserves"; -import { WALLET_PROTOCOL_VERSION } from "../wallet"; +import { WALLET_EXCHANGE_PROTOCOL_VERSION } from "./versions"; import * as LibtoolVersion from "../util/libtoolVersion"; import { guardOperationException } from "./errors"; @@ -103,7 +98,7 @@ export function getWithdrawDenomList( * Get information about a withdrawal from * a taler://withdraw URI by asking the bank. */ -async function getBankWithdrawalInfo( +export async function getBankWithdrawalInfo( ws: InternalWalletState, talerWithdrawUri: string, ): Promise { @@ -130,33 +125,6 @@ async function getBankWithdrawalInfo( }; } -export async function acceptWithdrawal( - ws: InternalWalletState, - talerWithdrawUri: string, - selectedExchange: string, -): Promise { - const withdrawInfo = await getBankWithdrawalInfo(ws, talerWithdrawUri); - const exchangeWire = await getExchangePaytoUri( - ws, - selectedExchange, - withdrawInfo.wireTypes, - ); - const reserve = await createReserve(ws, { - amount: withdrawInfo.amount, - bankWithdrawStatusUrl: withdrawInfo.extractedStatusUrl, - exchange: selectedExchange, - senderWire: withdrawInfo.senderWire, - exchangeWire: exchangeWire, - }); - // We do this here, as the reserve should be registered before we return, - // so that we can redirect the user to the bank's status page. - await processReserveBankStatus(ws, reserve.reservePub); - console.log("acceptWithdrawal: returning"); - return { - reservePub: reserve.reservePub, - confirmTransferUrl: withdrawInfo.confirmTransferUrl, - }; -} async function getPossibleDenoms( ws: InternalWalletState, @@ -619,7 +587,7 @@ export async function getExchangeWithdrawalInfo( let versionMatch; if (exchangeDetails.protocolVersion) { versionMatch = LibtoolVersion.compare( - WALLET_PROTOCOL_VERSION, + WALLET_EXCHANGE_PROTOCOL_VERSION, exchangeDetails.protocolVersion, ); @@ -629,7 +597,7 @@ export async function getExchangeWithdrawalInfo( versionMatch.currentCmp === -1 ) { console.warn( - `wallet version ${WALLET_PROTOCOL_VERSION} might be outdated ` + + `wallet's support for exchange protocol version ${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` + `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`, ); } @@ -655,7 +623,7 @@ export async function getExchangeWithdrawalInfo( selectedDenoms, trustedAuditorPubs, versionMatch, - walletVersion: WALLET_PROTOCOL_VERSION, + walletVersion: WALLET_EXCHANGE_PROTOCOL_VERSION, wireFees: exchangeWireInfo, withdrawFee: acc, termsOfServiceAccepted: tosAccepted, -- cgit v1.2.3