fix concurrency bug in bank-integrated withdrawal, better response parsing

This commit is contained in:
Florian Dold 2020-07-31 20:13:59 +05:30
parent 119c1c708f
commit 3db00d9d73
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
2 changed files with 28 additions and 11 deletions

View File

@ -43,7 +43,10 @@ import {
getExchangeTrust, getExchangeTrust,
getExchangePaytoUri, getExchangePaytoUri,
} from "./exchanges"; } from "./exchanges";
import { codecForWithdrawOperationStatusResponse } from "../types/talerTypes"; import {
codecForWithdrawOperationStatusResponse,
codecForBankWithdrawalOperationPostResponse,
} from "../types/talerTypes";
import { assertUnreachable } from "../util/assertUnreachable"; import { assertUnreachable } from "../util/assertUnreachable";
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto"; import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto";
import { randomBytes } from "../crypto/primitives/nacl-fast"; import { randomBytes } from "../crypto/primitives/nacl-fast";
@ -71,7 +74,9 @@ import { TalerErrorCode } from "../TalerErrorCode";
import { import {
readSuccessResponseJsonOrErrorCode, readSuccessResponseJsonOrErrorCode,
throwUnexpectedRequestError, throwUnexpectedRequestError,
readSuccessResponseJsonOrThrow,
} from "../util/http"; } from "../util/http";
import { codecForAny } from "../util/codec";
const logger = new Logger("reserves.ts"); const logger = new Logger("reserves.ts");
@ -324,14 +329,14 @@ async function registerReserveWithBank(
return; return;
} }
const bankStatusUrl = bankInfo.statusUrl; const bankStatusUrl = bankInfo.statusUrl;
if (reserve.timestampReserveInfoPosted) { const httpResp = await ws.http.postJson(bankStatusUrl, {
throw Error("bank claims that reserve info selection is not done");
}
// FIXME: parse bank response
await ws.http.postJson(bankStatusUrl, {
reserve_pub: reservePub, reserve_pub: reservePub,
selected_exchange: bankInfo.exchangePaytoUri, selected_exchange: bankInfo.exchangePaytoUri,
}); });
await readSuccessResponseJsonOrThrow(
httpResp,
codecForBankWithdrawalOperationPostResponse(),
);
await ws.db.mutate(Stores.reserves, reservePub, (r) => { await ws.db.mutate(Stores.reserves, reservePub, (r) => {
switch (r.reserveStatus) { switch (r.reserveStatus) {
case ReserveRecordStatus.REGISTERING_BANK: case ReserveRecordStatus.REGISTERING_BANK:
@ -382,11 +387,9 @@ async function processReserveBankStatusImpl(
} }
const statusResp = await ws.http.get(bankStatusUrl); const statusResp = await ws.http.get(bankStatusUrl);
if (statusResp.status !== 200) { const status = await readSuccessResponseJsonOrThrow(
throw Error(`unexpected status ${statusResp.status} for bank status query`); statusResp,
} codecForWithdrawOperationStatusResponse(),
const status = codecForWithdrawOperationStatusResponse().decode(
await statusResp.json(),
); );
if (status.selection_done) { if (status.selection_done) {

View File

@ -940,6 +940,20 @@ export interface WithdrawUriInfoResponse {
possibleExchanges: ExchangeListItem[]; possibleExchanges: ExchangeListItem[];
} }
/**
* Response body for the following endpoint:
*
* POST {talerBankIntegrationApi}/withdrawal-operation/{wopid}
*/
export interface BankWithdrawalOperationPostResponse {
transfer_done: boolean;
}
export const codecForBankWithdrawalOperationPostResponse = (): Codec<BankWithdrawalOperationPostResponse> =>
makeCodecForObject<BankWithdrawalOperationPostResponse>()
.property("transfer_done", codecForBoolean)
.build("BankWithdrawalOperationPostResponse");
export type AmountString = string; export type AmountString = string;
export type Base32String = string; export type Base32String = string;
export type EddsaSignatureString = string; export type EddsaSignatureString = string;