gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 02/02: auto-refund


From: gnunet
Subject: [taler-wallet-core] 02/02: auto-refund
Date: Sat, 07 Dec 2019 18:42:23 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

commit 165486a11268ab3d8009506916cd22d233cd248b
Author: Florian Dold <address@hidden>
AuthorDate: Sat Dec 7 18:42:18 2019 +0100

    auto-refund
---
 src/dbTypes.ts         |  7 ++++++-
 src/util/helpers.ts    | 36 ++++++++++++++++++++++++------------
 src/wallet-impl/pay.ts | 45 ++++++++++++++++++++++++++++++++++++++++-----
 src/wallet-impl/tip.ts |  4 ++--
 4 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/src/dbTypes.ts b/src/dbTypes.ts
index 55304061..3ffade4e 100644
--- a/src/dbTypes.ts
+++ b/src/dbTypes.ts
@@ -788,7 +788,7 @@ export interface TipRecord {
   /**
    * Timestamp, the tip can't be picked up anymore after this deadline.
    */
-  deadline: number;
+  deadline: Timestamp;
 
   /**
    * The exchange that will sign our coins, chosen by the merchant.
@@ -1066,6 +1066,11 @@ export interface PurchaseRecord {
    * Last error (or undefined) for querying the refund status with the 
merchant.
    */
   lastRefundApplyError: OperationError | undefined;
+
+  /**
+   * Continue querying the refund status until this deadline has expired.
+   */
+  autoRefundDeadline: Timestamp | undefined;
 }
 
 /**
diff --git a/src/util/helpers.ts b/src/util/helpers.ts
index eb8a1c7b..3831e84a 100644
--- a/src/util/helpers.ts
+++ b/src/util/helpers.ts
@@ -24,7 +24,7 @@
 import { AmountJson } from "./amounts";
 import * as Amounts from "./amounts";
 
-import { Timestamp } from "../walletTypes";
+import { Timestamp, Duration } from "../walletTypes";
 
 /**
  * Show an amount in a form suitable for the user.
@@ -152,25 +152,37 @@ export function extractTalerStampOrThrow(stamp: string): 
Timestamp {
 }
 
 /**
- * Check if a timestamp is in the right format.
+ * Extract a duration from a Taler duration string.
  */
-export function timestampCheck(stamp: string): boolean {
-  return getTalerStampSec(stamp) !== null;
+export function extractTalerDuration(duration: string): Duration | undefined {
+  const m = duration.match(/\/?Delay\(([0-9]*)\)\/?/);
+  if (!m || !m[1]) {
+    return undefined;
+  }
+  return {
+    d_ms: parseInt(m[1], 10) * 1000,
+  };
 }
 
-
 /**
- * Get a JavaScript Date object from a Taler date string.
- * Returns null if input is not in the right format.
+ * Extract a duration from a Taler duration string.
  */
-export function getTalerStampDate(stamp: string): Date | null {
-  const sec = getTalerStampSec(stamp);
-  if (sec == null) {
-    return null;
+export function extractTalerDurationOrThrow(duration: string): Duration {
+  const r = extractTalerDuration(duration);
+  if (!r) {
+    throw Error("invalid duration");
   }
-  return new Date(sec * 1000);
+  return r;
+}
+
+/**
+ * Check if a timestamp is in the right format.
+ */
+export function timestampCheck(stamp: string): boolean {
+  return getTalerStampSec(stamp) !== null;
 }
 
+
 /**
  * Compute the hash function of a JSON object.
  */
diff --git a/src/wallet-impl/pay.ts b/src/wallet-impl/pay.ts
index 7076f905..c39feeec 100644
--- a/src/wallet-impl/pay.ts
+++ b/src/wallet-impl/pay.ts
@@ -62,6 +62,8 @@ import {
   strcmp,
   canonicalJson,
   extractTalerStampOrThrow,
+  extractTalerDurationOrThrow,
+  extractTalerDuration,
 } from "../util/helpers";
 import { Logger } from "../util/logging";
 import { InternalWalletState } from "./state";
@@ -359,6 +361,7 @@ async function recordConfirmPay(
     lastRefundApplyError: undefined,
     refundApplyRetryInfo: initRetryInfo(),
     firstSuccessfulPayTimestamp: undefined,
+    autoRefundDeadline: undefined,
   };
 
   await runWithWriteTransaction(
@@ -704,9 +707,23 @@ export async function submitPay(
     // FIXME: properly display error
     throw Error("merchant payment signature invalid");
   }
+  const isFirst = purchase.firstSuccessfulPayTimestamp === undefined;
   purchase.firstSuccessfulPayTimestamp = getTimestampNow();
   purchase.lastPayError = undefined;
   purchase.payRetryInfo = initRetryInfo(false);
+  if (isFirst) {
+    const ar = purchase.contractTerms.auto_refund;
+    if (ar) {
+      const autoRefundDelay = extractTalerDuration(ar);
+      if (autoRefundDelay) {
+        purchase.refundStatusRequested = true;
+        purchase.autoRefundDeadline = {
+          t_ms: getTimestampNow().t_ms + autoRefundDelay.d_ms,
+        }
+      }
+    }
+  }
+
   const modifiedCoins: CoinRecord[] = [];
   for (const pc of purchase.payReq.coins) {
     const c = await oneShotGet(ws.db, Stores.coins, pc.coin_pub);
@@ -1064,11 +1081,6 @@ async function acceptRefundResponse(
       return;
     }
 
-    p.lastRefundStatusTimestamp = getTimestampNow();
-    p.lastRefundStatusError = undefined;
-    p.refundStatusRetryInfo = initRetryInfo();
-    p.refundStatusRequested = false;
-
     for (const perm of refundPermissions) {
       if (
         !p.refundsPending[perm.merchant_sig] &&
@@ -1079,6 +1091,29 @@ async function acceptRefundResponse(
       }
     }
 
+    // Are we done with querying yet, or do we need to do another round
+    // after a retry delay?
+    let queryDone = true;
+
+    if (numNewRefunds === 0) {
+      if (p.autoRefundDeadline && p.autoRefundDeadline.t_ms < 
getTimestampNow().t_ms) {
+        queryDone = false;
+      }
+    }
+
+    if (queryDone) {
+      p.lastRefundStatusTimestamp = getTimestampNow();
+      p.lastRefundStatusError = undefined;
+      p.refundStatusRetryInfo = initRetryInfo();
+      p.refundStatusRequested = false;
+    } else {
+      // No error, but we need to try again!
+      p.lastRefundStatusTimestamp = getTimestampNow();
+      p.refundStatusRetryInfo.retryCounter++;
+      updateRetryInfoTimeout(p.refundStatusRetryInfo);
+      p.lastRefundStatusError = undefined;
+    }
+
     if (numNewRefunds) {
       p.lastRefundApplyError = undefined;
       p.refundApplyRetryInfo = initRetryInfo();
diff --git a/src/wallet-impl/tip.ts b/src/wallet-impl/tip.ts
index 9cfaed93..11e029fc 100644
--- a/src/wallet-impl/tip.ts
+++ b/src/wallet-impl/tip.ts
@@ -23,7 +23,7 @@ import { TipPickupGetResponse, TipPlanchetDetail, TipResponse 
} from "../talerTy
 import * as Amounts from "../util/amounts";
 import { Stores, PlanchetRecord, WithdrawalSessionRecord, initRetryInfo, 
updateRetryInfoTimeout } from "../dbTypes";
 import { getWithdrawDetailsForAmount, getVerifiedWithdrawDenomList, 
processWithdrawSession } from "./withdraw";
-import { getTalerStampSec } from "../util/helpers";
+import { getTalerStampSec, extractTalerStampOrThrow } from "../util/helpers";
 import { updateExchangeFromUrl } from "./exchanges";
 import { getRandomBytes, encodeCrock } from "../crypto/talerCrypto";
 import { guardOperationException } from "./errors";
@@ -68,7 +68,7 @@ export async function getTipStatus(
       tipId,
       accepted: false,
       amount,
-      deadline: getTalerStampSec(tipPickupStatus.stamp_expire)!,
+      deadline: extractTalerStampOrThrow(tipPickupStatus.stamp_expire),
       exchangeUrl: tipPickupStatus.exchange_url,
       merchantBaseUrl: res.merchantBaseUrl,
       nextUrl: undefined,

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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