[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-wallet-core] 01/02: handle permanent refund failure
From: |
gnunet |
Subject: |
[taler-wallet-core] 01/02: handle permanent refund failure |
Date: |
Sun, 06 Sep 2020 14:47:38 +0200 |
This is an automated email from the git hooks/post-receive script.
dold pushed a commit to branch master
in repository wallet-core.
commit c0861f0690425308e3e4126093f4edb2b105e64a
Author: Florian Dold <florian.dold@gmail.com>
AuthorDate: Sun Sep 6 18:17:12 2020 +0530
handle permanent refund failure
---
packages/taler-integrationtests/src/harness.ts | 16 ++++--
.../taler-wallet-core/src/operations/refund.ts | 60 ++++++++++++++++++++--
packages/taler-wallet-core/src/types/talerTypes.ts | 4 +-
3 files changed, 72 insertions(+), 8 deletions(-)
diff --git a/packages/taler-integrationtests/src/harness.ts
b/packages/taler-integrationtests/src/harness.ts
index cc5ffa16..d974bdd0 100644
--- a/packages/taler-integrationtests/src/harness.ts
+++ b/packages/taler-integrationtests/src/harness.ts
@@ -899,10 +899,20 @@ export class ExchangeService implements
ExchangeServiceInterface {
}
async runWirewatchOnce() {
- await sh(
+ await runCommand(
+ this.globalState,
+ `exchange-${this.name}-wirewatch-once`,
+ "taler-exchange-wirewatch",
+ [...this.timetravelArgArr, "-c", this.configFilename, "-t"],
+ );
+ }
+
+ async runAggregatorOnce() {
+ await runCommand(
this.globalState,
- "wirewatch-test",
- `taler-exchange-wirewatch ${this.timetravelArg} -c
'${this.configFilename}' -t`,
+ `exchange-${this.name}-aggregator-once`,
+ "taler-exchange-aggregator",
+ [...this.timetravelArgArr, "-c", this.configFilename, "-t"],
);
}
diff --git a/packages/taler-wallet-core/src/operations/refund.ts
b/packages/taler-wallet-core/src/operations/refund.ts
index 373e17a1..0c89e524 100644
--- a/packages/taler-wallet-core/src/operations/refund.ts
+++ b/packages/taler-wallet-core/src/operations/refund.ts
@@ -47,8 +47,6 @@ import {
MerchantCoinRefundStatus,
MerchantCoinRefundSuccessStatus,
MerchantCoinRefundFailureStatus,
- codecForMerchantOrderStatusPaid,
- AmountString,
codecForMerchantOrderRefundPickupResponse,
} from "../types/talerTypes";
import { guardOperationException } from "./errors";
@@ -202,6 +200,56 @@ async function storePendingRefund(
};
}
+async function storeFailedRefund(
+ tx: TransactionHandle,
+ p: PurchaseRecord,
+ r: MerchantCoinRefundFailureStatus,
+): Promise<void> {
+ const refundKey = getRefundKey(r);
+
+ const coin = await tx.get(Stores.coins, r.coin_pub);
+ if (!coin) {
+ console.warn("coin not found, can't apply refund");
+ return;
+ }
+ const denom = await tx.getIndexed(
+ Stores.denominations.denomPubHashIndex,
+ coin.denomPubHash,
+ );
+
+ if (!denom) {
+ throw Error("inconsistent database");
+ }
+
+ const allDenoms = await tx
+ .iterIndexed(
+ Stores.denominations.exchangeBaseUrlIndex,
+ coin.exchangeBaseUrl,
+ )
+ .toArray();
+
+ const amountLeft = Amounts.sub(
+ Amounts.add(coin.currentAmount, Amounts.parseOrThrow(r.refund_amount))
+ .amount,
+ denom.feeRefund,
+ ).amount;
+
+ const totalRefreshCostBound = getTotalRefreshCost(
+ allDenoms,
+ denom,
+ amountLeft,
+ );
+
+ p.refunds[refundKey] = {
+ type: RefundState.Failed,
+ obtainedTime: getTimestampNow(),
+ executionTime: r.execution_time,
+ refundAmount: Amounts.parseOrThrow(r.refund_amount),
+ refundFee: denom.feeRefund,
+ totalRefreshCostBound,
+ };
+}
+
async function acceptRefunds(
ws: InternalWalletState,
proposalId: string,
@@ -232,6 +280,10 @@ async function acceptRefunds(
const refundKey = getRefundKey(refundStatus);
const existingRefundInfo = p.refunds[refundKey];
+ const isPermanentFailure =
+ refundStatus.type === "failure" &&
+ refundStatus.exchange_status === 410;
+
// Already failed.
if (existingRefundInfo?.type === RefundState.Failed) {
continue;
@@ -244,7 +296,7 @@ async function acceptRefunds(
// Still pending.
if (
- refundStatus.type === "failure" &&
+ refundStatus.type === "failure" && !isPermanentFailure &&
existingRefundInfo?.type === RefundState.Pending
) {
continue;
@@ -254,6 +306,8 @@ async function acceptRefunds(
if (refundStatus.type === "success") {
await applySuccessfulRefund(tx, p, refreshCoinsMap, refundStatus);
+ } else if (isPermanentFailure) {
+ await storeFailedRefund(tx, p, refundStatus);
} else {
await storePendingRefund(tx, p, refundStatus);
}
diff --git a/packages/taler-wallet-core/src/types/talerTypes.ts
b/packages/taler-wallet-core/src/types/talerTypes.ts
index 0b4afda1..c944f156 100644
--- a/packages/taler-wallet-core/src/types/talerTypes.ts
+++ b/packages/taler-wallet-core/src/types/talerTypes.ts
@@ -1325,13 +1325,13 @@ export const codecForMerchantCoinRefundFailureStatus =
(): Codec<
buildCodecForObject<MerchantCoinRefundFailureStatus>()
.property("type", codecForConstString("failure"))
.property("coin_pub", codecForString())
- .property("exchange_status", codecForConstNumber(200))
+ .property("exchange_status", codecForNumber())
.property("rtransaction_id", codecForNumber())
.property("refund_amount", codecForString())
.property("exchange_code", codecOptional(codecForNumber()))
.property("exchange_reply", codecOptional(codecForAny()))
.property("execution_time", codecForTimestamp)
- .build("MerchantCoinRefundSuccessStatus");
+ .build("MerchantCoinRefundFailureStatus");
export const codecForMerchantCoinRefundStatus = (): Codec<
MerchantCoinRefundStatus
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.