gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]