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: implement fakebank


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: implement fakebank support (incl. tests) for #5005/#4964/4959
Date: Sun, 07 May 2017 21:11:58 +0200

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

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 18a020d  implement fakebank support (incl. tests) for #5005/#4964/4959
18a020d is described below

commit 18a020dd0241fbb7deead15b96d5f5fed9f1b9b5
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun May 7 21:11:56 2017 +0200

    implement fakebank support (incl. tests) for #5005/#4964/4959
---
 src/bank-lib/Makefile.am                   |   4 +-
 src/bank-lib/bank_api_admin.c              |  19 ++
 src/bank-lib/bank_api_history.c            |   2 +-
 src/bank-lib/fakebank.c                    |  75 +++++--
 src/bank-lib/test_bank_api.c               |  10 +-
 src/bank-lib/test_bank_api_with_fakebank.c |  12 +-
 src/bank-lib/test_bank_interpreter.c       | 346 ++++++++++++++++++++++++++++-
 src/bank-lib/test_bank_interpreter.h       |  21 +-
 src/include/taler_bank_service.h           |  12 +-
 9 files changed, 461 insertions(+), 40 deletions(-)

diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am
index 48c7e9c..8d673f9 100644
--- a/src/bank-lib/Makefile.am
+++ b/src/bank-lib/Makefile.am
@@ -57,7 +57,9 @@ check_PROGRAMS = \
   test_bank_api_with_fakebank
 
 TESTS = \
-  $(check_PROGRAMS)
+  test_bank_api_with_fakebank
+# For now, test_bank_api is known NOT to work (#5005, #4964, etc.)
+# $(check_PROGRAMS)
 
 test_bank_api_SOURCES = \
   test_bank_interpreter.c test_bank_interpreter.h \
diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin.c
index 9aa37c4..af23c57 100644
--- a/src/bank-lib/bank_api_admin.c
+++ b/src/bank-lib/bank_api_admin.c
@@ -78,6 +78,7 @@ handle_admin_add_incoming_finished (void *cls,
                                     const json_t *json)
 {
   struct TALER_BANK_AdminAddIncomingHandle *aai = cls;
+  uint64_t serial_id = UINT64_MAX;
 
   aai->job = NULL;
   switch (response_code)
@@ -85,6 +86,23 @@ handle_admin_add_incoming_finished (void *cls,
   case 0:
     break;
   case MHD_HTTP_OK:
+    {
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_uint64 ("serial_id",
+                                 &serial_id),
+        GNUNET_JSON_spec_end()
+      };
+
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (json,
+                             spec,
+                             NULL, NULL))
+      {
+        GNUNET_break_op (0);
+        response_code = 0;
+        break;
+      }
+    }
     break;
   case MHD_HTTP_BAD_REQUEST:
     /* This should never happen, either us or the bank is buggy
@@ -117,6 +135,7 @@ handle_admin_add_incoming_finished (void *cls,
   }
   aai->cb (aai->cb_cls,
            response_code,
+           serial_id,
            json);
   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 a83ad8f..ecb3561 100644
--- a/src/bank-lib/bank_api_history.c
+++ b/src/bank-lib/bank_api_history.c
@@ -94,7 +94,7 @@ parse_account_history (struct TALER_BANK_HistoryHandle *hh,
       GNUNET_JSON_spec_uint64 ("row_id",
                                &serial_id),
       GNUNET_JSON_spec_string ("wt_subject",
-                               &td.wire_transfer_subject),
+                               (const char **) &td.wire_transfer_subject),
       GNUNET_JSON_spec_uint64 ("counterpart",
                                &other_account),
       GNUNET_JSON_spec_end()
diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c
index eb76563..f8edd08 100644
--- a/src/bank-lib/fakebank.c
+++ b/src/bank-lib/fakebank.c
@@ -80,7 +80,7 @@ struct Transaction
   /**
    * Number of this transaction.
    */
-  unsigned long long serial_id;
+  uint64_t serial_id;
 };
 
 
@@ -112,7 +112,7 @@ struct TALER_FAKEBANK_Handle
   /**
    * Number of transactions.
    */
-  unsigned long long serial_counter;
+  uint64_t serial_counter;
 };
 
 
@@ -337,12 +337,12 @@ handle_admin_add_incoming (struct TALER_FAKEBANK_Handle 
*h,
       return MHD_NO;
     }
     t->exchange_base_url = GNUNET_strdup (base_url);
-    t->serial_id = h->serial_counter++;
+    t->serial_id = ++h->serial_counter;
     t->date = GNUNET_TIME_absolute_get ();
     GNUNET_TIME_round_abs (&t->date);
-    GNUNET_CONTAINER_DLL_insert (h->transactions_head,
-                                 h->transactions_tail,
-                                 t);
+    GNUNET_CONTAINER_DLL_insert_tail (h->transactions_head,
+                                      h->transactions_tail,
+                                      t);
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Receiving incoming wire transfer: %llu->%llu from %s\n",
@@ -350,7 +350,36 @@ handle_admin_add_incoming (struct TALER_FAKEBANK_Handle *h,
               (unsigned long long) t->credit_account,
               t->exchange_base_url);
   json_decref (json);
-  resp = MHD_create_response_from_buffer (0, "", MHD_RESPMEM_PERSISTENT);
+
+  /* Finally build response object */
+  {
+    void *json_str;
+    size_t json_len;
+
+    json = json_pack ("{s:I}",
+                      "serial_id",
+                      (json_int_t) t->serial_id);
+    json_str = json_dumps (json,
+                           JSON_INDENT(2));
+    if (NULL == json_str)
+    {
+      GNUNET_break (0);
+      return MHD_NO;
+    }
+    json_len = strlen (json_str);
+    resp = MHD_create_response_from_buffer (json_len,
+                                            json_str,
+                                            MHD_RESPMEM_MUST_FREE);
+    if (NULL == resp)
+    {
+      GNUNET_break (0);
+      free (json_str);
+      return MHD_NO;
+    }
+    (void) MHD_add_response_header (resp,
+                                    MHD_HTTP_HEADER_CONTENT_TYPE,
+                                    "application/json");
+  }
   ret = MHD_queue_response (connection,
                             MHD_HTTP_OK,
                             resp);
@@ -395,7 +424,7 @@ handle_history (struct TALER_FAKEBANK_Handle *h,
                                      "direction");
   start = MHD_lookup_connection_value (connection,
                                        MHD_GET_ARGUMENT_KIND,
-                                       "start");
+                                       "start_row");
   acc = MHD_lookup_connection_value (connection,
                                      MHD_GET_ARGUMENT_KIND,
                                      "account_number");
@@ -433,31 +462,40 @@ handle_history (struct TALER_FAKEBANK_Handle *h,
   }
   if (NULL == dir)
     direction = TALER_BANK_DIRECTION_BOTH;
-  else if (0 == strcasecmp (dir, "CREDIT"))
+  else if (0 == strcasecmp (dir,
+                            "CREDIT"))
     direction = TALER_BANK_DIRECTION_CREDIT;
   else
     direction = TALER_BANK_DIRECTION_DEBIT;
   if (NULL == start)
-    start_number = (count > 0) ? 0 : UINT64_MAX;
-  if (UINT64_MAX == start_number)
   {
-    pos = h->transactions_tail;
+    if (count > 0)
+      pos = h->transactions_head;
+    else
+      pos = h->transactions_tail;
   }
   else
   {
-    unsigned long long off = 0;
-
+    if (NULL == h->transactions_head)
+    {
+      GNUNET_break (0);
+      return MHD_NO;
+    }
     for (pos = h->transactions_head;
-         off < start_number;
-         off++)
+         pos->serial_id != start_number;
+         pos = pos->next)
     {
       if (NULL == pos)
       {
         GNUNET_break (0);
         return MHD_NO;
       }
-      pos = pos->next;
     }
+    /* range is exclusive, skip the matching entry */
+    if (count > 0)
+      pos = pos->next;
+    if (count < 0)
+      pos = pos->prev;
   }
   history = json_array ();
   while ( (NULL != pos) &&
@@ -542,6 +580,9 @@ handle_history (struct TALER_FAKEBANK_Handle *h,
       free (json_str);
       return MHD_NO;
     }
+    (void) MHD_add_response_header (resp,
+                                    MHD_HTTP_HEADER_CONTENT_TYPE,
+                                    "application/json");
     ret = MHD_queue_response (connection,
                               MHD_HTTP_OK,
                               resp);
diff --git a/src/bank-lib/test_bank_api.c b/src/bank-lib/test_bank_api.c
index 2340769..086a0af 100644
--- a/src/bank-lib/test_bank_api.c
+++ b/src/bank-lib/test_bank_api.c
@@ -44,7 +44,7 @@ run (void *cls)
       .label = "history-0",
       .details.history.account_number = 1,
       .details.history.direction = TALER_BANK_DIRECTION_BOTH,
-      .details.history.start_row = 0,
+      .details.history.start_row_ref = NULL,
       .details.history.num_results = 5 },
     { .oc = TBI_OC_ADMIN_ADD_INCOMING,
       .label = "deposit-1",
@@ -64,25 +64,25 @@ run (void *cls)
       .label = "history-1c",
       .details.history.account_number = 1,
       .details.history.direction = TALER_BANK_DIRECTION_CREDIT,
-      .details.history.start_row = 0,
+      .details.history.start_row_ref = NULL,
       .details.history.num_results = 5 },
     { .oc = TBI_OC_HISTORY,
       .label = "history-2d",
       .details.history.account_number = 2,
       .details.history.direction = TALER_BANK_DIRECTION_DEBIT,
-      .details.history.start_row = 0,
+      .details.history.start_row_ref = NULL,
       .details.history.num_results = 5 },
     { .oc = TBI_OC_HISTORY,
       .label = "history-2dr",
       .details.history.account_number = 2,
       .details.history.direction = TALER_BANK_DIRECTION_DEBIT,
-      .details.history.start_row = UINT64_MAX,
+      .details.history.start_row_ref = NULL,
       .details.history.num_results = -5 },
     { .oc = TBI_OC_HISTORY,
       .label = "history-2fwd",
       .details.history.account_number = 2,
       .details.history.direction = TALER_BANK_DIRECTION_DEBIT,
-      .details.history.start_row = 1,
+      .details.history.start_row_ref = "deposit-1",
       .details.history.num_results = 5 },
     { .oc = TBI_OC_END }
   };
diff --git a/src/bank-lib/test_bank_api_with_fakebank.c 
b/src/bank-lib/test_bank_api_with_fakebank.c
index 9729fb8..01ab30c 100644
--- a/src/bank-lib/test_bank_api_with_fakebank.c
+++ b/src/bank-lib/test_bank_api_with_fakebank.c
@@ -43,7 +43,7 @@ run (void *cls)
       .label = "history-0",
       .details.history.account_number = 1,
       .details.history.direction = TALER_BANK_DIRECTION_BOTH,
-      .details.history.start_row = 0,
+      .details.history.start_row_ref = NULL,
       .details.history.num_results = 1 },
     /* Add EUR:5.01 to account 1 */
     { .oc = TBI_OC_ADMIN_ADD_INCOMING,
@@ -58,13 +58,13 @@ run (void *cls)
       .label = "history-1c",
       .details.history.account_number = 1,
       .details.history.direction = TALER_BANK_DIRECTION_CREDIT,
-      .details.history.start_row = 0,
+      .details.history.start_row_ref = NULL,
       .details.history.num_results = 5 },
     { .oc = TBI_OC_HISTORY,
       .label = "history-1d",
       .details.history.account_number = 1,
       .details.history.direction = TALER_BANK_DIRECTION_DEBIT,
-      .details.history.start_row = 0,
+      .details.history.start_row_ref = NULL,
       .details.history.num_results = 5 },
     { .oc = TBI_OC_ADMIN_ADD_INCOMING,
       .label = "debit-2",
@@ -79,18 +79,18 @@ run (void *cls)
       .details.admin_add_incoming.credit_account_no = 2,
       .details.admin_add_incoming.debit_account_no = 3,
       .details.admin_add_incoming.exchange_base_url = "https://exchange.org/";,
-      .details.admin_add_incoming.amount = "PUDOS:3.21" },
+      .details.admin_add_incoming.amount = "PUDOS:3.22" },
     { .oc = TBI_OC_HISTORY,
       .label = "history-2b",
       .details.history.account_number = 2,
       .details.history.direction = TALER_BANK_DIRECTION_BOTH,
-      .details.history.start_row = 0,
+      .details.history.start_row_ref = NULL,
       .details.history.num_results = 5 },
     { .oc = TBI_OC_HISTORY,
       .label = "history-2bi",
       .details.history.account_number = 2,
       .details.history.direction = TALER_BANK_DIRECTION_BOTH,
-      .details.history.start_row = 1,
+      .details.history.start_row_ref = "debit-1",
       .details.history.num_results = 5 },
     /* check transfers arrived at fakebank */
     { .oc = TBI_OC_EXPECT_TRANSFER,
diff --git a/src/bank-lib/test_bank_interpreter.c 
b/src/bank-lib/test_bank_interpreter.c
index e58651b..9603605 100644
--- a/src/bank-lib/test_bank_interpreter.c
+++ b/src/bank-lib/test_bank_interpreter.c
@@ -92,6 +92,9 @@ static void
 fail (struct InterpreterState *is)
 {
   *is->resultp = GNUNET_SYSERR;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Interpreter failed at command `%s'\n",
+              is->commands[is->ip].label);
   GNUNET_SCHEDULER_shutdown ();
 }
 
@@ -129,6 +132,307 @@ find_command (const struct InterpreterState *is,
 
 
 /**
+ * Item in the transaction history, as reconstructed from the
+ * command history.
+ */
+struct History
+{
+
+  /**
+   * Wire details.
+   */
+  struct TALER_BANK_TransferDetails details;
+
+  /**
+   * Serial ID of the wire transfer.
+   */
+  uint64_t serial_id;
+
+  /**
+   * Direction of the transfer.
+   */
+  enum TALER_BANK_Direction direction;
+
+};
+
+
+/**
+ * Build history of transactions matching the current
+ * command in @a is.
+ *
+ * @param is interpreter state
+ * @param[out] rh history array to initialize
+ * @return number of entries in @a rh
+ */
+static uint64_t
+build_history (struct InterpreterState *is,
+               struct History **rh)
+{
+  const struct TBI_Command *cmd = &is->commands[is->ip];
+  uint64_t total;
+  struct History *h;
+  const struct TBI_Command *ref;
+  int inc;
+  unsigned int start;
+  unsigned int end;
+  int ok;
+
+  GNUNET_assert (TBI_OC_HISTORY == cmd->oc);
+  if (NULL != cmd->details.history.start_row_ref)
+  {
+    ref = find_command (is,
+                        cmd->details.history.start_row_ref);
+    GNUNET_assert (NULL != ref);
+  }
+  else
+  {
+    ref = NULL;
+  }
+  GNUNET_assert (0 != cmd->details.history.num_results);
+  if (0 == is->ip)
+  {
+    *rh = NULL;
+    return 0;
+  }
+  if (cmd->details.history.num_results > 0)
+  {
+    inc = 1;
+    start = 0;
+    end = is->ip - 1;
+  }
+  else
+  {
+    inc = -1;
+    start = is->ip - 1;
+    end = 0;
+  }
+
+  total = 0;
+  ok = GNUNET_NO;
+  if (NULL == ref)
+    ok = GNUNET_YES;
+  for (unsigned int off = start;off != end + inc; off += inc)
+  {
+    const struct TBI_Command *pos = &is->commands[off];
+
+    if (TBI_OC_ADMIN_ADD_INCOMING != pos->oc)
+      continue;
+    if ( (NULL != ref) &&
+         (ref->details.admin_add_incoming.serial_id ==
+          pos->details.admin_add_incoming.serial_id) )
+    {
+      total = 0;
+      ok = GNUNET_YES;
+      continue;
+    }
+    if (GNUNET_NO == ok)
+      continue; /* skip until we find the marker */
+    if (total >= cmd->details.history.num_results * inc)
+      break; /* hit limit specified by command */
+    if ( ( (0 != (cmd->details.history.direction & 
TALER_BANK_DIRECTION_CREDIT)) &&
+           (cmd->details.history.account_number ==
+            pos->details.admin_add_incoming.credit_account_no)) ||
+         ( (0 != (cmd->details.history.direction & 
TALER_BANK_DIRECTION_DEBIT)) &&
+           (cmd->details.history.account_number ==
+            pos->details.admin_add_incoming.debit_account_no)) )
+      total++; /* found matching record */
+  }
+  GNUNET_assert (GNUNET_YES == ok);
+  if (0 == total)
+  {
+    *rh = NULL;
+    return 0;
+  }
+  GNUNET_assert (total < UINT_MAX);
+  h = GNUNET_new_array ((unsigned int) total,
+                        struct History);
+  total = 0;
+  ok = GNUNET_NO;
+  if (NULL == ref)
+    ok = GNUNET_YES;
+  for (unsigned int off = start;off != end + inc; off += inc)
+  {
+    const struct TBI_Command *pos = &is->commands[off];
+
+    if (TBI_OC_ADMIN_ADD_INCOMING != pos->oc)
+      continue;
+    if ( (NULL != ref) &&
+         (ref->details.admin_add_incoming.serial_id ==
+          pos->details.admin_add_incoming.serial_id) )
+    {
+      total = 0;
+      ok = GNUNET_YES;
+      continue;
+    }
+    if (GNUNET_NO == ok)
+      continue; /* skip until we find the marker */
+    if (total >= cmd->details.history.num_results * inc)
+      break; /* hit limit specified by command */
+
+    if ( ( (0 != (cmd->details.history.direction & 
TALER_BANK_DIRECTION_CREDIT)) &&
+           (cmd->details.history.account_number ==
+            pos->details.admin_add_incoming.credit_account_no)) &&
+         ( (0 != (cmd->details.history.direction & 
TALER_BANK_DIRECTION_DEBIT)) &&
+           (cmd->details.history.account_number ==
+            pos->details.admin_add_incoming.debit_account_no)) )
+    {
+      GNUNET_break (0);
+      continue;
+    }
+
+    if ( (0 != (cmd->details.history.direction & TALER_BANK_DIRECTION_CREDIT)) 
&&
+         (cmd->details.history.account_number ==
+          pos->details.admin_add_incoming.credit_account_no))
+    {
+      h[total].direction = TALER_BANK_DIRECTION_CREDIT;
+      h[total].details.account_details
+        = json_pack ("{s:s, s:s, s:I}",
+                     "type",
+                     "test",
+                     "bank_uri",
+                     "http://localhost:8081";,
+                     "account_number",
+                     (json_int_t) 
pos->details.admin_add_incoming.debit_account_no);
+      GNUNET_assert (NULL != h[total].details.account_details);
+    }
+    if ( (0 != (cmd->details.history.direction & TALER_BANK_DIRECTION_DEBIT)) 
&&
+           (cmd->details.history.account_number ==
+            pos->details.admin_add_incoming.debit_account_no))
+    {
+      h[total].direction = TALER_BANK_DIRECTION_DEBIT;
+      h[total].details.account_details
+        = json_pack ("{s:s, s:s, s:I}",
+                     "type",
+                     "test",
+                     "bank_uri",
+                     "http://localhost:8081";,
+                     "account_number",
+                     (json_int_t) 
pos->details.admin_add_incoming.credit_account_no);
+      GNUNET_assert (NULL != h[total].details.account_details);
+    }
+    if ( ( (0 != (cmd->details.history.direction & 
TALER_BANK_DIRECTION_CREDIT)) &&
+           (cmd->details.history.account_number ==
+            pos->details.admin_add_incoming.credit_account_no)) ||
+         ( (0 != (cmd->details.history.direction & 
TALER_BANK_DIRECTION_DEBIT)) &&
+           (cmd->details.history.account_number ==
+            pos->details.admin_add_incoming.debit_account_no)) )
+    {
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_string_to_amount 
(pos->details.admin_add_incoming.amount,
+                                             &h[total].details.amount));
+      /* h[total].execution_date; // unknown here */
+      h[total].serial_id
+        = pos->details.admin_add_incoming.serial_id;
+      h[total].details.wire_transfer_subject
+        = GNUNET_STRINGS_data_to_string_alloc 
(&pos->details.admin_add_incoming.wtid,
+                                               sizeof (struct 
TALER_WireTransferIdentifierRawP));
+      total++;
+    }
+  }
+  *rh = h;
+  return total;
+}
+
+
+/**
+ * Free history @a h of length @a h_len.
+ *
+ * @param h history array to free
+ * @param h_len number of entries in @a h
+ */
+static void
+free_history (struct History *h,
+              uint64_t h_len)
+{
+  for (uint64_t off = 0;off<h_len;off++)
+  {
+    GNUNET_free (h[off].details.wire_transfer_subject);
+    json_decref (h[off].details.account_details);
+  }
+  GNUNET_free_non_null (h);
+}
+
+
+/**
+ * Compute how many results we expect to be returned for
+ * the history command at @a is.
+ *
+ * @param is the interpreter state to inspect
+ * @return number of results expected
+ */
+static uint64_t
+compute_result_count (struct InterpreterState *is)
+{
+  uint64_t total;
+  struct History *h;
+
+  total = build_history (is,
+                         &h);
+  free_history (h,
+                total);
+  return total;
+}
+
+
+/**
+ * Check that @a dir and @a details are the transaction
+ * results we expect at offset @a off in the history of
+ * the current command executed by @a is
+ *
+ * @param is the interpreter state we are in
+ * @param off the offset of the result
+ * @param dir the direction of the transaction
+ * @param details the transaction details to check
+ * @return #GNUNET_OK if the transaction is what we expect
+ */
+static int
+check_result (struct InterpreterState *is,
+              unsigned int off,
+              enum TALER_BANK_Direction dir,
+              const struct TALER_BANK_TransferDetails *details)
+{
+  uint64_t total;
+  struct History *h;
+
+  total = build_history (is,
+                         &h);
+  if (off >= total)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Test says history has at most %u results, but got result #%u 
to check\n",
+                (unsigned int) total,
+                off);
+    free_history (h,
+                  total);
+    return GNUNET_SYSERR;
+  }
+  if (h[off].direction != dir)
+  {
+    GNUNET_break (0);
+    free_history (h,
+                  total);
+    return GNUNET_SYSERR;
+  }
+
+  if ( (0 != strcmp (h[off].details.wire_transfer_subject,
+                     details->wire_transfer_subject)) ||
+       (0 != TALER_amount_cmp (&h[off].details.amount,
+                               &details->amount)) ||
+       (1 != json_equal (h[off].details.account_details,
+                         details->account_details)) )
+  {
+    GNUNET_break (0);
+    free_history (h,
+                  total);
+    return GNUNET_SYSERR;
+  }
+  free_history (h,
+                total);
+  return GNUNET_OK;
+}
+
+
+/**
  * Run the main interpreter loop that performs bank operations.
  *
  * @param cls contains the `struct InterpreterState`
@@ -143,17 +447,20 @@ interpreter_run (void *cls);
  * @param cls closure with the interpreter state
  * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful 
status request
  *                    0 if the bank's reply is bogus (fails to follow the 
protocol)
+ * @param serial_id unique ID of the wire transfer in the bank's records; 
UINT64_MAX on error
  * @param json detailed response from the HTTPD, or NULL if reply was not in 
JSON
  */
 static void
 add_incoming_cb (void *cls,
                  unsigned int http_status,
+                 uint64_t serial_id,
                  const json_t *json)
 {
   struct InterpreterState *is = cls;
   struct TBI_Command *cmd = &is->commands[is->ip];
 
   cmd->details.admin_add_incoming.aih = NULL;
+  cmd->details.admin_add_incoming.serial_id = serial_id;
   if (cmd->details.admin_add_incoming.expected_response_code != http_status)
   {
     GNUNET_break (0);
@@ -203,12 +510,31 @@ history_cb (void *cls,
   if (MHD_HTTP_OK != http_status)
   {
     cmd->details.history.hh = NULL;
+    if ( (cmd->details.history.results_obtained !=
+          compute_result_count (is)) ||
+         (GNUNET_YES ==
+          cmd->details.history.failed) )
+    {
+      GNUNET_break (0);
+      fail (is);
+      return;
+    }
     is->ip++;
     is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
                                        is);
     return;
   }
-  /* FIXME: check history data is OK! (#4959) */
+  if (GNUNET_OK !=
+      check_result (is,
+                    cmd->details.history.results_obtained,
+                    dir,
+                    details))
+  {
+    GNUNET_break (0);
+    cmd->details.history.failed = GNUNET_YES;
+    return;
+  }
+  cmd->details.history.results_obtained++;
 }
 
 
@@ -227,6 +553,7 @@ interpreter_run (void *cls)
   struct TALER_Amount amount;
   const struct GNUNET_SCHEDULER_TaskContext *tc;
   struct TALER_BANK_AuthenticationData auth;
+  uint64_t rowid;
 
   is->task = NULL;
   tc = GNUNET_SCHEDULER_get_task_context ();
@@ -280,13 +607,27 @@ interpreter_run (void *cls)
     }
     return;
   case TBI_OC_HISTORY:
+    if (NULL != cmd->details.history.start_row_ref)
+    {
+      ref = find_command (is,
+                          cmd->details.history.start_row_ref);
+      GNUNET_assert (NULL != ref);
+    }
+    else
+    {
+      ref = NULL;
+    }
+    if (NULL != ref)
+      rowid = ref->details.admin_add_incoming.serial_id;
+    else
+      rowid = UINT64_MAX;
     cmd->details.history.hh
       = TALER_BANK_history (is->ctx,
                             "http://localhost:8081";,
                             &auth,
                             cmd->details.history.account_number,
                             cmd->details.history.direction,
-                            cmd->details.history.start_row,
+                            rowid,
                             cmd->details.history.num_results,
                             &history_cb,
                             is);
@@ -300,6 +641,7 @@ interpreter_run (void *cls)
   case TBI_OC_EXPECT_TRANSFER:
     ref = find_command (is,
                         cmd->details.expect_transfer.cmd_ref);
+    GNUNET_assert (NULL != ref);
     GNUNET_assert (GNUNET_OK ==
                    TALER_string_to_amount 
(ref->details.admin_add_incoming.amount,
                                            &amount));
diff --git a/src/bank-lib/test_bank_interpreter.h 
b/src/bank-lib/test_bank_interpreter.h
index 06b4e2d..d4e9c1a 100644
--- a/src/bank-lib/test_bank_interpreter.h
+++ b/src/bank-lib/test_bank_interpreter.h
@@ -125,6 +125,11 @@ struct TBI_Command
        */
       struct TALER_BANK_AdminAddIncomingHandle *aih;
 
+      /**
+       * The serial ID for this record, as returned by the bank.
+       */
+      uint64_t serial_id;
+
     } admin_add_incoming;
 
     struct {
@@ -140,10 +145,10 @@ struct TBI_Command
       enum TALER_BANK_Direction direction;
 
       /**
-       * At which offset do we start?
-       * Use UINT64_MAX or 0 for the extremes.
+       * At which serial ID do we start? References the respective @e
+       * admin_add_incoming command.  Use NULL for the extremes.
        */
-      uint64_t start_row;
+      const char *start_row_ref;
 
       /**
        * How many results should be returned (if available)?
@@ -155,6 +160,16 @@ struct TBI_Command
        */
       struct TALER_BANK_HistoryHandle *hh;
 
+      /**
+       * How many results did we actually get?
+       */
+      uint64_t results_obtained;
+
+      /**
+       * Set to #GNUNET_YES if we encountered a problem.
+       */
+      int failed;
+
     } history;
 
     /**
diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h
index 7522023..803250d 100644
--- a/src/include/taler_bank_service.h
+++ b/src/include/taler_bank_service.h
@@ -98,11 +98,13 @@ struct TALER_BANK_AdminAddIncomingHandle;
  * @param cls closure
  * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful 
status request
  *                    0 if the bank's reply is bogus (fails to follow the 
protocol)
+ * @param serial_id unique ID of the wire transfer in the bank's records; 
UINT64_MAX on error
  * @param json detailed response from the HTTPD, or NULL if reply was not in 
JSON
  */
 typedef void
 (*TALER_BANK_AdminAddIncomingResultCallback) (void *cls,
                                               unsigned int http_status,
+                                              uint64_t serial_id,
                                               const json_t *json);
 
 
@@ -188,22 +190,22 @@ struct TALER_BANK_HistoryHandle;
 struct TALER_BANK_TransferDetails
 {
   /**
-   * amount that was transferred
+   * Amount that was transferred
    */
   struct TALER_Amount amount;
 
   /**
-   * when did the transfer happen
+   * Time of the the transfer
    */
   struct GNUNET_TIME_Absolute execution_date;
 
   /**
-   * wire transfer subject
+   * Wire transfer subject
    */
-  const char *wire_transfer_subject;
+  char *wire_transfer_subject;
 
   /**
-   * what was the other account that was involved
+   * The other account that was involved
    */
   json_t *account_details;
 };

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



reply via email to

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