gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-exchange] branch master updated: /history-range.


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: /history-range.
Date: Mon, 08 Apr 2019 23:57:04 +0200

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

marcello pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new ed0da1fd /history-range.
ed0da1fd is described below

commit ed0da1fdb3e85a0d19148b3ec9eb481e8c06c025
Author: Marcello Stanisci <address@hidden>
AuthorDate: Mon Apr 8 23:53:52 2019 +0200

    /history-range.
    
    Implementing the "lib" and "testing-lib" functions to use it.
---
 src/bank-lib/bank_api_admin.c               |   4 +
 src/bank-lib/bank_api_history.c             | 333 ++++++++++++++++++++--------
 src/bank-lib/fakebank.c                     |  11 +-
 src/bank-lib/test_bank_interpreter.c        |   2 +
 src/bank-lib/testing_api_cmd_history.c      | 209 ++++++++++++++++-
 src/include/taler_bank_service.h            |  37 ++++
 src/include/taler_testing_lib.h             |  72 ++++--
 src/lib/Makefile.am                         |   3 +-
 src/lib/testing_api_cmd_fakebank_transfer.c |  30 ++-
 src/lib/testing_api_trait_time.c            |  76 +++++++
 src/wire-plugins/plugin_wire_taler-bank.c   |   2 +
 11 files changed, 652 insertions(+), 127 deletions(-)

diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin.c
index 3a1ec4ef..8eff229f 100644
--- a/src/bank-lib/bank_api_admin.c
+++ b/src/bank-lib/bank_api_admin.c
@@ -79,6 +79,7 @@ handle_admin_add_incoming_finished (void *cls,
 {
   struct TALER_BANK_AdminAddIncomingHandle *aai = cls;
   uint64_t row_id = UINT64_MAX;
+  struct GNUNET_TIME_Absolute timestamp;
   enum TALER_ErrorCode ec;
   const json_t *j = response;
 
@@ -93,6 +94,8 @@ handle_admin_add_incoming_finished (void *cls,
       struct GNUNET_JSON_Specification spec[] = {
         GNUNET_JSON_spec_uint64 ("row_id",
                                  &row_id),
+        GNUNET_JSON_spec_absolute_time ("timestamp",
+                                        &timestamp),
         GNUNET_JSON_spec_end()
       };
 
@@ -148,6 +151,7 @@ handle_admin_add_incoming_finished (void *cls,
            response_code,
            ec,
            row_id,
+           timestamp,
            j);
   TALER_BANK_admin_add_incoming_cancel (aai);
 }
diff --git a/src/bank-lib/bank_api_history.c b/src/bank-lib/bank_api_history.c
index ab757a2d..4b9ea3c3 100644
--- a/src/bank-lib/bank_api_history.c
+++ b/src/bank-lib/bank_api_history.c
@@ -2,22 +2,26 @@
   This file is part of TALER
   Copyright (C) 2017 GNUnet e.V. & Inria
 
-  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.
-
-  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
-  TALER; see the file COPYING.  If not, see
-  <http://www.gnu.org/licenses/>
+  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.
+
+  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 TALER; see the file COPYING.  If not,
+  see <http://www.gnu.org/licenses/>
 */
 /**
  * @file bank-lib/bank_api_history.c
- * @brief Implementation of the /history requests of the bank's HTTP API
+ * @brief Implementation of the /history[-range]
+ *        requests of the bank's HTTP API.
  * @author Christian Grothoff
+ * @author Marcello Stanisci
  */
 #include "platform.h"
 #include "bank_api_common.h"
@@ -60,7 +64,23 @@ struct TALER_BANK_HistoryHandle
    * Closure for @a cb.
    */
   void *hcb_cls;
+};
+
+
+/**
+ * Represent a URL argument+value pair.
+ */
+struct HistoryArgumentURL
+{
+  /**
+   * Name of the URL argument.
+   */
+  char argument[20];
 
+  /**
+   * Value of the URL argument.
+   */
+  char value[20];
 };
 
 
@@ -248,24 +268,202 @@ handle_history_finished (void *cls,
 }
 
 
+
+/**
+ * Backend of both the /history[-range] requests.
+ *
+ * @param ctx curl context for the event loop
+ * @param bank_base_url base URL of the bank.
+ * @param urlargs path + URL arguments.
+ * @param auth authentication data to use
+ * @param hres_cb the callback to call with the transaction
+ *        history
+ * @param hres_cb_cls closure for the above callback
+ * @return NULL if the inputs are invalid (i.e. zero value for
+ *         @e num_results). In this case, the callback is not
+ *         called.
+ */
+static struct TALER_BANK_HistoryHandle *
+put_history_job (struct GNUNET_CURL_Context *ctx,
+                 const char *bank_base_url,
+                 const char *urlargs,
+                 const struct TALER_BANK_AuthenticationData *auth,
+                 TALER_BANK_HistoryResultCallback hres_cb,
+                 void *hres_cb_cls)
+{
+  struct TALER_BANK_HistoryHandle *hh;
+  CURL *eh;
+
+  hh = GNUNET_new (struct TALER_BANK_HistoryHandle);
+  hh->hcb = hres_cb;
+  hh->hcb_cls = hres_cb_cls;
+  hh->bank_base_url = GNUNET_strdup (bank_base_url);
+  hh->request_url = TALER_BANK_path_to_url_ (bank_base_url,
+                                             urlargs);
+
+  hh->authh = TALER_BANK_make_auth_header_ (auth);
+  eh = curl_easy_init ();
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_HTTPHEADER,
+                                   hh->authh));
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_URL,
+                                   hh->request_url));
+  hh->job = GNUNET_CURL_job_add (ctx,
+                                 eh,
+                                 GNUNET_NO,
+                                 &handle_history_finished,
+                                 hh);
+  return hh;
+}
+
+
+/**
+ * Convert fixed value 'direction' into string.
+ *
+ * @param direction the value to convert.
+ * @return string representation of @a direction.  When length
+ *         is zero, an error occurred.
+ */
+static struct HistoryArgumentURL
+conv_direction (enum TALER_BANK_Direction direction)
+{
+  struct HistoryArgumentURL ret;
+
+  if (TALER_BANK_DIRECTION_NONE == direction)
+  {
+    /* Should just never happen.  */
+    GNUNET_assert (0);
+    return ret;
+  }
+
+  if (TALER_BANK_DIRECTION_BOTH ==
+      (TALER_BANK_DIRECTION_BOTH & direction))
+    strcpy (&ret.value[0],
+            "both");
+  else if (TALER_BANK_DIRECTION_CREDIT ==
+      (TALER_BANK_DIRECTION_CREDIT & direction))
+    strcpy (&ret.value[0],
+            "credit");
+  else if (TALER_BANK_DIRECTION_DEBIT ==
+      (TALER_BANK_DIRECTION_BOTH & direction)) /*why use 'both' flag?*/
+    strcpy (&ret.value[0],
+            "debit");
+  return ret;
+}
+
+
+/**
+ * Convert fixed value 'direction' into string representation
+ * of the "cancel" argument.
+ *
+ * @param direction the value to convert.
+ * @return string representation of @a direction.  When length
+ *         is zero, an error occurred.
+ */
+static struct HistoryArgumentURL
+conv_cancel (enum TALER_BANK_Direction direction)
+{
+  struct HistoryArgumentURL ret;
+
+  if (TALER_BANK_DIRECTION_CANCEL ==
+      (TALER_BANK_DIRECTION_CANCEL & direction))
+    strcpy (&ret.value[0],
+            "show");
+  else
+    strcpy (&ret.value[0],
+            "omit");
+  return ret;
+}
+
+/**
+ * Request the wire transfer history of a bank account,
+ * using time stamps to narrow the results.
+ *
+ * @param ctx curl context for the event loop
+ * @param bank_base_url URL of the bank (used to execute this
+ *        request)
+ * @param auth authentication data to use
+ * @param account_number which account number should we query
+ * @param direction what kinds of wire transfers should be
+ *        returned
+ * @param ascending if GNUNET_YES, history elements will
+ *        be returned in chronological order.
+ * @param start_date threshold for oldest result.
+ * @param end_date threshold for youngest result.
+ * @param hres_cb the callback to call with the transaction
+ *        history
+ * @param hres_cb_cls closure for the above callback
+ * @return NULL if the inputs are invalid (i.e. zero value for
+ *         @e num_results). In this case, the callback is not
+ *         called.
+ */
+struct TALER_BANK_HistoryHandle *
+TALER_BANK_history_range (struct GNUNET_CURL_Context *ctx,
+                          const char *bank_base_url,
+                          const struct TALER_BANK_AuthenticationData *auth,
+                          uint64_t account_number,
+                          enum TALER_BANK_Direction direction,
+                          unsigned int ascending,
+                          struct GNUNET_TIME_Absolute start_date,
+                          struct GNUNET_TIME_Absolute end_date,
+                          TALER_BANK_HistoryResultCallback hres_cb,
+                          void *hres_cb_cls)
+{
+  struct TALER_BANK_HistoryHandle *hh;
+  char *url;
+
+  GNUNET_TIME_round_abs (&start_date);
+  GNUNET_TIME_round_abs (&end_date);
+
+  GNUNET_asprintf (&url,
+                   
"/history?auth=basic&account_number=%llu&start=%llu&end=%llu&direction=%s&cancelled=%s&ordering=%s",
+                   (unsigned long long) account_number,
+                   start_date.abs_value_us / 1000LL / 1000LL,
+                   end_date.abs_value_us / 1000LL / 1000LL,
+                   conv_direction (direction).value,
+                   conv_cancel (direction).value,
+                   (GNUNET_YES == ascending) ? "ascending" : "descending");
+
+  hh = put_history_job (ctx,
+                        bank_base_url,
+                        url,
+                        auth,
+                        hres_cb,
+                        hres_cb_cls);
+
+  GNUNET_free (url);
+  return hh;
+}
+
+
+
 /**
  * Request the wire transfer history of a bank account.
  *
  * @param ctx curl context for the event loop
- * @param bank_base_url URL of the bank (used to execute this request)
+ * @param bank_base_url URL of the bank (used to execute this
+ *        request)
  * @param auth authentication data to use
  * @param account_number which account number should we query
- * @param direction what kinds of wire transfers should be returned
- * @param ascending if GNUNET_YES, history elements will be returned in 
chronological order.
- * @param start_row from which row on do we want to get results, use 
UINT64_MAX for the latest; exclusive
- * @param num_results how many results do we want; negative numbers to go into 
the past,
- *                    positive numbers to go into the future starting at @a 
start_row;
- *                    must not be zero.
- * @param hres_cb the callback to call with the transaction history
+ * @param direction what kinds of wire transfers should be
+ *        returned
+ * @param ascending if GNUNET_YES, history elements will
+ *        be returned in chronological order.
+ * @param start_row from which row on do we want to get results,
+ *        use UINT64_MAX for the latest; exclusive
+ * @param num_results how many results do we want;
+ *        negative numbers to go into the past, positive numbers
+ *        to go into the future starting at @a start_row;
+ *        must not be zero.
+ * @param hres_cb the callback to call with the transaction
+ *        history
  * @param hres_cb_cls closure for the above callback
- * @return NULL
- *         if the inputs are invalid (i.e. zero value for @e num_results).
- *         In this case, the callback is not called.
+ * @return NULL if the inputs are invalid (i.e. zero value for
+ *         @e num_results). In this case, the callback is not
+ *         called.
  */
 struct TALER_BANK_HistoryHandle *
 TALER_BANK_history (struct GNUNET_CURL_Context *ctx,
@@ -280,91 +478,44 @@ TALER_BANK_history (struct GNUNET_CURL_Context *ctx,
                     void *hres_cb_cls)
 {
   struct TALER_BANK_HistoryHandle *hh;
-  CURL *eh;
   char *url;
-  const char *dir;
-  const char *can;
 
   if (0 == num_results)
   {
     GNUNET_break (0);
     return NULL;
   }
-  if (TALER_BANK_DIRECTION_NONE == direction)
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-
-  dir = NULL;
-  if (TALER_BANK_DIRECTION_BOTH == (TALER_BANK_DIRECTION_BOTH & direction))
-    dir = "both";
-  else if (TALER_BANK_DIRECTION_CREDIT == (TALER_BANK_DIRECTION_CREDIT & 
direction))
-    dir = "credit";
-  else if (TALER_BANK_DIRECTION_DEBIT == (TALER_BANK_DIRECTION_BOTH & 
direction))
-    dir = "debit";
-  if (NULL == dir)
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  if (TALER_BANK_DIRECTION_CANCEL == (TALER_BANK_DIRECTION_CANCEL & direction))
-    can = "show";
-  else
-    can = "omit";
 
+  GNUNET_asprintf (&url,
+                   
"/history?auth=basic&account_number=%llu&delta=%lld&direction=%s&cancelled=%s&ordering=%s&start=%llu",
+                   (unsigned long long) account_number,
+                   (long long) num_results,
+                   conv_direction (direction).value,
+                   conv_cancel (direction).value,
+                   (GNUNET_YES == ascending) ? "ascending" : "descending",
+                   start_row);
+
+  /* Locate and "cut" the 'start' argument,
+   * if the user didn't provide one.  */
   if (UINT64_MAX == start_row)
-  {
-    GNUNET_asprintf (&url,
-                     
"/history?auth=basic&account_number=%llu&delta=%lld&direction=%s&cancelled=%s&ordering=%s",
-                     (unsigned long long) account_number,
-                     (long long) num_results,
-                     dir,
-                     can,
-                     (GNUNET_YES == ascending) ? "ascending" : "descending");
+    *strstr (url, "&start=") = '\0';
 
-  }
-  else
-  {
-    GNUNET_asprintf (&url,
-                     
"/history?auth=basic&account_number=%llu&delta=%lld&start=%llu&direction=%s&cancelled=%s&ordering=%s",
-                     (unsigned long long) account_number,
-                     (long long) num_results,
-                     (unsigned long long) start_row,
-                     dir,
-                     can,
-                     (GNUNET_YES == ascending) ? "ascending" : "descending");
-  }
+  hh = put_history_job (ctx,
+                        bank_base_url,
+                        url,
+                        auth,
+                        hres_cb,
+                        hres_cb_cls);
 
-  hh = GNUNET_new (struct TALER_BANK_HistoryHandle);
-  hh->hcb = hres_cb;
-  hh->hcb_cls = hres_cb_cls;
-  hh->bank_base_url = GNUNET_strdup (bank_base_url);
-  hh->request_url = TALER_BANK_path_to_url_ (bank_base_url,
-                                             url);
   GNUNET_free (url);
-  hh->authh = TALER_BANK_make_auth_header_ (auth);
-  eh = curl_easy_init ();
-  GNUNET_assert (CURLE_OK ==
-                 curl_easy_setopt (eh,
-                                   CURLOPT_HTTPHEADER,
-                                   hh->authh));
-  GNUNET_assert (CURLE_OK ==
-                 curl_easy_setopt (eh,
-                                   CURLOPT_URL,
-                                   hh->request_url));
-  hh->job = GNUNET_CURL_job_add (ctx,
-                                 eh,
-                                 GNUNET_NO,
-                                 &handle_history_finished,
-                                 hh);
   return hh;
 }
 
 
 /**
- * Cancel a history request.  This function cannot be used on a request
- * handle if a response is already served for it.
+ * Cancel a history request.  This function cannot be
+ * used on a request handle if a response is already
+ * served for it.
  *
  * @param hh the history request handle
  */
diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c
index 37aae042..9915516c 100644
--- a/src/bank-lib/fakebank.c
+++ b/src/bank-lib/fakebank.c
@@ -160,11 +160,12 @@ TALER_FAKEBANK_make_transfer (struct 
TALER_FAKEBANK_Handle *h,
   struct Transaction *t;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Making transfer from %llu to %llu over %s and subject %s\n",
+              "Making transfer from %llu to %llu over %s and subject %s; for 
exchange: %s\n",
               (unsigned long long) debit_account,
               (unsigned long long) credit_account,
               TALER_amount2s (amount),
-              subject);
+              subject,
+              exchange_base_url);
   t = GNUNET_new (struct Transaction);
   t->debit_account = debit_account;
   t->credit_account = credit_account;
@@ -463,9 +464,11 @@ handle_admin_add_incoming (struct TALER_FAKEBANK_Handle *h,
     void *json_str;
     size_t json_len;
 
-    json = json_pack ("{s:I}",
+    json = json_pack ("{s:I, s:s}",
                       "row_id",
-                      (json_int_t) row_id);
+                      (json_int_t) row_id,
+                      "timestamp", "/Date(0)/"); /*dummy tmp */
+
     json_str = json_dumps (json,
                            JSON_INDENT(2));
     json_decref (json);
diff --git a/src/bank-lib/test_bank_interpreter.c 
b/src/bank-lib/test_bank_interpreter.c
index fc765779..9430e84b 100644
--- a/src/bank-lib/test_bank_interpreter.c
+++ b/src/bank-lib/test_bank_interpreter.c
@@ -530,6 +530,7 @@ next (struct InterpreterState *is)
  *                    0 if the bank's reply is bogus (fails to follow the 
protocol)
  * @param ec taler status code
  * @param row_id unique ID of the wire transfer in the bank's records; 
UINT64_MAX on error
+ * @param timestamp time stamp of when the transaction settled at the bank
  * @param json detailed response from the HTTPD, or NULL if reply was not in 
JSON
  */
 static void
@@ -537,6 +538,7 @@ add_incoming_cb (void *cls,
                  unsigned int http_status,
                  enum TALER_ErrorCode ec,
                  uint64_t row_id,
+                 struct GNUNET_TIME_Absolute timestamp,
                  const json_t *json)
 {
   struct InterpreterState *is = cls;
diff --git a/src/bank-lib/testing_api_cmd_history.c 
b/src/bank-lib/testing_api_cmd_history.c
index e3b05c83..37e15af8 100644
--- a/src/bank-lib/testing_api_cmd_history.c
+++ b/src/bank-lib/testing_api_cmd_history.c
@@ -90,6 +90,27 @@ struct HistoryState
    * chronological order.
    */
   unsigned int ascending;
+
+  /**********************************
+   * Following defs are specific to *
+   * the "/history-range" version.  *
+   **********************************/
+
+  /**
+   * Last row number we want in the result.  Only used
+   * as a trait source when using the /history-range API.
+   */
+  const char *end_row_reference;
+
+  /**
+   * Start date for /history-range.
+   */
+  struct GNUNET_TIME_Absolute start_date;
+
+  /**
+   * End date for /history-range.
+   */
+  struct GNUNET_TIME_Absolute end_date;
 };
 
 /**
@@ -669,6 +690,8 @@ history_cb (void *cls,
   struct TALER_TESTING_Interpreter *is = cls;
   struct HistoryState *hs = is->commands[is->ip].cls;
 
+  /* Possibly we got the 204 status code
+   * as a "end of list" marker.  */
   if (MHD_HTTP_OK != http_status)
   {
     hs->hh = NULL;
@@ -710,7 +733,7 @@ history_cb (void *cls,
                         JSON_COMPACT);
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Result %u was `%s'\n",
-                  (unsigned int) hs->results_obtained,
+                  (unsigned int) hs->results_obtained++,
                   acc);
       if (NULL != acc)
         free (acc);
@@ -758,7 +781,6 @@ history_run (void *cls,
 
     TALER_LOG_DEBUG ("row id (from trait) is %llu\n",
                      (unsigned long long) row_id);
-
   }
 
   auth = &AUTHS[hs->account_no - 1];
@@ -777,6 +799,81 @@ history_run (void *cls,
 
 
 /**
+ * Run the command.
+ *
+ * @param cls closure.
+ * @param cmd the command to execute.
+ * @param is the interpreter state.
+ */
+static void
+history_range_run (void *cls,
+                   const struct TALER_TESTING_Command *cmd,
+                   struct TALER_TESTING_Interpreter *is)
+{
+  
+  struct HistoryState *hs = cls;
+  const struct GNUNET_TIME_Absolute *start_date;
+  const struct GNUNET_TIME_Absolute *end_date;
+  struct TALER_BANK_AuthenticationData *auth;
+
+  if (NULL != hs->start_row_reference)
+  {
+      
+    const struct TALER_TESTING_Command *history_cmd;
+
+    history_cmd = TALER_TESTING_interpreter_lookup_command
+      (is, hs->start_row_reference);
+
+    if (NULL == history_cmd)
+      TALER_TESTING_FAIL (is);
+
+    if (GNUNET_OK != TALER_TESTING_get_trait_absolute_time
+        (history_cmd, 0, &start_date))
+      TALER_TESTING_FAIL (is);
+  }
+  else
+  {
+    GNUNET_assert (UINT64_MAX != hs->start_date.abs_value_us);
+    start_date = &hs->start_date;
+  }
+
+  if (NULL != hs->end_row_reference)
+  {
+
+    const struct TALER_TESTING_Command *history_cmd;
+
+    history_cmd = TALER_TESTING_interpreter_lookup_command
+      (is, hs->end_row_reference);
+
+    if (NULL == history_cmd)
+      TALER_TESTING_FAIL (is);
+
+    if (GNUNET_OK != TALER_TESTING_get_trait_absolute_time
+        (history_cmd, 0, &end_date))
+      TALER_TESTING_FAIL (is);
+  }
+  else
+  {
+    GNUNET_assert (UINT64_MAX != hs->end_date.abs_value_us);
+    end_date = &hs->end_date;
+  }
+
+  auth = &AUTHS[hs->account_no - 1];
+  hs->hh = TALER_BANK_history_range (is->ctx,
+                                     hs->bank_url,
+                                     auth,
+                                     hs->account_no,
+                                     hs->direction,
+                                     hs->ascending,
+                                     *start_date,
+                                     *end_date,
+                                     &history_cb,
+                                     is);
+  GNUNET_assert (NULL != hs->hh);
+}
+
+
+/**
  * Free the state from a "history" CMD, and possibly cancel
  * a pending operation thereof.
  *
@@ -848,4 +945,112 @@ TALER_TESTING_cmd_bank_history
   return cmd;
 }
 
+
+/**
+ * Make a "history-range" CMD, picking dates from traits.
+ *
+ * @param label command label.
+ * @param bank_url base URL of the bank offering the "history"
+ *        operation.
+ * @param account_no bank account number to ask the history for.
+ * @param direction which direction this operation is interested.
+ * @param ascending if GNUNET_YES, the bank will return the rows
+ *        in ascending (= chronological) order.
+ * @param start_row_reference reference to a command that can
+ *        offer a absolute time to use as the 'start' argument
+ *        for "/history-range".
+ * @param end_row_reference reference to a command that can
+ *        offer a absolute time to use as the 'end' argument
+ *        for "/history-range".
+ * @param num_result how many rows we want in the result. 
+ *
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_bank_history_range
+  (const char *label,
+   const char *bank_url,
+   uint64_t account_no,
+   enum TALER_BANK_Direction direction,
+   unsigned int ascending,
+   const char *start_row_reference,
+   const char *end_row_reference,
+   long long num_results)
+{
+  struct HistoryState *hs;
+
+  hs = GNUNET_new (struct HistoryState);
+  hs->bank_url = bank_url;
+  hs->account_no = account_no;
+  hs->direction = direction;
+  hs->start_row_reference = start_row_reference;
+  hs->end_row_reference = end_row_reference;
+  hs->num_results = num_results;
+  hs->ascending = ascending;
+  hs->start_date = GNUNET_TIME_UNIT_FOREVER_ABS;
+  hs->end_date = GNUNET_TIME_UNIT_FOREVER_ABS;
+
+  struct TALER_TESTING_Command cmd = {
+    .label = label,
+    .cls = hs,
+    .run = &history_range_run,
+    .cleanup = &history_cleanup,
+    .traits = &history_traits
+  };
+
+  return cmd;
+}
+
+
+/**
+ * Make a "history-range" CMD, picking dates from the arguments.
+ *
+ * @param label command label.
+ * @param bank_url base URL of the bank offering the "history"
+ *        operation.
+ * @param account_no bank account number to ask the history for.
+ * @param direction which direction this operation is interested.
+ * @param ascending if GNUNET_YES, the bank will return the rows
+ *        in ascending (= chronological) order.
+ * @param start_date value for the 'start' argument
+ *        of "/history-range".
+ * @param end_date value for the 'end' argument
+ *        of "/history-range".
+ * @param num_result how many rows we want in the result. 
+ *
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_bank_history_range_with_dates
+  (const char *label,
+   const char *bank_url,
+   uint64_t account_no,
+   enum TALER_BANK_Direction direction,
+   unsigned int ascending,
+   struct GNUNET_TIME_Absolute start_date,
+   struct GNUNET_TIME_Absolute end_date,
+   long long num_results)
+{
+  struct HistoryState *hs;
+
+  hs = GNUNET_new (struct HistoryState);
+  hs->bank_url = bank_url;
+  hs->account_no = account_no;
+  hs->direction = direction;
+  hs->num_results = num_results;
+  hs->ascending = ascending;
+  hs->start_date = start_date;
+  hs->end_date = start_date;
+
+  struct TALER_TESTING_Command cmd = {
+    .label = label,
+    .cls = hs,
+    .run = &history_range_run,
+    .cleanup = &history_cleanup,
+    .traits = &history_traits
+  };
+
+  return cmd;
+}
+
 /* end of testing_api_cmd_history.c */
diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h
index 2f4a0602..2cebbe6e 100644
--- a/src/include/taler_bank_service.h
+++ b/src/include/taler_bank_service.h
@@ -101,6 +101,7 @@ struct TALER_BANK_AdminAddIncomingHandle;
  *                    0 if the bank's reply is bogus (fails to follow the 
protocol)
  * @param ec detailed error code
  * @param serial_id unique ID of the wire transfer in the bank's records; 
UINT64_MAX on error
+ * @param timestamp time when the transaction was made.
  * @param json detailed response from the HTTPD, or NULL if reply was not in 
JSON
  */
 typedef void
@@ -108,6 +109,7 @@ typedef void
                                               unsigned int http_status,
                                               enum TALER_ErrorCode ec,
                                               uint64_t serial_id,
+                                              struct GNUNET_TIME_Absolute 
timestamp,
                                               const json_t *json);
 
 
@@ -282,6 +284,41 @@ TALER_BANK_history (struct GNUNET_CURL_Context *ctx,
 
 
 /**
+ * Request the wire transfer history of a bank account,
+ * using time stamps to narrow the results.
+ *
+ * @param ctx curl context for the event loop
+ * @param bank_base_url URL of the bank (used to execute this
+ *        request)
+ * @param auth authentication data to use
+ * @param account_number which account number should we query
+ * @param direction what kinds of wire transfers should be
+ *        returned
+ * @param ascending if GNUNET_YES, history elements will
+ *        be returned in chronological order.
+ * @param start_date threshold for oldest result.
+ * @param end_date threshold for youngest result.
+ * @param hres_cb the callback to call with the transaction
+ *        history
+ * @param hres_cb_cls closure for the above callback
+ * @return NULL if the inputs are invalid (i.e. zero value for
+ *         @e num_results). In this case, the callback is not
+ *         called.
+ */
+struct TALER_BANK_HistoryHandle *
+TALER_BANK_history_range (struct GNUNET_CURL_Context *ctx,
+                          const char *bank_base_url,
+                          const struct TALER_BANK_AuthenticationData *auth,
+                          uint64_t account_number,
+                          enum TALER_BANK_Direction direction,
+                          unsigned int ascending,
+                          struct GNUNET_TIME_Absolute start_date,
+                          struct GNUNET_TIME_Absolute end_date,
+                          TALER_BANK_HistoryResultCallback hres_cb,
+                          void *hres_cb_cls);
+
+
+/**
  * Cancel an history request.  This function cannot be used on a request
  * handle if the last response (anything with a status code other than
  * 200) is already served for it.
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index d0b5f275..31180c30 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -654,8 +654,9 @@ struct TALER_TESTING_SetupContext
  * @return #GNUNET_OK if no errors occurred.
  */
 int
-TALER_TESTING_setup_with_exchange_cfg (void *cls,
-                                       const struct 
GNUNET_CONFIGURATION_Handle *cfg);
+TALER_TESTING_setup_with_exchange_cfg
+  (void *cls,
+   const struct GNUNET_CONFIGURATION_Handle *cfg);
 
 
 /**
@@ -681,22 +682,23 @@ TALER_TESTING_setup_with_exchange (TALER_TESTING_Main 
main_cb,
 
 /**
  * Initialize scheduler loop and curl context for the test case
- * including starting and stopping the auditor and exchange using the
- * given configuration file.
+ * including starting and stopping the auditor and exchange using
+ * the given configuration file.
  *
  * @param cls must be a `struct TALER_TESTING_SetupContext *`
  * @param cfg configuration to use.
  * @return #GNUNET_OK if no errors occurred.
  */
 int
-TALER_TESTING_setup_with_auditor_and_exchange_cfg (void *cls,
-                                                   const struct 
GNUNET_CONFIGURATION_Handle *cfg);
+TALER_TESTING_setup_with_auditor_and_exchange_cfg
+  (void *cls,
+   const struct GNUNET_CONFIGURATION_Handle *cfg);
 
 
 /**
  * Initialize scheduler loop and curl context for the test case
- * including starting and stopping the auditor and exchange using the
- * given configuration file.
+ * including starting and stopping the auditor and exchange using
+ * the given configuration file.
  *
  * @param main_cb main method.
  * @param main_cb_cls main method closure.
@@ -709,12 +711,10 @@ TALER_TESTING_setup_with_auditor_and_exchange_cfg (void 
*cls,
  * @return #GNUNET_OK if no errors occurred.
  */
 int
-TALER_TESTING_setup_with_auditor_and_exchange (TALER_TESTING_Main main_cb,
-                                               void *main_cb_cls,
-                                               const char *config_file);
-
-
-
+TALER_TESTING_setup_with_auditor_and_exchange
+  (TALER_TESTING_Main main_cb,
+   void *main_cb_cls,
+   const char *config_file);
 
 /* ************** Specific interpreter commands ************ */
 
@@ -872,14 +872,15 @@ TALER_TESTING_cmd_fakebank_transfer_with_instance
 
 /**
  * Modify a fakebank transfer command to enable retries when the
- * reserve is not yet full or we get other transient errors from the
- * fakebank.
+ * reserve is not yet full or we get other transient errors from
+ * the fakebank.
  *
  * @param cmd a fakebank transfer command
  * @return the command with retries enabled
  */
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_fakebank_transfer_retry (struct TALER_TESTING_Command cmd);
+TALER_TESTING_cmd_fakebank_transfer_retry
+  (struct TALER_TESTING_Command cmd);
 
 
 /**
@@ -1020,7 +1021,8 @@ TALER_TESTING_cmd_withdraw_denomination
  * @return the command with retries enabled
  */
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_withdraw_with_retry (struct TALER_TESTING_Command cmd);
+TALER_TESTING_cmd_withdraw_with_retry
+  (struct TALER_TESTING_Command cmd);
 
 
 /**
@@ -1098,7 +1100,8 @@ TALER_TESTING_cmd_deposit
  * @return the command with retries enabled
  */
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_deposit_with_retry (struct TALER_TESTING_Command cmd);
+TALER_TESTING_cmd_deposit_with_retry
+  (struct TALER_TESTING_Command cmd);
 
 
 /**
@@ -1148,7 +1151,8 @@ TALER_TESTING_cmd_refresh_melt_double
  * @return modified command.
  */
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_refresh_melt_with_retry (struct TALER_TESTING_Command cmd);
+TALER_TESTING_cmd_refresh_melt_with_retry
+  (struct TALER_TESTING_Command cmd);
 
 
 /**
@@ -2407,4 +2411,32 @@ TALER_TESTING_get_trait_cmd
    struct TALER_TESTING_Command **_cmd);
 
 
+/**
+ * Obtain a absolute time from @a cmd.
+ *
+ * @param cmd command to extract trait from
+ * @param index which time stamp to pick if
+ *        @a cmd has multiple on offer.
+ * @param time[out] set to the wanted WTID.
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_TESTING_get_trait_absolute_time
+  (const struct TALER_TESTING_Command *cmd,
+   unsigned int index,
+   const struct GNUNET_TIME_Absolute **time);
+
+
+/**
+ * Offer a absolute time.
+ *
+ * @param index associate the object with this index
+ * @param time which object should be returned
+ * @return the trait.
+ */
+struct TALER_TESTING_Trait
+TALER_TESTING_make_trait_absolute_time
+  (unsigned int index,
+   const struct GNUNET_TIME_Absolute *time);
+
 #endif
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index adf075fa..8b20860b 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -107,7 +107,8 @@ libtalertesting_la_SOURCES = \
   testing_api_trait_key_peer.c \
   testing_api_trait_wtid.c \
   testing_api_trait_amount.c \
-  testing_api_trait_cmd.c
+  testing_api_trait_cmd.c \
+  testing_api_trait_time.c
 libtalertesting_la_LIBADD = \
   libtalerexchange.la \
   $(top_builddir)/src/wire/libtalerwire.la \
diff --git a/src/lib/testing_api_cmd_fakebank_transfer.c 
b/src/lib/testing_api_cmd_fakebank_transfer.c
index 43f72573..ce9ad854 100644
--- a/src/lib/testing_api_cmd_fakebank_transfer.c
+++ b/src/lib/testing_api_cmd_fakebank_transfer.c
@@ -102,6 +102,11 @@ struct FakebankTransferState
   uint64_t serial_id;
 
   /**
+   * Timestamp of the transaction (as returned from the bank).
+   */
+  struct GNUNET_TIME_Absolute timestamp;
+
+  /**
    * Exchange URL.  This value is fed to the bank when requesting
    * the wire transfer; note: the bank needs it because a merchant
    * might want to know which exchange performed a wire transfer to
@@ -182,6 +187,7 @@ do_retry (void *cls)
  *        bogus (fails to follow the protocol)
  * @param ec taler-specific error code, #TALER_EC_NONE on success
  * @param serial_id unique ID of the wire transfer
+ * @param timestamp time stamp of the transaction made.
  * @param full_response full response from the exchange (for
  *        logging, in case of errors)
  */
@@ -190,13 +196,13 @@ add_incoming_cb (void *cls,
                  unsigned int http_status,
                 enum TALER_ErrorCode ec,
                  uint64_t serial_id,
+                 struct GNUNET_TIME_Absolute timestamp,
                  const json_t *full_response)
 {
   struct FakebankTransferState *fts = cls;
   struct TALER_TESTING_Interpreter *is = fts->is;
 
   fts->aih = NULL;
-  fts->serial_id = serial_id;
   if (MHD_HTTP_OK != http_status)
   {
     if (GNUNET_YES == fts->do_retry)
@@ -205,18 +211,20 @@ add_incoming_cb (void *cls,
            (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec) ||
           (MHD_HTTP_INTERNAL_SERVER_ERROR == http_status) )
       {
-        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                    "Retrying fakebank transfer failed with %u/%d\n",
-                    http_status,
-                    (int) ec);
+        GNUNET_log
+          (GNUNET_ERROR_TYPE_INFO,
+           "Retrying fakebank transfer failed with %u/%d\n",
+           http_status,
+           (int) ec);
        /* on DB conflicts, do not use backoff */
        if (TALER_EC_DB_COMMIT_FAILED_ON_RETRY == ec)
          fts->backoff = GNUNET_TIME_UNIT_ZERO;
        else
          fts->backoff = EXCHANGE_LIB_BACKOFF (fts->backoff);
-       fts->retry_task = GNUNET_SCHEDULER_add_delayed (fts->backoff,
-                                                        &do_retry,
-                                                        fts);
+       fts->retry_task = GNUNET_SCHEDULER_add_delayed
+          (fts->backoff,
+           &do_retry,
+           fts);
        return;
       }
     }
@@ -228,6 +236,9 @@ add_incoming_cb (void *cls,
     TALER_TESTING_interpreter_fail (is);
     return;
   }
+
+  fts->serial_id = serial_id;
+  fts->timestamp = timestamp;
   TALER_TESTING_interpreter_next (is);
 }
 
@@ -422,7 +433,7 @@ fakebank_transfer_traits (void *cls,
                           unsigned int index)
 {
   struct FakebankTransferState *fts = cls;
-  #define MANDATORY 6
+  #define MANDATORY 7
   struct TALER_TESTING_Trait traits[MANDATORY + 1] = {
     TALER_TESTING_MAKE_TRAIT_DEBIT_ACCOUNT
       (&fts->debit_account_no),
@@ -431,6 +442,7 @@ fakebank_transfer_traits (void *cls,
     TALER_TESTING_make_trait_url (0, fts->exchange_url),
     TALER_TESTING_MAKE_TRAIT_ROW_ID (&fts->serial_id),
     TALER_TESTING_make_trait_amount_obj (0, &fts->amount),
+    TALER_TESTING_make_trait_absolute_time (0, &fts->timestamp)
   };
 
   /**
diff --git a/src/lib/testing_api_trait_time.c b/src/lib/testing_api_trait_time.c
new file mode 100644
index 00000000..3fd07bbb
--- /dev/null
+++ b/src/lib/testing_api_trait_time.c
@@ -0,0 +1,76 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2018 Taler Systems SA
+
+  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.
+
+  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 TALER; see the file COPYING.  If not, see
+  <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file exchange-lib/testing_api_trait_time.c
+ * @brief traits to offer time stamps.
+ * @author Marcello Stanisci
+ */
+#include "platform.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_curl_lib.h>
+#include "exchange_api_handle.h"
+#include "taler_signatures.h"
+#include "taler_testing_lib.h"
+
+#define TALER_TESTING_TRAIT_TIME_ABS "time-abs"
+
+/**
+ * Obtain a absolute time from @a cmd.
+ *
+ * @param cmd command to extract trait from
+ * @param index which time stamp to pick if
+ *        @a cmd has multiple on offer.
+ * @param time[out] set to the wanted WTID.
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_TESTING_get_trait_absolute_time
+  (const struct TALER_TESTING_Command *cmd,
+   unsigned int index,
+   const struct GNUNET_TIME_Absolute **time)
+{
+  return cmd->traits (cmd->cls,
+                      (const void **) time,
+                      TALER_TESTING_TRAIT_TIME_ABS,
+                      index);
+}
+
+
+/**
+ * Offer a absolute time.
+ *
+ * @param index associate the object with this index
+ * @param time which object should be returned
+ * @return the trait.
+ */
+struct TALER_TESTING_Trait
+TALER_TESTING_make_trait_absolute_time
+  (unsigned int index,
+   const struct GNUNET_TIME_Absolute *time)
+{
+  struct TALER_TESTING_Trait ret = {
+    .index = index,
+    .trait_name = TALER_TESTING_TRAIT_TIME_ABS,
+    .ptr = (const void *) time
+  };
+  return ret;
+}
+
+/* end of testing_api_trait_time.c */
diff --git a/src/wire-plugins/plugin_wire_taler-bank.c 
b/src/wire-plugins/plugin_wire_taler-bank.c
index 096e81df..a35fb5d2 100644
--- a/src/wire-plugins/plugin_wire_taler-bank.c
+++ b/src/wire-plugins/plugin_wire_taler-bank.c
@@ -619,6 +619,7 @@ taler_bank_prepare_wire_transfer (void *cls,
  *                    0 if the bank's reply is bogus (fails to follow the 
protocol)
  * @param ec error code from the bank
  * @param serial_id unique ID of the wire transfer in the bank's records; 
UINT64_MAX on error
+ * @param timestamp time when the transfer was settled by the bank.
  * @param json detailed response from the HTTPD, or NULL if reply was not JSON
  */
 static void
@@ -626,6 +627,7 @@ execute_cb (void *cls,
             unsigned int http_status,
             enum TALER_ErrorCode ec,
             uint64_t serial_id,
+            struct GNUNET_TIME_Absolute timestamp,
             const json_t *json)
 {
   struct TALER_WIRE_ExecuteHandle *eh = cls;

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



reply via email to

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