gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: misc bugfixes in reserves_in bat


From: gnunet
Subject: [taler-exchange] branch master updated: misc bugfixes in reserves_in batch logic
Date: Sat, 22 Apr 2023 01:20:44 +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 2dab1fac misc bugfixes in reserves_in batch logic
2dab1fac is described below

commit 2dab1fac1c08ac75c12708ae0cf10e2108a76256
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Apr 22 01:20:41 2023 +0200

    misc bugfixes in reserves_in batch logic
---
 src/exchange/taler-exchange-httpd_reserves_get.c  |   40 +-
 src/exchangedb/exchange_do_reserves_in_insert.sql | 1319 ++++++++++-----------
 src/exchangedb/pg_reserves_in_insert.c            |  880 ++++++--------
 src/testing/testing_api_cmd_exec_wirewatch.c      |    1 -
 src/testing/testing_api_loop.c                    |    2 +-
 5 files changed, 998 insertions(+), 1244 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_reserves_get.c 
b/src/exchange/taler-exchange-httpd_reserves_get.c
index 003db926..c22e62bf 100644
--- a/src/exchange/taler-exchange-httpd_reserves_get.c
+++ b/src/exchange/taler-exchange-httpd_reserves_get.c
@@ -147,18 +147,13 @@ db_event_cb (void *cls,
              const void *extra,
              size_t extra_size)
 {
-  struct TEH_RequestContext *rc = cls;
-  struct ReservePoller *rp = rc->rh_ctx;
+  struct ReservePoller *rp = cls;
   struct GNUNET_AsyncScopeSave old_scope;
 
   (void) extra;
   (void) extra_size;
   if (! rp->suspended)
     return; /* might get multiple wake-up events */
-  GNUNET_async_scope_enter (&rc->async_scope_id,
-                            &old_scope);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Resuming from long-polling on reserve\n");
   TEH_check_invariants ();
   rp->suspended = false;
   MHD_resume_connection (rp->connection);
@@ -238,7 +233,8 @@ TEH_handler_reserves_get (struct TEH_RequestContext *rc,
     };
 
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Starting DB event listening\n");
+                "Starting DB event listening until %s\n",
+                GNUNET_TIME_absolute2s (rp->timeout));
     rp->eh = TEH_plugin->event_listen (
       TEH_plugin->cls,
       GNUNET_TIME_absolute_get_remaining (rp->timeout),
@@ -256,49 +252,27 @@ TEH_handler_reserves_get (struct TEH_RequestContext *rc,
     {
     case GNUNET_DB_STATUS_SOFT_ERROR:
       GNUNET_break (0); /* single-shot query should never have soft-errors */
-      if (NULL != rp->eh)
-      {
-        TEH_plugin->event_listen_cancel (TEH_plugin->cls,
-                                         rp->eh);
-        rp->eh = NULL;
-      }
       return TALER_MHD_reply_with_error (rc->connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GENERIC_DB_SOFT_FAILURE,
                                          "get_reserve_balance");
     case GNUNET_DB_STATUS_HARD_ERROR:
       GNUNET_break (0);
-      if (NULL != rp->eh)
-      {
-        TEH_plugin->event_listen_cancel (TEH_plugin->cls,
-                                         rp->eh);
-        rp->eh = NULL;
-      }
       return TALER_MHD_reply_with_error (rc->connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          TALER_EC_GENERIC_DB_FETCH_FAILED,
                                          "get_reserve_balance");
     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
-      if (NULL != rp->eh)
-      {
-        TEH_plugin->event_listen_cancel (TEH_plugin->cls,
-                                         rp->eh);
-        rp->eh = NULL;
-      }
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Got reserve balance of %s\n",
+                  TALER_amount2s (&rp->balance));
       return TALER_MHD_REPLY_JSON_PACK (rc->connection,
                                         MHD_HTTP_OK,
                                         TALER_JSON_pack_amount ("balance",
                                                                 &rp->balance));
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
-      if ( (NULL != rp) ||
-           (GNUNET_TIME_absolute_is_future (rp->timeout)) )
+      if (! GNUNET_TIME_absolute_is_future (rp->timeout))
       {
-        if (NULL != rp->eh)
-        {
-          TEH_plugin->event_listen_cancel (TEH_plugin->cls,
-                                           rp->eh);
-          rp->eh = NULL;
-        }
         return TALER_MHD_reply_with_error (rc->connection,
                                            MHD_HTTP_NOT_FOUND,
                                            
TALER_EC_EXCHANGE_RESERVES_STATUS_UNKNOWN,
diff --git a/src/exchangedb/exchange_do_reserves_in_insert.sql 
b/src/exchangedb/exchange_do_reserves_in_insert.sql
index 3a217acc..e7506dc8 100644
--- a/src/exchangedb/exchange_do_reserves_in_insert.sql
+++ b/src/exchangedb/exchange_do_reserves_in_insert.sql
@@ -23,12 +23,12 @@ CREATE OR REPLACE FUNCTION 
exchange_do_batch_reserves_in_insert(
   IN in_credit_frac INT4,
   IN in_exchange_account_name VARCHAR,
   IN in_execution_date INT8,
-  IN in_wire_source_h_payto BYTEA,    ---h_payto
+  IN in_wire_source_h_payto BYTEA,
   IN in_payto_uri VARCHAR,
-  IN in_notify text,
-  OUT out_reserve_found BOOLEAN,
-  OUT transaction_duplicate BOOLEAN,
-  OUT ruuid INT8)
+  IN in_notify TEXT,
+  OUT out_reserve_found0 BOOLEAN,
+  OUT transaction_duplicate0 BOOLEAN,
+  OUT ruuid0 INT8)
 LANGUAGE plpgsql
 AS $$
 DECLARE
@@ -38,11 +38,10 @@ DECLARE
 DECLARE
   curs_trans refcursor;
 BEGIN
-  ruuid = 0;
-  out_reserve_found = TRUE;
-  transaction_duplicate = TRUE;
+  ruuid0 = 0;
+  out_reserve_found0 = TRUE;
+  transaction_duplicate0 = TRUE;
 
---SIMPLE INSERT ON CONFLICT DO NOTHING
   INSERT INTO wire_targets
     (wire_target_h_payto
     ,payto_uri)
@@ -65,18 +64,16 @@ BEGIN
       ,in_credit_frac
       ,in_reserve_expiration
       ,in_gc_date)
-     ON CONFLICT DO NOTHING
-     RETURNING reserve_uuid, reserve_pub)
-   SELECT * FROM reserve_changes;
+    ON CONFLICT DO NOTHING
+    RETURNING reserve_uuid, reserve_pub)
+  SELECT reserve_uuid, reserve_pub FROM reserve_changes;
+
   FETCH FROM curs INTO i;
   IF FOUND
   THEN
     -- We made a change, so the reserve did not previously exist.
-    IF in_reserve_pub = i.reserve_pub
-    THEN
-        out_reserve_found = FALSE;
-        ruuid = i.reserve_uuid;
-    END IF;
+    out_reserve_found0 = FALSE;
+    ruuid0 = i.reserve_uuid;
   END IF;
   CLOSE curs;
 
@@ -100,56 +97,56 @@ BEGIN
     ,in_execution_date)
     ON CONFLICT DO NOTHING
     RETURNING reserve_pub)
-  SELECT * FROM reserve_transaction;
+  SELECT reserve_pub FROM reserve_transaction;
+
   FETCH FROM curs_trans INTO i;
   IF FOUND
   THEN
-    IF i.reserve_pub = in_reserve_pub
-    THEN
-    -- HAPPY PATH THERE IS NO DUPLICATE TRANS
-       transaction_duplicate = FALSE;
-       EXECUTE FORMAT (
+    transaction_duplicate0 = FALSE;
+    EXECUTE FORMAT (
          'NOTIFY %s'
          ,in_notify);
-    END IF;
   END IF;
+
   CLOSE curs_trans;
+
   RETURN;
 END $$;
 
+
 CREATE OR REPLACE FUNCTION exchange_do_batch2_reserves_insert(
   IN in_gc_date INT8,
   IN in_reserve_expiration INT8,
-  IN in_reserve_pub BYTEA,
-  IN in_wire_ref INT8,
-  IN in_credit_val INT8,
-  IN in_credit_frac INT4,
-  IN in_exchange_account_name VARCHAR,
-  IN in_execution_date INT8,
-  IN in_wire_source_h_payto BYTEA,    ---h_payto
-  IN in_payto_uri VARCHAR,
-  IN in_notify text,
-  IN in2_notify text,
-  IN in2_reserve_pub BYTEA,
-  IN in2_wire_ref INT8,
-  IN in2_credit_val INT8,
-  IN in2_credit_frac INT4,
-  IN in2_exchange_account_name VARCHAR,
-  IN in2_execution_date INT8,
-  IN in2_wire_source_h_payto BYTEA,    ---h_payto
-  IN in2_payto_uri VARCHAR,
-  OUT out_reserve_found BOOLEAN,
-  OUT out_reserve_found2 BOOLEAN,
-  OUT transaction_duplicate BOOLEAN,
-  OUT transaction_duplicate2 BOOLEAN,
-  OUT ruuid INT8,
-  OUT ruuid2 INT8)
+  IN in0_reserve_pub BYTEA,
+  IN in0_wire_ref INT8,
+  IN in0_credit_val INT8,
+  IN in0_credit_frac INT4,
+  IN in0_exchange_account_name VARCHAR,
+  IN in0_execution_date INT8,
+  IN in0_wire_source_h_payto BYTEA,
+  IN in0_payto_uri VARCHAR,
+  IN in0_notify TEXT,
+  IN in1_reserve_pub BYTEA,
+  IN in1_wire_ref INT8,
+  IN in1_credit_val INT8,
+  IN in1_credit_frac INT4,
+  IN in1_exchange_account_name VARCHAR,
+  IN in1_execution_date INT8,
+  IN in1_wire_source_h_payto BYTEA,
+  IN in1_payto_uri VARCHAR,
+  IN in1_notify TEXT,
+  OUT out_reserve_found0 BOOLEAN,
+  OUT out_reserve_found1 BOOLEAN,
+  OUT transaction_duplicate0 BOOLEAN,
+  OUT transaction_duplicate1 BOOLEAN,
+  OUT ruuid0 INT8,
+  OUT ruuid1 INT8)
 LANGUAGE plpgsql
 AS $$
 DECLARE
   curs_reserve_exist REFCURSOR;
 DECLARE
-  curs_transaction_exist refcursor;
+  curs_transaction_exist REFCURSOR;
 DECLARE
   i RECORD;
 DECLARE
@@ -157,21 +154,21 @@ DECLARE
 DECLARE
   k INT8;
 BEGIN
-  transaction_duplicate=TRUE;
-  transaction_duplicate2=TRUE;
-  out_reserve_found = TRUE;
-  out_reserve_found2 = TRUE;
-  ruuid=0;
-  ruuid2=0;
-  k=0;
+  transaction_duplicate0 = TRUE;
+  transaction_duplicate1 = TRUE;
+  out_reserve_found0 = TRUE;
+  out_reserve_found1 = TRUE;
+  ruuid0=0;
+  ruuid1=0;
+
   INSERT INTO wire_targets
     (wire_target_h_payto
     ,payto_uri)
     VALUES
-    (in_wire_source_h_payto
-    ,in_payto_uri),
-    (in2_wire_source_h_payto
-    ,in2_payto_uri)
+    (in0_wire_source_h_payto
+    ,in0_payto_uri),
+    (in1_wire_source_h_payto
+    ,in1_payto_uri)
   ON CONFLICT DO NOTHING;
 
   OPEN curs_reserve_exist FOR
@@ -183,39 +180,51 @@ BEGIN
       ,expiration_date
       ,gc_date)
       VALUES
-      (in_reserve_pub
-      ,in_credit_val
-      ,in_credit_frac
+      (in0_reserve_pub
+      ,in0_credit_val
+      ,in0_credit_frac
       ,in_reserve_expiration
       ,in_gc_date),
-      (in2_reserve_pub
-      ,in2_credit_val
-      ,in2_credit_frac
+      (in1_reserve_pub
+      ,in1_credit_val
+      ,in1_credit_frac
       ,in_reserve_expiration
       ,in_gc_date)
-     ON CONFLICT DO NOTHING
-     RETURNING reserve_uuid,reserve_pub)
-    SELECT * FROM reserve_changes;
-  WHILE k < 2 LOOP
+    ON CONFLICT DO NOTHING
+    RETURNING reserve_uuid, reserve_pub)
+  SELECT reserve_uuid, reserve_pub FROM reserve_changes;
+
+  k=0;
+  <<loop_reserve>> LOOP
     FETCH FROM curs_reserve_exist INTO i;
-    IF FOUND
+    IF NOT FOUND
     THEN
-      IF in_reserve_pub = i.reserve_pub
-      THEN
-        ruuid = i.reserve_uuid;
-        IF in_reserve_pub <> in2_reserve_pub
-        THEN
-          out_reserve_found = FALSE;
-         END IF;
-      END IF;
-      IF in2_reserve_pub = i.reserve_pub
-      THEN
-          out_reserve_found2 = FALSE;
-          ruuid2 = i.reserve_uuid;
-      END IF;
+      EXIT loop_reserve;
     END IF;
-    k=k+1;
-  END LOOP;
+
+    <<loop_k>> LOOP
+      CASE k
+        WHEN 0 THEN
+          k = k + 1;
+          IF in0_reserve_pub = i.reserve_pub
+          THEN
+            ruuid0 = i.reserve_uuid;
+            out_reserve_found0 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 1 THEN
+          IF in1_reserve_pub = i.reserve_pub
+          THEN
+            ruuid1 = i.reserve_uuid;
+            out_reserve_found1 = FALSE;
+            EXIT loop_reserve;
+          END IF;
+          EXIT loop_k;
+      END CASE;
+    END LOOP loop_k;
+  END LOOP loop_reserve;
+
   CLOSE curs_reserve_exist;
 
   OPEN curs_transaction_exist FOR
@@ -229,160 +238,153 @@ BEGIN
     ,wire_source_h_payto
     ,execution_date)
     VALUES
-    (in_reserve_pub
-    ,in_wire_ref
-    ,in_credit_val
-    ,in_credit_frac
-    ,in_exchange_account_name
-    ,in_wire_source_h_payto
-    ,in_execution_date),
-    (in2_reserve_pub
-    ,in2_wire_ref
-    ,in2_credit_val
-    ,in2_credit_frac
-    ,in2_exchange_account_name
-    ,in2_wire_source_h_payto
-    ,in2_execution_date)
+    (in0_reserve_pub
+    ,in0_wire_ref
+    ,in0_credit_val
+    ,in0_credit_frac
+    ,in0_exchange_account_name
+    ,in0_wire_source_h_payto
+    ,in0_execution_date),
+    (in1_reserve_pub
+    ,in1_wire_ref
+    ,in1_credit_val
+    ,in1_credit_frac
+    ,in1_exchange_account_name
+    ,in1_wire_source_h_payto
+    ,in1_execution_date)
     ON CONFLICT DO NOTHING
     RETURNING reserve_pub)
-  SELECT * FROM reserve_in_exist;
+  SELECT reserve_pub FROM reserve_in_exist;
+
   FETCH FROM curs_transaction_exist INTO r;
-  IF FOUND
-  THEN
-    IF in_reserve_pub = r.reserve_pub
-    THEN
-       transaction_duplicate = FALSE;
-       EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in_notify);
-    END IF;
-    IF in2_reserve_pub = r.reserve_pub
-    THEN
-       transaction_duplicate2 = FALSE;
-       EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in2_notify);
-    END IF;
-    FETCH FROM curs_transaction_exist INTO r;
-    IF FOUND
+
+  k=0;
+  <<loop_transaction>> LOOP
+    FETCH FROM curs_transaction_exist INTO i;
+    IF NOT FOUND
     THEN
-      IF in_reserve_pub = r.reserve_pub
-      THEN
-        transaction_duplicate = FALSE;
-        EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in_notify);
-      END IF;
-      IF in2_reserve_pub = r.reserve_pub
-      THEN
-        transaction_duplicate2 = FALSE;
-        EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in2_notify);
-      END IF;
+      EXIT loop_transaction;
     END IF;
-  END IF;
-/*  IF transaction_duplicate
-  OR transaction_duplicate2
-  THEN
-    CLOSE curs_transaction_exist;
-    ROLLBACK;
-    RETURN;
-  END IF;*/
+
+    <<loop2_k>> LOOP
+      CASE k
+        WHEN 0 THEN
+          k = k + 1;
+          IF in0_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate0 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in0_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 1 THEN
+          IF in0_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate1 = FALSE;
+            EXECUTE FORMAT (
+              'NOTIFY %s'
+              ,in1_notify);
+            EXIT loop_transaction;
+          END IF;
+      END CASE;
+    END LOOP loop2_k;
+  END LOOP loop_transaction;
+
   CLOSE curs_transaction_exist;
+
   RETURN;
 END $$;
 
+
 CREATE OR REPLACE FUNCTION exchange_do_batch4_reserves_insert(
   IN in_gc_date INT8,
   IN in_reserve_expiration INT8,
-  IN in_reserve_pub BYTEA,
-  IN in_wire_ref INT8,
-  IN in_credit_val INT8,
-  IN in_credit_frac INT4,
-  IN in_exchange_account_name VARCHAR,
-  IN in_execution_date INT8,
-  IN in_wire_source_h_payto BYTEA,    ---h_payto
-  IN in_payto_uri VARCHAR,
-  IN in_notify text,
-  IN in2_notify text,
-  IN in3_notify text,
-  IN in4_notify text,
+  IN in0_reserve_pub BYTEA,
+  IN in0_wire_ref INT8,
+  IN in0_credit_val INT8,
+  IN in0_credit_frac INT4,
+  IN in0_exchange_account_name VARCHAR,
+  IN in0_execution_date INT8,
+  IN in0_wire_source_h_payto BYTEA,
+  IN in0_payto_uri VARCHAR,
+  IN in0_notify TEXT,
+  IN in1_reserve_pub BYTEA,
+  IN in1_wire_ref INT8,
+  IN in1_credit_val INT8,
+  IN in1_credit_frac INT4,
+  IN in1_exchange_account_name VARCHAR,
+  IN in1_execution_date INT8,
+  IN in1_wire_source_h_payto BYTEA,
+  IN in1_payto_uri VARCHAR,
+  IN in1_notify TEXT,
   IN in2_reserve_pub BYTEA,
   IN in2_wire_ref INT8,
   IN in2_credit_val INT8,
   IN in2_credit_frac INT4,
   IN in2_exchange_account_name VARCHAR,
   IN in2_execute_date INT8,
-  IN in2_wire_source_h_payto BYTEA,    ---h_payto
+  IN in2_wire_source_h_payto BYTEA,
   IN in2_payto_uri VARCHAR,
+  IN in2_notify TEXT,
   IN in3_reserve_pub BYTEA,
   IN in3_wire_ref INT8,
   IN in3_credit_val INT8,
   IN in3_credit_frac INT4,
   IN in3_exchange_account_name VARCHAR,
   IN in3_execute_date INT8,
-  IN in3_wire_source_h_payto BYTEA,    ---h_payto
+  IN in3_wire_source_h_payto BYTEA,
   IN in3_payto_uri VARCHAR,
-  IN in4_reserve_pub BYTEA,
-  IN in4_wire_ref INT8,
-  IN in4_credit_val INT8,
-  IN in4_credit_frac INT4,
-  IN in4_exchange_account_name VARCHAR,
-  IN in4_execution_date INT8,
-  IN in4_wire_source_h_payto BYTEA,    ---h_payto
-  IN in4_payto_uri VARCHAR,
-  OUT out_reserve_found BOOLEAN,
+  IN in3_notify TEXT,
+  OUT out_reserve_found0 BOOLEAN,
+  OUT out_reserve_found1 BOOLEAN,
   OUT out_reserve_found2 BOOLEAN,
   OUT out_reserve_found3 BOOLEAN,
-  OUT out_reserve_found4 BOOLEAN,
-  OUT transaction_duplicate BOOLEAN,
+  OUT transaction_duplicate0 BOOLEAN,
+  OUT transaction_duplicate1 BOOLEAN,
   OUT transaction_duplicate2 BOOLEAN,
   OUT transaction_duplicate3 BOOLEAN,
-  OUT transaction_duplicate4 BOOLEAN,
-  OUT ruuid INT8,
+  OUT ruuid0 INT8,
+  OUT ruuid1 INT8,
   OUT ruuid2 INT8,
-  OUT ruuid3 INT8,
-  OUT ruuid4 INT8)
+  OUT ruuid3 INT8)
 LANGUAGE plpgsql
 AS $$
 DECLARE
-  curs_reserve_exist refcursor;
+  curs_reserve_exist REFCURSOR;
 DECLARE
   k INT8;
 DECLARE
-  curs_transaction_exist refcursor;
+  curs_transaction_exist REFCURSOR;
 DECLARE
   i RECORD;
-
 BEGIN
---INITIALIZATION
-  transaction_duplicate=TRUE;
+  transaction_duplicate0=TRUE;
+  transaction_duplicate1=TRUE;
   transaction_duplicate2=TRUE;
   transaction_duplicate3=TRUE;
-  transaction_duplicate4=TRUE;
-  out_reserve_found = TRUE;
+  out_reserve_found0 = TRUE;
+  out_reserve_found1 = TRUE;
   out_reserve_found2 = TRUE;
   out_reserve_found3 = TRUE;
-  out_reserve_found4 = TRUE;
-  ruuid=0;
+  ruuid0=0;
+  ruuid1=0;
   ruuid2=0;
   ruuid3=0;
-  ruuid4=0;
-  k=0;
-  --SIMPLE INSERT ON CONFLICT DO NOTHING
+
   INSERT INTO wire_targets
     (wire_target_h_payto
     ,payto_uri)
     VALUES
-    (in_wire_source_h_payto
-    ,in_payto_uri),
+    (in0_wire_source_h_payto
+    ,in0_payto_uri),
+    (in1_wire_source_h_payto
+    ,in1_payto_uri),
     (in2_wire_source_h_payto
     ,in2_payto_uri),
     (in3_wire_source_h_payto
-    ,in3_payto_uri),
-    (in4_wire_source_h_payto
-    ,in4_payto_uri)
+    ,in3_payto_uri)
   ON CONFLICT DO NOTHING;
 
   OPEN curs_reserve_exist FOR
@@ -394,9 +396,14 @@ BEGIN
       ,expiration_date
       ,gc_date)
       VALUES
-      (in_reserve_pub
-      ,in_credit_val
-      ,in_credit_frac
+      (in0_reserve_pub
+      ,in0_credit_val
+      ,in0_credit_frac
+      ,in_reserve_expiration
+      ,in_gc_date),
+      (in1_reserve_pub
+      ,in1_credit_val
+      ,in1_credit_frac
       ,in_reserve_expiration
       ,in_gc_date),
       (in2_reserve_pub
@@ -408,310 +415,313 @@ BEGIN
       ,in3_credit_val
       ,in3_credit_frac
       ,in_reserve_expiration
-      ,in_gc_date),
-      (in4_reserve_pub
-      ,in4_credit_val
-      ,in4_credit_frac
-      ,in_reserve_expiration
       ,in_gc_date)
-     ON CONFLICT DO NOTHING
-     RETURNING reserve_uuid,reserve_pub)
-    SELECT * FROM reserve_changes;
+    ON CONFLICT DO NOTHING
+    RETURNING reserve_uuid,reserve_pub)
+  SELECT reserve_uuid, reserve_pub FROM reserve_changes;
 
-  WHILE k < 4 LOOP
+  k=0;
+  <<loop_reserve>> LOOP
     FETCH FROM curs_reserve_exist INTO i;
-    IF FOUND
+    IF NOT FOUND
     THEN
-      IF in_reserve_pub = i.reserve_pub
-      THEN
-         ruuid = i.reserve_uuid;
-         IF in_reserve_pub
-         NOT IN (in2_reserve_pub
-                ,in3_reserve_pub
-                ,in4_reserve_pub)
-         THEN
-           out_reserve_found = FALSE;
-         END IF;
-      END IF;
-      IF in2_reserve_pub = i.reserve_pub
-      THEN
-         ruuid2 = i.reserve_uuid;
-         IF in2_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in3_reserve_pub
-                ,in4_reserve_pub)
-         THEN
-           out_reserve_found2 = FALSE;
-         END IF;
-      END IF;
-      IF in3_reserve_pub = i.reserve_pub
-      THEN
-         ruuid3 = i.reserve_uuid;
-         IF in3_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in2_reserve_pub
-                ,in4_reserve_pub)
-         THEN
-           out_reserve_found3 = FALSE;
-         END IF;
-      END IF;
-      IF in4_reserve_pub = i.reserve_pub
-      THEN
-         ruuid4 = i.reserve_uuid;
-         IF in4_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in2_reserve_pub
-                ,in3_reserve_pub)
-         THEN
-           out_reserve_found4 = FALSE;
-         END IF;
-      END IF;
+      EXIT loop_reserve;
     END IF;
-  k=k+1;
-  END LOOP;
+
+    <<loop_k>> LOOP
+      CASE k
+        WHEN 0 THEN
+          k = k + 1;
+          IF in0_reserve_pub = i.reserve_pub
+          THEN
+            ruuid0 = i.reserve_uuid;
+            out_reserve_found0 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 1 THEN
+          k = k + 1;
+          IF in1_reserve_pub = i.reserve_pub
+          THEN
+            ruuid1 = i.reserve_uuid;
+            out_reserve_found1 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 2 THEN
+          k = k + 1;
+          IF in2_reserve_pub = i.reserve_pub
+          THEN
+            ruuid2 = i.reserve_uuid;
+            out_reserve_found2 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 3 THEN
+          IF in3_reserve_pub = i.reserve_pub
+          THEN
+            ruuid3 = i.reserve_uuid;
+            out_reserve_found3 = FALSE;
+            EXIT loop_reserve;
+          END IF;
+          EXIT loop_k;
+      END CASE;
+    END LOOP loop_k;
+  END LOOP loop_reserve;
+
   CLOSE curs_reserve_exist;
 
-  k=0;
   OPEN curs_transaction_exist FOR
-  WITH reserve_in_changes AS (
+  WITH reserve_changes AS (
     INSERT INTO reserves_in
-    (reserve_pub
-    ,wire_reference
-    ,credit_val
-    ,credit_frac
-    ,exchange_account_section
-    ,wire_source_h_payto
-    ,execution_date)
+      (reserve_pub
+      ,wire_reference
+      ,credit_val
+      ,credit_frac
+      ,exchange_account_section
+      ,wire_source_h_payto
+      ,execution_date)
       VALUES
-    (in_reserve_pub
-    ,in_wire_ref
-    ,in_credit_val
-    ,in_credit_frac
-    ,in_exchange_account_name
-    ,in_wire_source_h_payto
-    ,in_execution_date),
-    (in2_reserve_pub
-    ,in2_wire_ref
-    ,in2_credit_val
-    ,in2_credit_frac
-    ,in2_exchange_account_name
-    ,in2_wire_source_h_payto
-    ,in2_execution_date),
-    (in3_reserve_pub
-    ,in3_wire_ref
-    ,in3_credit_val
-    ,in3_credit_frac
-    ,in3_exchange_account_name
-    ,in3_wire_source_h_payto
-    ,in3_execution_date),
-    (in4_reserve_pub
-    ,in4_wire_ref
-    ,in4_credit_val
-    ,in4_credit_frac
-    ,in4_exchange_account_name
-    ,in4_wire_source_h_payto
-    ,in4_execution_date)
-     ON CONFLICT DO NOTHING
-     RETURNING reserve_pub)
-    SELECT * FROM reserve_in_changes;
-  WHILE k < 4 LOOP
+      (in0_reserve_pub
+      ,in0_wire_ref
+      ,in0_credit_val
+      ,in0_credit_frac
+      ,in0_exchange_account_name
+      ,in0_wire_source_h_payto
+      ,in0_execution_date),
+      (in1_reserve_pub
+      ,in1_wire_ref
+      ,in1_credit_val
+      ,in1_credit_frac
+      ,in1_exchange_account_name
+      ,in1_wire_source_h_payto
+      ,in1_execution_date),
+      (in2_reserve_pub
+      ,in2_wire_ref
+      ,in2_credit_val
+      ,in2_credit_frac
+      ,in2_exchange_account_name
+      ,in2_wire_source_h_payto
+      ,in2_execution_date),
+      (in3_reserve_pub
+      ,in3_wire_ref
+      ,in3_credit_val
+      ,in3_credit_frac
+      ,in3_exchange_account_name
+      ,in3_wire_source_h_payto
+      ,in3_execution_date)
+    ON CONFLICT DO NOTHING
+    RETURNING reserve_pub)
+  SELECT reserve_uuid, reserve_pub FROM reserve_changes;
+
+  k=0;
+  <<loop_transaction>> LOOP
     FETCH FROM curs_transaction_exist INTO i;
-    IF FOUND
+    IF NOT FOUND
     THEN
-      IF in_reserve_pub = i.reserve_pub
-      THEN
-         transaction_duplicate = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in_notify);
-      END IF;
-      IF in2_reserve_pub = i.reserve_pub
-      THEN
-         transaction_duplicate2 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in2_notify);
-      END IF;
-      IF in3_reserve_pub = i.reserve_pub
-      THEN
-         transaction_duplicate3 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in3_notify);
-      END IF;
-      IF in4_reserve_pub = i.reserve_pub
-      THEN
-         transaction_duplicate4 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in4_notify);
-      END IF;
+      EXIT loop_transaction;
     END IF;
-  k=k+1;
-  END LOOP;
- /**ROLLBACK TRANSACTION IN SORTED PROCEDURE IS IT PROSSIBLE ?**/
-  /*IF transaction_duplicate
-  OR transaction_duplicate2
-  OR transaction_duplicate3
-  OR transaction_duplicate4
-  THEN
-    RAISE EXCEPTION 'Reserve did not exist, but INSERT into reserves_in gave 
conflict';
-    ROLLBACK;
-    CLOSE curs_transaction_exist;
-    RETURN;
-  END IF;*/
+
+    <<loop2_k>> LOOP
+      CASE k
+        WHEN 0 THEN
+          k = k + 1;
+          IF in0_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate0 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in0_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 1 THEN
+          k = k + 1;
+          IF in1_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate1 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in1_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 2 THEN
+          k = k + 1;
+          IF in2_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate2 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in2_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 3 THEN
+          IF in3_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate3 = FALSE;
+            EXECUTE FORMAT (
+              'NOTIFY %s'
+              ,in3_notify);
+            EXIT loop_transaction;
+          END IF;
+      END CASE;
+    END LOOP loop2_k;
+  END LOOP loop_transaction;
+
   CLOSE curs_transaction_exist;
-  RETURN;
 
+  RETURN;
 END $$;
 
+
 CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert(
   IN in_gc_date INT8,
   IN in_reserve_expiration INT8,
-  IN in_reserve_pub BYTEA,
-  IN in_wire_ref INT8,
-  IN in_credit_val INT8,
-  IN in_credit_frac INT4,
-  IN in_exchange_account_name VARCHAR,
-  IN in_execution_date INT8,
-  IN in_wire_source_h_payto BYTEA,    ---h_payto
-  IN in_payto_uri VARCHAR,
-  IN in_notify text,
-  IN in2_notify text,
-  IN in3_notify text,
-  IN in4_notify text,
-  IN in5_notify text,
-  IN in6_notify text,
-  IN in7_notify text,
-  IN in8_notify text,
+  IN in0_reserve_pub BYTEA,
+  IN in0_wire_ref INT8,
+  IN in0_credit_val INT8,
+  IN in0_credit_frac INT4,
+  IN in0_exchange_account_name VARCHAR,
+  IN in0_execution_date INT8,
+  IN in0_wire_source_h_payto BYTEA,
+  IN in0_payto_uri VARCHAR,
+  IN in0_notify TEXT,
+  IN in1_reserve_pub BYTEA,
+  IN in1_wire_ref INT8,
+  IN in1_credit_val INT8,
+  IN in1_credit_frac INT4,
+  IN in1_exchange_account_name VARCHAR,
+  IN in1_execution_date INT8,
+  IN in1_wire_source_h_payto BYTEA,
+  IN in1_payto_uri VARCHAR,
+  IN in1_notify TEXT,
   IN in2_reserve_pub BYTEA,
   IN in2_wire_ref INT8,
   IN in2_credit_val INT8,
   IN in2_credit_frac INT4,
   IN in2_exchange_account_name VARCHAR,
   IN in2_execution_date INT8,
-  IN in2_wire_source_h_payto BYTEA,    ---h_payto
+  IN in2_wire_source_h_payto BYTEA,
   IN in2_payto_uri VARCHAR,
+  IN in2_notify TEXT,
   IN in3_reserve_pub BYTEA,
   IN in3_wire_ref INT8,
   IN in3_credit_val INT8,
   IN in3_credit_frac INT4,
   IN in3_exchange_account_name VARCHAR,
   IN in3_execution_date INT8,
-  IN in3_wire_source_h_payto BYTEA,    ---h_payto
+  IN in3_wire_source_h_payto BYTEA,
   IN in3_payto_uri VARCHAR,
+  IN in3_notify TEXT,
   IN in4_reserve_pub BYTEA,
   IN in4_wire_ref INT8,
   IN in4_credit_val INT8,
   IN in4_credit_frac INT4,
   IN in4_exchange_account_name VARCHAR,
   IN in4_execution_date INT8,
-  IN in4_wire_source_h_payto BYTEA,    ---h_payto
+  IN in4_wire_source_h_payto BYTEA,
   IN in4_payto_uri VARCHAR,
+  IN in4_notify TEXT,
   IN in5_reserve_pub BYTEA,
   IN in5_wire_ref INT8,
   IN in5_credit_val INT8,
   IN in5_credit_frac INT4,
   IN in5_exchange_account_name VARCHAR,
   IN in5_execution_date INT8,
-  IN in5_wire_source_h_payto BYTEA,    ---h_payto
+  IN in5_wire_source_h_payto BYTEA,
   IN in5_payto_uri VARCHAR,
+  IN in5_notify TEXT,
   IN in6_reserve_pub BYTEA,
   IN in6_wire_ref INT8,
   IN in6_credit_val INT8,
   IN in6_credit_frac INT4,
   IN in6_exchange_account_name VARCHAR,
   IN in6_execution_date INT8,
-  IN in6_wire_source_h_payto BYTEA,    ---h_payto
+  IN in6_wire_source_h_payto BYTEA,
   IN in6_payto_uri VARCHAR,
+  IN in6_notify TEXT,
   IN in7_reserve_pub BYTEA,
   IN in7_wire_ref INT8,
   IN in7_credit_val INT8,
   IN in7_credit_frac INT4,
   IN in7_exchange_account_name VARCHAR,
   IN in7_execution_date INT8,
-  IN in7_wire_source_h_payto BYTEA,    ---h_payto
+  IN in7_wire_source_h_payto BYTEA,
   IN in7_payto_uri VARCHAR,
-  IN in8_reserve_pub BYTEA,
-  IN in8_wire_ref INT8,
-  IN in8_credit_val INT8,
-  IN in8_credit_frac INT4,
-  IN in8_exchange_account_name VARCHAR,
-  IN in8_execution_date INT8,
-  IN in8_wire_source_h_payto BYTEA,    ---h_payto
-  IN in8_payto_uri VARCHAR,
-  OUT out_reserve_found BOOLEAN,
+  IN in7_notify TEXT,
+  OUT out_reserve_found0 BOOLEAN,
+  OUT out_reserve_found1 BOOLEAN,
   OUT out_reserve_found2 BOOLEAN,
   OUT out_reserve_found3 BOOLEAN,
   OUT out_reserve_found4 BOOLEAN,
   OUT out_reserve_found5 BOOLEAN,
   OUT out_reserve_found6 BOOLEAN,
   OUT out_reserve_found7 BOOLEAN,
-  OUT out_reserve_found8 BOOLEAN,
-  OUT transaction_duplicate BOOLEAN,
+  OUT transaction_duplicate0 BOOLEAN,
+  OUT transaction_duplicate1 BOOLEAN,
   OUT transaction_duplicate2 BOOLEAN,
   OUT transaction_duplicate3 BOOLEAN,
   OUT transaction_duplicate4 BOOLEAN,
   OUT transaction_duplicate5 BOOLEAN,
   OUT transaction_duplicate6 BOOLEAN,
   OUT transaction_duplicate7 BOOLEAN,
-  OUT transaction_duplicate8 BOOLEAN,
-  OUT ruuid INT8,
+  OUT ruuid0 INT8,
+  OUT ruuid1 INT8,
   OUT ruuid2 INT8,
   OUT ruuid3 INT8,
   OUT ruuid4 INT8,
   OUT ruuid5 INT8,
   OUT ruuid6 INT8,
-  OUT ruuid7 INT8,
-  OUT ruuid8 INT8)
+  OUT ruuid7 INT8)
 LANGUAGE plpgsql
 AS $$
 DECLARE
-  curs_reserve_existed refcursor;
+  curs_reserve_exist REFCURSOR;
 DECLARE
   k INT8;
 DECLARE
-  curs_transaction_existed refcursor;
+  curs_transaction_exist REFCURSOR;
 DECLARE
   i RECORD;
 DECLARE
   r RECORD;
 
 BEGIN
---INITIALIZATION
-  transaction_duplicate=TRUE;
+  transaction_duplicate0=TRUE;
+  transaction_duplicate1=TRUE;
   transaction_duplicate2=TRUE;
   transaction_duplicate3=TRUE;
   transaction_duplicate4=TRUE;
   transaction_duplicate5=TRUE;
   transaction_duplicate6=TRUE;
   transaction_duplicate7=TRUE;
-  transaction_duplicate8=TRUE;
-  out_reserve_found = TRUE;
+  out_reserve_found0 = TRUE;
+  out_reserve_found1 = TRUE;
   out_reserve_found2 = TRUE;
   out_reserve_found3 = TRUE;
   out_reserve_found4 = TRUE;
   out_reserve_found5 = TRUE;
   out_reserve_found6 = TRUE;
   out_reserve_found7 = TRUE;
-  out_reserve_found8 = TRUE;
-  ruuid=0;
+  ruuid0=0;
+  ruuid1=0;
   ruuid2=0;
   ruuid3=0;
   ruuid4=0;
   ruuid5=0;
   ruuid6=0;
   ruuid7=0;
-  ruuid8=0;
-  k=0;
 
-  --SIMPLE INSERT ON CONFLICT DO NOTHING
   INSERT INTO wire_targets
     (wire_target_h_payto
     ,payto_uri)
     VALUES
-    (in_wire_source_h_payto
-    ,in_payto_uri),
+    (in0_wire_source_h_payto
+    ,in0_payto_uri),
+    (in1_wire_source_h_payto
+    ,in1_payto_uri),
     (in2_wire_source_h_payto
     ,in2_payto_uri),
     (in3_wire_source_h_payto
@@ -723,12 +733,10 @@ BEGIN
     (in6_wire_source_h_payto
     ,in6_payto_uri),
     (in7_wire_source_h_payto
-    ,in7_payto_uri),
-    (in8_wire_source_h_payto
-    ,in8_payto_uri)
+    ,in7_payto_uri)
   ON CONFLICT DO NOTHING;
 
-  OPEN curs_reserve_existed FOR
+  OPEN curs_reserve_exist FOR
   WITH reserve_changes AS (
     INSERT INTO reserves
       (reserve_pub
@@ -737,9 +745,14 @@ BEGIN
       ,expiration_date
       ,gc_date)
       VALUES
-      (in_reserve_pub
-      ,in_credit_val
-      ,in_credit_frac
+      (in0_reserve_pub
+      ,in0_credit_val
+      ,in0_credit_frac
+      ,in_reserve_expiration
+      ,in_gc_date),
+      (in1_reserve_pub
+      ,in1_credit_val
+      ,in1_credit_frac
       ,in_reserve_expiration
       ,in_gc_date),
       (in2_reserve_pub
@@ -771,295 +784,269 @@ BEGIN
       ,in7_credit_val
       ,in7_credit_frac
       ,in_reserve_expiration
-      ,in_gc_date),
-      (in8_reserve_pub
-      ,in8_credit_val
-      ,in8_credit_frac
-      ,in_reserve_expiration
       ,in_gc_date)
-     ON CONFLICT DO NOTHING
-     RETURNING reserve_uuid,reserve_pub)
-    SELECT * FROM reserve_changes;
-
-  WHILE k < 8 LOOP
+    ON CONFLICT DO NOTHING
+    RETURNING reserve_uuid,reserve_pub)
+  SELECT reserve_uuid, reserve_pub FROM reserve_changes;
 
-    FETCH FROM curs_reserve_existed INTO i;
-    IF FOUND
+  k=0;
+  <<loop_reserve>> LOOP
+    FETCH FROM curs_reserve_exist INTO i;
+    IF NOT FOUND
     THEN
-      IF in_reserve_pub = i.reserve_pub
-      THEN
-         ruuid = i.reserve_uuid;
-         IF in_reserve_pub
-         NOT IN (in2_reserve_pub
-                ,in3_reserve_pub
-                ,in4_reserve_pub
-                ,in5_reserve_pub
-                ,in6_reserve_pub
-                ,in7_reserve_pub
-                ,in8_reserve_pub)
-         THEN
-           out_reserve_found = FALSE;
-         END IF;
-      END IF;
-      IF in2_reserve_pub = i.reserve_pub
-      THEN
-         ruuid2 = i.reserve_uuid;
-         IF in2_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in3_reserve_pub
-                ,in4_reserve_pub
-                ,in5_reserve_pub
-                ,in6_reserve_pub
-                ,in7_reserve_pub
-                ,in8_reserve_pub)
-         THEN
-           out_reserve_found2 = FALSE;
-         END IF;
-      END IF;
-      IF in3_reserve_pub = i.reserve_pub
-      THEN
-         ruuid3 = i.reserve_uuid;
-         IF in3_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in2_reserve_pub
-                ,in4_reserve_pub
-                ,in5_reserve_pub
-                ,in6_reserve_pub
-                ,in7_reserve_pub
-                ,in8_reserve_pub)
-         THEN
-           out_reserve_found3 = FALSE;
-         END IF;
-      END IF;
-      IF in4_reserve_pub = i.reserve_pub
-      THEN
-         ruuid4 = i.reserve_uuid;
-         IF in4_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in2_reserve_pub
-                ,in3_reserve_pub
-                ,in5_reserve_pub
-                ,in6_reserve_pub
-                ,in7_reserve_pub
-                ,in8_reserve_pub)
-         THEN
-           out_reserve_found4 = FALSE;
-         END IF;
-      END IF;
-      IF in5_reserve_pub = i.reserve_pub
-      THEN
-         ruuid5 = i.reserve_uuid;
-         IF in5_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in2_reserve_pub
-                ,in3_reserve_pub
-                ,in4_reserve_pub
-                ,in6_reserve_pub
-                ,in7_reserve_pub
-                ,in8_reserve_pub)
-         THEN
-           out_reserve_found5 = FALSE;
-         END IF;
-      END IF;
-      IF in6_reserve_pub = i.reserve_pub
-      THEN
-         ruuid6 = i.reserve_uuid;
-         IF in6_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in2_reserve_pub
-                ,in3_reserve_pub
-                ,in4_reserve_pub
-                ,in5_reserve_pub
-                ,in7_reserve_pub
-                ,in8_reserve_pub)
-         THEN
-           out_reserve_found6 = FALSE;
-         END IF;
-      END IF;
-      IF in7_reserve_pub = i.reserve_pub
-      THEN
-         ruuid7 = i.reserve_uuid;
-         IF in7_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in2_reserve_pub
-                ,in3_reserve_pub
-                ,in4_reserve_pub
-                ,in5_reserve_pub
-                ,in6_reserve_pub
-                ,in8_reserve_pub)
-         THEN
-           out_reserve_found7 = FALSE;
-         END IF;
-      END IF;
-      IF in8_reserve_pub = i.reserve_pub
-      THEN
-         ruuid8 = i.reserve_uuid;
-         IF in8_reserve_pub
-         NOT IN (in_reserve_pub
-                ,in2_reserve_pub
-                ,in3_reserve_pub
-                ,in4_reserve_pub
-                ,in5_reserve_pub
-                ,in6_reserve_pub
-                ,in7_reserve_pub)
-         THEN
-           out_reserve_found8 = FALSE;
-         END IF;
-      END IF;
+      EXIT loop_reserve;
     END IF;
-  k=k+1;
-  END LOOP;
 
-  CLOSE curs_reserve_existed;
+    <<loop_k>> LOOP
+      CASE k
+        WHEN 0 THEN
+          k = k + 1;
+          IF in0_reserve_pub = i.reserve_pub
+          THEN
+            ruuid0 = i.reserve_uuid;
+            out_reserve_found0 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 1 THEN
+          k = k + 1;
+          IF in1_reserve_pub = i.reserve_pub
+          THEN
+            ruuid1 = i.reserve_uuid;
+            out_reserve_found1 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 2 THEN
+          k = k + 1;
+          IF in2_reserve_pub = i.reserve_pub
+          THEN
+            ruuid2 = i.reserve_uuid;
+            out_reserve_found2 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 3 THEN
+          k = k + 1;
+          IF in3_reserve_pub = i.reserve_pub
+          THEN
+            ruuid3 = i.reserve_uuid;
+            out_reserve_found3 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 4 THEN
+          k = k + 1;
+          IF in4_reserve_pub = i.reserve_pub
+          THEN
+            ruuid4 = i.reserve_uuid;
+            out_reserve_found4 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 5 THEN
+          k = k + 1;
+          IF in5_reserve_pub = i.reserve_pub
+          THEN
+            ruuid5 = i.reserve_uuid;
+            out_reserve_found5 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 6 THEN
+          k = k + 1;
+          IF in6_reserve_pub = i.reserve_pub
+          THEN
+            ruuid6 = i.reserve_uuid;
+            out_reserve_found6 = FALSE;
+            CONTINUE loop_reserve;
+          END IF;
+          CONTINUE loop_k;
+        WHEN 7 THEN
+          IF in7_reserve_pub = i.reserve_pub
+          THEN
+            ruuid7 = i.reserve_uuid;
+            out_reserve_found7 = FALSE;
+            EXIT loop_reserve;
+          END IF;
+          EXIT loop_k;
+      END CASE;
+    END LOOP loop_k;
+  END LOOP loop_reserve;
 
-  k=0;
-  OPEN curs_transaction_existed FOR
-  WITH reserve_in_changes AS (
+  CLOSE curs_reserve_exist;
+
+  OPEN curs_transaction_exist FOR
+  WITH reserve_changes AS (
     INSERT INTO reserves_in
-    (reserve_pub
-    ,wire_reference
-    ,credit_val
-    ,credit_frac
-    ,exchange_account_section
-    ,wire_source_h_payto
-    ,execution_date)
+      (reserve_pub
+      ,wire_reference
+      ,credit_val
+      ,credit_frac
+      ,exchange_account_section
+      ,wire_source_h_payto
+      ,execution_date)
       VALUES
-    (in_reserve_pub
-    ,in_wire_ref
-    ,in_credit_val
-    ,in_credit_frac
-    ,in_exchange_account_name
-    ,in_wire_source_h_payto
-    ,in_execution_date),
-    (in2_reserve_pub
-    ,in2_wire_ref
-    ,in2_credit_val
-    ,in2_credit_frac
-    ,in2_exchange_account_name
-    ,in2_wire_source_h_payto
-    ,in2_execution_date),
-    (in3_reserve_pub
-    ,in3_wire_ref
-    ,in3_credit_val
-    ,in3_credit_frac
-    ,in3_exchange_account_name
-    ,in3_wire_source_h_payto
-    ,in3_execution_date),
-    (in4_reserve_pub
-    ,in4_wire_ref
-    ,in4_credit_val
-    ,in4_credit_frac
-    ,in4_exchange_account_name
-    ,in4_wire_source_h_payto
-    ,in4_execution_date),
-    (in5_reserve_pub
-    ,in5_wire_ref
-    ,in5_credit_val
-    ,in5_credit_frac
-    ,in5_exchange_account_name
-    ,in5_wire_source_h_payto
-    ,in5_execution_date),
-    (in6_reserve_pub
-    ,in6_wire_ref
-    ,in6_credit_val
-    ,in6_credit_frac
-    ,in6_exchange_account_name
-    ,in6_wire_source_h_payto
-    ,in6_execution_date),
-    (in7_reserve_pub
-    ,in7_wire_ref
-    ,in7_credit_val
-    ,in7_credit_frac
-    ,in7_exchange_account_name
-    ,in7_wire_source_h_payto
-    ,in7_execution_date),
-    (in8_reserve_pub
-    ,in8_wire_ref
-    ,in8_credit_val
-    ,in8_credit_frac
-    ,in8_exchange_account_name
-    ,in8_wire_source_h_payto
-    ,in8_execution_date)
-     ON CONFLICT DO NOTHING
-     RETURNING reserve_pub)
-    SELECT * FROM reserve_in_changes;
+      (in0_reserve_pub
+      ,in0_wire_ref
+      ,in0_credit_val
+      ,in0_credit_frac
+      ,in0_exchange_account_name
+      ,in0_wire_source_h_payto
+      ,in0_execution_date),
+      (in1_reserve_pub
+      ,in1_wire_ref
+      ,in1_credit_val
+      ,in1_credit_frac
+      ,in1_exchange_account_name
+      ,in1_wire_source_h_payto
+      ,in1_execution_date),
+      (in2_reserve_pub
+      ,in2_wire_ref
+      ,in2_credit_val
+      ,in2_credit_frac
+      ,in2_exchange_account_name
+      ,in2_wire_source_h_payto
+      ,in2_execution_date),
+      (in3_reserve_pub
+      ,in3_wire_ref
+      ,in3_credit_val
+      ,in3_credit_frac
+      ,in3_exchange_account_name
+      ,in3_wire_source_h_payto
+      ,in3_execution_date),
+      (in4_reserve_pub
+      ,in4_wire_ref
+      ,in4_credit_val
+      ,in4_credit_frac
+      ,in4_exchange_account_name
+      ,in4_wire_source_h_payto
+      ,in4_execution_date),
+      (in5_reserve_pub
+      ,in5_wire_ref
+      ,in5_credit_val
+      ,in5_credit_frac
+      ,in5_exchange_account_name
+      ,in5_wire_source_h_payto
+      ,in5_execution_date),
+      (in6_reserve_pub
+      ,in6_wire_ref
+      ,in6_credit_val
+      ,in6_credit_frac
+      ,in6_exchange_account_name
+      ,in6_wire_source_h_payto
+      ,in6_execution_date),
+      (in7_reserve_pub
+      ,in7_wire_ref
+      ,in7_credit_val
+      ,in7_credit_frac
+      ,in7_exchange_account_name
+      ,in7_wire_source_h_payto
+      ,in7_execution_date)
+    ON CONFLICT DO NOTHING
+    RETURNING reserve_pub)
+  SELECT reserve_pub FROM reserve_changes;
 
-  WHILE k < 8 LOOP
-    FETCH FROM curs_transaction_existed INTO r;
-    IF FOUND
+  k=0;
+  <<loop_transaction>> LOOP
+    FETCH FROM curs_transaction_exist INTO i;
+    IF NOT FOUND
     THEN
-      IF in_reserve_pub = r.reserve_pub
-      THEN
-         transaction_duplicate = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in_notify);
-      END IF;
-      IF in2_reserve_pub = r.reserve_pub
-      THEN
-         transaction_duplicate2 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in2_notify);
-      END IF;
-      IF in3_reserve_pub = r.reserve_pub
-      THEN
-         transaction_duplicate3 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in3_notify);
-      END IF;
-      IF in4_reserve_pub = r.reserve_pub
-      THEN
-         transaction_duplicate4 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in4_notify);
-      END IF;
-      IF in5_reserve_pub = r.reserve_pub
-      THEN
-         transaction_duplicate5 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in5_notify);
-      END IF;
-      IF in6_reserve_pub = r.reserve_pub
-      THEN
-         transaction_duplicate6 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in6_notify);
-      END IF;
-      IF in7_reserve_pub = r.reserve_pub
-      THEN
-         transaction_duplicate7 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in7_notify);
-      END IF;
-      IF in8_reserve_pub = r.reserve_pub
-      THEN
-         transaction_duplicate8 = FALSE;
-         EXECUTE FORMAT (
-         'NOTIFY %s'
-         ,in8_notify);
-      END IF;
+      EXIT loop_transaction;
     END IF;
-  k=k+1;
-  END LOOP;
- /* IF transaction_duplicate
-  OR transaction_duplicate2
-  OR transaction_duplicate3
-  OR transaction_duplicate4
-  OR transaction_duplicate5
-  OR transaction_duplicate6
-  OR transaction_duplicate7
-  OR transaction_duplicate8
-  THEN
-    CLOSE curs_transaction_existed;
-    ROLLBACK;
-    RETURN;
-  END IF;*/
-  CLOSE curs_transaction_existed;
+
+    <<loop2_k>> LOOP
+      CASE k
+        WHEN 0 THEN
+          k = k + 1;
+          IF in0_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate0 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in0_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 1 THEN
+          k = k + 1;
+          IF in1_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate1 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in1_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 2 THEN
+          k = k + 1;
+          IF in2_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate2 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in2_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 3 THEN
+          k = k + 1;
+          IF in3_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate3 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in3_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 4 THEN
+          k = k + 1;
+          IF in4_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate4 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in4_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 5 THEN
+          k = k + 1;
+          IF in5_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate2 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in5_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 6 THEN
+          k = k + 1;
+          IF in6_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate6 = FALSE;
+            EXECUTE FORMAT (
+               'NOTIFY %s'
+              ,in6_notify);
+            CONTINUE loop_transaction;
+          END IF;
+          CONTINUE loop2_k;
+        WHEN 7 THEN
+          IF in7_reserve_pub = r.reserve_pub
+          THEN
+            transaction_duplicate7 = FALSE;
+            EXECUTE FORMAT (
+              'NOTIFY %s'
+              ,in7_notify);
+            EXIT loop_transaction;
+          END IF;
+      END CASE;
+    END LOOP loop2_k;
+  END LOOP loop_transaction;
+
+  CLOSE curs_transaction_exist;
   RETURN;
 END $$;
diff --git a/src/exchangedb/pg_reserves_in_insert.c 
b/src/exchangedb/pg_reserves_in_insert.c
index 876774de..2e29a185 100644
--- a/src/exchangedb/pg_reserves_in_insert.c
+++ b/src/exchangedb/pg_reserves_in_insert.c
@@ -55,53 +55,107 @@ compute_notify_on_reserve (const struct 
TALER_ReservePublicKeyP *reserve_pub)
 }
 
 
+/**
+ * Record we keep per reserve to process.
+ */
+struct ReserveRecord
+{
+  /**
+   * Details about reserve to insert (input).
+   */
+  const struct TALER_EXCHANGEDB_ReserveInInfo *reserve;
+
+  /**
+   * Hash of the payto URI in @e reserve.
+   */
+  struct TALER_PaytoHashP h_payto;
+
+  /**
+   * Notification to trigger on the reserve (input).
+   */
+  char *notify_s;
+
+  /**
+   * Set to UUID of the reserve (output);
+   */
+  uint64_t reserve_uuid;
+
+  /**
+   * Set to true if the transaction was an exact duplicate (output).
+   */
+  bool transaction_duplicate;
+
+  /**
+   * Set to true if the transaction conflicted with an existing reserve 
(output)
+   * and needs to be re-done with an UPDATE.
+   */
+  bool conflicts;
+};
+
+
+/**
+ * Generate the SQL parameters to insert the record @a rr at
+ * index @a index
+ */
+#define RR_QUERY_PARAM(rr,index) \
+  GNUNET_PQ_query_param_auto_from_type (rr[index].reserve->reserve_pub),    \
+  GNUNET_PQ_query_param_uint64 (&rr[index].reserve->wire_reference),        \
+  TALER_PQ_query_param_amount (rr[index].reserve->balance),                 \
+  GNUNET_PQ_query_param_string (rr[index].reserve->exchange_account_name),  \
+  GNUNET_PQ_query_param_timestamp (&rr[index].reserve->execution_time),     \
+  GNUNET_PQ_query_param_auto_from_type (&rr[index].h_payto),                \
+  GNUNET_PQ_query_param_string (rr[index].reserve->sender_account_details), \
+  GNUNET_PQ_query_param_string (rr[index].notify_s)
+
+
+/**
+ * Generate the SQL parameters to obtain results for record @a rr at
+ * index @a index
+ */
+#define RR_RESULT_PARAM(rr,index) \
+  GNUNET_PQ_result_spec_bool ("conflicted" TALER_S (index),            \
+                              &rr[index].conflicts),                   \
+  GNUNET_PQ_result_spec_bool ("transaction_duplicate" TALER_S (index), \
+                              &rr[index].transaction_duplicate),       \
+  GNUNET_PQ_result_spec_uint64 ("reserve_uuid" TALER_S (index),        \
+                                &rr[index].reserve_uuid)
+
+
+/**
+ * Insert 1 reserve record @a rr into the database.
+ *
+ * @param pg database context
+ * @param gc gc timestamp to use
+ * @param reserve_expiration expiration time to use
+ * @param[in,out] rr array of reserve details to use and update
+ * @return database transaction status
+ */
 static enum GNUNET_DB_QueryStatus
 insert1 (struct PostgresClosure *pg,
-         const struct TALER_EXCHANGEDB_ReserveInInfo reserves[1],
          struct GNUNET_TIME_Timestamp gc,
-         char *const *notify_s,
          struct GNUNET_TIME_Timestamp reserve_expiration,
-         bool *transaction_duplicate,
-         bool *conflict,
-         uint64_t *reserve_uuid)
+         struct ReserveRecord *rr)
 {
   enum GNUNET_DB_QueryStatus qs;
-  struct TALER_PaytoHashP h_payto0;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_timestamp (&gc),
     GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[0].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[0].wire_reference),
-    TALER_PQ_query_param_amount (reserves[0].balance),
-    GNUNET_PQ_query_param_string (reserves[0].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[0].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto0),
-    GNUNET_PQ_query_param_string (reserves[0].sender_account_details),
-
-    GNUNET_PQ_query_param_string (notify_s[0]),
+    RR_QUERY_PARAM (rr, 0),
     GNUNET_PQ_query_param_end
   };
   struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_bool ("conflicted",
-                                &conflict[0]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate",
-                                &transaction_duplicate[0]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
-                                  &reserve_uuid[0]),
+    RR_RESULT_PARAM (rr, 0),
     GNUNET_PQ_result_spec_end
   };
 
   PREPARE (pg,
            "batch1_reserve_create",
            "SELECT "
-           " out_reserve_found AS conflicted"
-           ",transaction_duplicate"
-           ",ruuid AS reserve_uuid"
+           " out_reserve_found0 AS conflicted0"
+           ",transaction_duplicate0 AS transaction_duplicate0"
+           ",ruuid0 AS reserve_uuid0"
            " FROM exchange_do_batch_reserves_in_insert"
            " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);");
-  TALER_payto_hash (reserves[0].sender_account_details,
-                    &h_payto0);
   qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                  "batch1_reserve_create",
                                                  params,
@@ -114,7 +168,7 @@ insert1 (struct PostgresClosure *pg,
     return qs;
   }
   GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
-  if ((! conflict[0]) && transaction_duplicate[0])
+  if ((! rr[0].conflicts) && rr[0].transaction_duplicate)
   {
     GNUNET_break (0);
     TEH_PG_rollback (pg);
@@ -124,463 +178,257 @@ insert1 (struct PostgresClosure *pg,
 }
 
 
+/**
+ * Insert 2 reserve records @a rr into the database.
+ *
+ * @param pg database context
+ * @param gc gc timestamp to use
+ * @param reserve_expiration expiration time to use
+ * @param[in,out] rr array of reserve details to use and update
+ * @return database transaction status
+ */
 static enum GNUNET_DB_QueryStatus
 insert2 (struct PostgresClosure *pg,
-         const struct TALER_EXCHANGEDB_ReserveInInfo reserves[2],
          struct GNUNET_TIME_Timestamp gc,
-         char *const*notify_s,
          struct GNUNET_TIME_Timestamp reserve_expiration,
-         bool *transaction_duplicate,
-         bool *conflict,
-         uint64_t *reserve_uuid)
+         struct ReserveRecord *rr)
 {
-  enum GNUNET_DB_QueryStatus qs1;
-  struct TALER_PaytoHashP h_payto[2];
+  enum GNUNET_DB_QueryStatus qs;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_timestamp (&gc),
     GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[0].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[0].wire_reference),
-    TALER_PQ_query_param_amount (reserves[0].balance),
-    GNUNET_PQ_query_param_string (reserves[0].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[0].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[0]),
-    GNUNET_PQ_query_param_string (reserves[0].sender_account_details),
-
-    GNUNET_PQ_query_param_string (notify_s[0]),
-    GNUNET_PQ_query_param_string (notify_s[1]),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[1].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[1].wire_reference),
-    TALER_PQ_query_param_amount (reserves[1].balance),
-    GNUNET_PQ_query_param_string (reserves[1].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[1].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[1]),
-    GNUNET_PQ_query_param_string (reserves[1].sender_account_details),
+    RR_QUERY_PARAM (rr, 0),
+    RR_QUERY_PARAM (rr, 1),
     GNUNET_PQ_query_param_end
   };
   struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_bool ("conflicted",
-                                &conflict[0]),
-    GNUNET_PQ_result_spec_bool ("conflicted2",
-                                &conflict[1]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate",
-                                &transaction_duplicate[0]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate2",
-                                &transaction_duplicate[1]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
-                                  &reserve_uuid[0]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid2",
-                                  &reserve_uuid[1]),
+    RR_RESULT_PARAM (rr, 0),
+    RR_RESULT_PARAM (rr, 1),
     GNUNET_PQ_result_spec_end
   };
 
   PREPARE (pg,
            "batch2_reserve_create",
-           "SELECT "
-           "out_reserve_found AS conflicted"
-           ",out_reserve_found2 AS conflicted2"
-           ",transaction_duplicate"
-           ",transaction_duplicate2"
-           ",ruuid AS reserve_uuid"
-           ",ruuid2 AS reserve_uuid2"
+           "SELECT"
+           " out_reserve_found0 AS conflicted0"
+           ",out_reserve_found1 AS conflicted1"
+           ",transaction_duplicate0"
+           ",transaction_duplicate1"
+           ",ruuid0 AS reserve_uuid0"
+           ",ruuid1 AS reserve_uuid1"
            " FROM exchange_do_batch2_reserves_insert"
            " 
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20);");
-  TALER_payto_hash (reserves[0].sender_account_details,
-                    &h_payto[0]);
-  TALER_payto_hash (reserves[1].sender_account_details,
-                    &h_payto[1]);
-  qs1 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                  "batch2_reserve_create",
-                                                  params,
-                                                  rs);
-  if (qs1 < 0)
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                 "batch2_reserve_create",
+                                                 params,
+                                                 rs);
+  if (qs < 0)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Failed to create reserves 2(%d)\n",
-                qs1);
-    return qs1;
+                qs);
+    return qs;
   }
-
-  GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs1);
-  if ( ((! conflict[0]) && (transaction_duplicate[0])) ||
-       ((! conflict[1]) && (transaction_duplicate[1])) )
+  GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
+  for (unsigned int i = 0; i<2; i++)
   {
-    GNUNET_break (0);
-    TEH_PG_rollback (pg);
-    return GNUNET_DB_STATUS_HARD_ERROR;
+    if ((! rr[i].conflicts) && (rr[i].transaction_duplicate))
+    {
+      GNUNET_break (0);
+      TEH_PG_rollback (pg);
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
   }
-  return qs1;
+  return qs;
 }
 
 
+/**
+ * Insert 4 reserve records @a rr into the database.
+ *
+ * @param pg database context
+ * @param gc gc timestamp to use
+ * @param reserve_expiration expiration time to use
+ * @param[in,out] rr array of reserve details to use and update
+ * @return database transaction status
+ */
 static enum GNUNET_DB_QueryStatus
 insert4 (struct PostgresClosure *pg,
-         const struct TALER_EXCHANGEDB_ReserveInInfo reserves[4],
          struct GNUNET_TIME_Timestamp gc,
-         char *const*notify_s,
          struct GNUNET_TIME_Timestamp reserve_expiration,
-         bool *transaction_duplicate,
-         bool *conflict,
-         uint64_t *reserve_uuid)
+         struct ReserveRecord *rr)
 {
-  enum GNUNET_DB_QueryStatus qs3;
-  struct TALER_PaytoHashP h_payto[4];
+  enum GNUNET_DB_QueryStatus qs;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_timestamp (&gc),
     GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[0].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[0].wire_reference),
-    TALER_PQ_query_param_amount (reserves[0].balance),
-    GNUNET_PQ_query_param_string (reserves[0].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[0].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[0]),
-    GNUNET_PQ_query_param_string (reserves[0].sender_account_details),
-
-    GNUNET_PQ_query_param_string (notify_s[0]),
-    GNUNET_PQ_query_param_string (notify_s[1]),
-    GNUNET_PQ_query_param_string (notify_s[2]),
-    GNUNET_PQ_query_param_string (notify_s[3]),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[1].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[1].wire_reference),
-    TALER_PQ_query_param_amount (reserves[1].balance),
-    GNUNET_PQ_query_param_string (reserves[1].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[1].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[1]),
-    GNUNET_PQ_query_param_string (reserves[1].sender_account_details),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[2].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[2].wire_reference),
-    TALER_PQ_query_param_amount (reserves[2].balance),
-    GNUNET_PQ_query_param_string (reserves[2].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[2].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[2]),
-    GNUNET_PQ_query_param_string (reserves[2].sender_account_details),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[3].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[3].wire_reference),
-    TALER_PQ_query_param_amount (reserves[3].balance),
-    GNUNET_PQ_query_param_string (reserves[3].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[3].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[3]),
-    GNUNET_PQ_query_param_string (reserves[3].sender_account_details),
-
+    RR_QUERY_PARAM (rr, 0),
+    RR_QUERY_PARAM (rr, 1),
+    RR_QUERY_PARAM (rr, 2),
+    RR_QUERY_PARAM (rr, 3),
     GNUNET_PQ_query_param_end
   };
-
   struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_bool ("conflicted",
-                                &conflict[0]),
-    GNUNET_PQ_result_spec_bool ("conflicted2",
-                                &conflict[1]),
-    GNUNET_PQ_result_spec_bool ("conflicted3",
-                                &conflict[2]),
-    GNUNET_PQ_result_spec_bool ("conflicted4",
-                                &conflict[3]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate",
-                                &transaction_duplicate[0]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate2",
-                                &transaction_duplicate[1]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate3",
-                                &transaction_duplicate[2]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate4",
-                                &transaction_duplicate[3]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
-                                  &reserve_uuid[0]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid2",
-                                  &reserve_uuid[1]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid3",
-                                  &reserve_uuid[2]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid4",
-                                  &reserve_uuid[3]),
+    RR_RESULT_PARAM (rr, 0),
+    RR_RESULT_PARAM (rr, 1),
+    RR_RESULT_PARAM (rr, 2),
+    RR_RESULT_PARAM (rr, 3),
     GNUNET_PQ_result_spec_end
   };
 
   PREPARE (pg,
            "batch4_reserve_create",
-           "SELECT "
-           "out_reserve_found AS conflicted"
+           "SELECT"
+           " out_reserve_found0 AS conflicted0"
+           ",out_reserve_found1 AS conflicted1"
            ",out_reserve_found2 AS conflicted2"
            ",out_reserve_found3 AS conflicted3"
-           ",out_reserve_found4 AS conflicted4"
-           ",transaction_duplicate"
+           ",transaction_duplicate0"
+           ",transaction_duplicate1"
            ",transaction_duplicate2"
            ",transaction_duplicate3"
-           ",transaction_duplicate4"
-           ",ruuid AS reserve_uuid"
+           ",ruuid0 AS reserve_uuid0"
+           ",ruuid1 AS reserve_uuid1"
            ",ruuid2 AS reserve_uuid2"
            ",ruuid3 AS reserve_uuid3"
-           ",ruuid4 AS reserve_uuid4"
            " FROM exchange_do_batch4_reserves_insert"
            " 
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38);");
-
-  for (unsigned int i = 0; i<4; i++)
-    TALER_payto_hash (reserves[i].sender_account_details,
-                      &h_payto[i]);
-  qs3 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                  "batch4_reserve_create",
-                                                  params,
-                                                  rs);
-  if (qs3 < 0)
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                 "batch4_reserve_create",
+                                                 params,
+                                                 rs);
+  if (qs < 0)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Failed to create reserves4 (%d)\n",
-                qs3);
-    return qs3;
+                qs);
+    return qs;
   }
 
-  GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs3);
-
-  if (
-    ((! conflict[0]) && (transaction_duplicate[0]))
-    || ((! conflict[1]) && (transaction_duplicate[1]))
-    || ((! conflict[2]) && (transaction_duplicate[2]))
-    || ((! conflict[3]) && (transaction_duplicate[3]))
-    )
+  GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
+  for (unsigned int i = 0; i<4; i++)
   {
-    GNUNET_break (0);
-    TEH_PG_rollback (pg);
-    return GNUNET_DB_STATUS_HARD_ERROR;
+    if ((! rr[i].conflicts) && (rr[i].transaction_duplicate))
+    {
+      GNUNET_break (0);
+      TEH_PG_rollback (pg);
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
   }
-  return qs3;
+  return qs;
 }
 
 
+/**
+ * Insert 8 reserve records @a rr into the database.
+ *
+ * @param pg database context
+ * @param gc gc timestamp to use
+ * @param reserve_expiration expiration time to use
+ * @param[in,out] rr array of reserve details to use and update
+ * @return database transaction status
+ */
 static enum GNUNET_DB_QueryStatus
 insert8 (struct PostgresClosure *pg,
-         const struct TALER_EXCHANGEDB_ReserveInInfo reserves[8],
          struct GNUNET_TIME_Timestamp gc,
-         char *const*notify_s,
          struct GNUNET_TIME_Timestamp reserve_expiration,
-         bool *transaction_duplicate,
-         bool *conflict,
-         uint64_t *reserve_uuid)
+         struct ReserveRecord *rr)
 {
-  enum GNUNET_DB_QueryStatus qs3;
-  struct TALER_PaytoHashP h_payto[8];
+  enum GNUNET_DB_QueryStatus qs;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_timestamp (&gc),
     GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[0].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[0].wire_reference),
-    TALER_PQ_query_param_amount (reserves[0].balance),
-    GNUNET_PQ_query_param_string (reserves[0].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[0].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[0]),
-    GNUNET_PQ_query_param_string (reserves[0].sender_account_details),
-
-    GNUNET_PQ_query_param_string (notify_s[0]),
-    GNUNET_PQ_query_param_string (notify_s[1]),
-    GNUNET_PQ_query_param_string (notify_s[2]),
-    GNUNET_PQ_query_param_string (notify_s[3]),
-    GNUNET_PQ_query_param_string (notify_s[4]),
-    GNUNET_PQ_query_param_string (notify_s[5]),
-    GNUNET_PQ_query_param_string (notify_s[6]),
-    GNUNET_PQ_query_param_string (notify_s[7]),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[1].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[1].wire_reference),
-    TALER_PQ_query_param_amount (reserves[1].balance),
-    GNUNET_PQ_query_param_string (reserves[1].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[1].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[1]),
-    GNUNET_PQ_query_param_string (reserves[1].sender_account_details),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[2].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[2].wire_reference),
-    TALER_PQ_query_param_amount (reserves[2].balance),
-    GNUNET_PQ_query_param_string (reserves[2].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[2].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[2]),
-    GNUNET_PQ_query_param_string (reserves[2].sender_account_details),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[3].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[3].wire_reference),
-    TALER_PQ_query_param_amount (reserves[3].balance),
-    GNUNET_PQ_query_param_string (reserves[3].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[3].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[3]),
-    GNUNET_PQ_query_param_string (reserves[3].sender_account_details),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[4].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[4].wire_reference),
-    TALER_PQ_query_param_amount (reserves[4].balance),
-    GNUNET_PQ_query_param_string (reserves[4].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[4].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[4]),
-    GNUNET_PQ_query_param_string (reserves[4].sender_account_details),
-    GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[5].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[5].wire_reference),
-    TALER_PQ_query_param_amount (reserves[5].balance),
-    GNUNET_PQ_query_param_string (reserves[5].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[5].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[5]),
-    GNUNET_PQ_query_param_string (reserves[5].sender_account_details),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[6].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[6].wire_reference),
-    TALER_PQ_query_param_amount (reserves[6].balance),
-    GNUNET_PQ_query_param_string (reserves[6].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[6].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[6]),
-    GNUNET_PQ_query_param_string (reserves[6].sender_account_details),
-
-    GNUNET_PQ_query_param_auto_from_type (reserves[7].reserve_pub),
-    GNUNET_PQ_query_param_uint64 (&reserves[7].wire_reference),
-    TALER_PQ_query_param_amount (reserves[7].balance),
-    GNUNET_PQ_query_param_string (reserves[7].exchange_account_name),
-    GNUNET_PQ_query_param_timestamp (&reserves[7].execution_time),
-    GNUNET_PQ_query_param_auto_from_type (&h_payto[7]),
-    GNUNET_PQ_query_param_string (reserves[7].sender_account_details),
-
+    RR_QUERY_PARAM (rr, 0),
+    RR_QUERY_PARAM (rr, 1),
+    RR_QUERY_PARAM (rr, 2),
+    RR_QUERY_PARAM (rr, 3),
+    RR_QUERY_PARAM (rr, 4),
+    RR_QUERY_PARAM (rr, 5),
+    RR_QUERY_PARAM (rr, 6),
+    RR_QUERY_PARAM (rr, 7),
     GNUNET_PQ_query_param_end
   };
-
   struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_bool ("conflicted",
-                                &conflict[0]),
-    GNUNET_PQ_result_spec_bool ("conflicted2",
-                                &conflict[1]),
-    GNUNET_PQ_result_spec_bool ("conflicted3",
-                                &conflict[2]),
-    GNUNET_PQ_result_spec_bool ("conflicted4",
-                                &conflict[3]),
-    GNUNET_PQ_result_spec_bool ("conflicted5",
-                                &conflict[4]),
-    GNUNET_PQ_result_spec_bool ("conflicted6",
-                                &conflict[5]),
-    GNUNET_PQ_result_spec_bool ("conflicted7",
-                                &conflict[6]),
-    GNUNET_PQ_result_spec_bool ("conflicted8",
-                                &conflict[7]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate",
-                                &transaction_duplicate[0]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate2",
-                                &transaction_duplicate[1]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate3",
-                                &transaction_duplicate[2]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate4",
-                                &transaction_duplicate[3]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate5",
-                                &transaction_duplicate[4]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate6",
-                                &transaction_duplicate[5]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate7",
-                                &transaction_duplicate[6]),
-    GNUNET_PQ_result_spec_bool ("transaction_duplicate8",
-                                &transaction_duplicate[7]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
-                                  &reserve_uuid[0]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid2",
-                                  &reserve_uuid[1]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid3",
-                                  &reserve_uuid[2]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid4",
-                                  &reserve_uuid[3]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid5",
-                                  &reserve_uuid[4]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid6",
-                                  &reserve_uuid[5]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid7",
-                                  &reserve_uuid[6]),
-    GNUNET_PQ_result_spec_uint64 ("reserve_uuid8",
-                                  &reserve_uuid[7]),
+    RR_RESULT_PARAM (rr, 0),
+    RR_RESULT_PARAM (rr, 1),
+    RR_RESULT_PARAM (rr, 2),
+    RR_RESULT_PARAM (rr, 3),
+    RR_RESULT_PARAM (rr, 4),
+    RR_RESULT_PARAM (rr, 5),
+    RR_RESULT_PARAM (rr, 6),
+    RR_RESULT_PARAM (rr, 7),
     GNUNET_PQ_result_spec_end
   };
 
   PREPARE (pg,
            "batch8_reserve_create",
            "SELECT"
-           " out_reserve_found AS conflicted"
+           " out_reserve_found0 AS conflicted0"
+           ",out_reserve_found1 AS conflicted1"
            ",out_reserve_found2 AS conflicted2"
            ",out_reserve_found3 AS conflicted3"
            ",out_reserve_found4 AS conflicted4"
            ",out_reserve_found5 AS conflicted5"
            ",out_reserve_found6 AS conflicted6"
            ",out_reserve_found7 AS conflicted7"
-           ",out_reserve_found8 AS conflicted8"
-           ",transaction_duplicate"
+           ",transaction_duplicate0"
+           ",transaction_duplicate1"
            ",transaction_duplicate2"
            ",transaction_duplicate3"
            ",transaction_duplicate4"
            ",transaction_duplicate5"
            ",transaction_duplicate6"
            ",transaction_duplicate7"
-           ",transaction_duplicate8"
-           ",ruuid AS reserve_uuid"
+           ",ruuid0 AS reserve_uuid0"
+           ",ruuid1 AS reserve_uuid1"
            ",ruuid2 AS reserve_uuid2"
            ",ruuid3 AS reserve_uuid3"
            ",ruuid4 AS reserve_uuid4"
            ",ruuid5 AS reserve_uuid5"
            ",ruuid6 AS reserve_uuid6"
            ",ruuid7 AS reserve_uuid7"
-           ",ruuid8 AS reserve_uuid8"
            " FROM exchange_do_batch8_reserves_insert"
            " 
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,
 $40, 
$41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$70,$71,$72,$73,$74);");
 
-  for (unsigned int i = 0; i<8; i++)
-    TALER_payto_hash (reserves[i].sender_account_details,
-                      &h_payto[i]);
-  qs3 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                  "batch8_reserve_create",
-                                                  params,
-                                                  rs);
-  if (qs3 < 0)
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                 "batch8_reserve_create",
+                                                 params,
+                                                 rs);
+  if (qs < 0)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Failed to create reserves8 (%d)\n",
-                qs3);
-    return qs3;
+                qs);
+    return qs;
   }
 
-  GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs3);
-  if (
-    ((! conflict[0]) && (transaction_duplicate[0]))
-    || ((! conflict[1]) && (transaction_duplicate[1]))
-    || ((! conflict[2]) && (transaction_duplicate[2]))
-    || ((! conflict[3]) && (transaction_duplicate[3]))
-    || ((! conflict[4]) && (transaction_duplicate[4]))
-    || ((! conflict[5]) && (transaction_duplicate[5]))
-    || ((! conflict[6]) && (transaction_duplicate[6]))
-    || ((! conflict[7]) && (transaction_duplicate[7]))
-    )
+  GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs);
+  for (unsigned int i = 0; i<8; i++)
   {
-    GNUNET_break (0);
-    TEH_PG_rollback (pg);
-    return GNUNET_DB_STATUS_HARD_ERROR;
+    if ((! rr[i].conflicts) && (rr[i].transaction_duplicate))
+    {
+      GNUNET_break (0);
+      TEH_PG_rollback (pg);
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
   }
-  return qs3;
+  return qs;
 }
 
 
-enum GNUNET_DB_QueryStatus
-TEH_PG_reserves_in_insert (
-  void *cls,
-  const struct TALER_EXCHANGEDB_ReserveInInfo *reserves,
+static enum GNUNET_DB_QueryStatus
+transact (
+  struct PostgresClosure *pg,
+  struct ReserveRecord *rr,
   unsigned int reserves_length,
   unsigned int batch_size,
   enum GNUNET_DB_QueryStatus *results)
 {
-  struct PostgresClosure *pg = cls;
-  enum GNUNET_DB_QueryStatus qs1;
-  enum GNUNET_DB_QueryStatus qs2;
-  enum GNUNET_DB_QueryStatus qs4;
-  enum GNUNET_DB_QueryStatus qs5;
-  uint64_t reserve_uuid[reserves_length];
-  bool transaction_duplicate[reserves_length];
-  bool need_update = false;
   struct GNUNET_TIME_Timestamp reserve_expiration
     = GNUNET_TIME_relative_to_timestamp (pg->idle_reserve_expiration_time);
   struct GNUNET_TIME_Timestamp gc
     = GNUNET_TIME_relative_to_timestamp (pg->legal_reserve_expiration_time);
-  bool conflicts[reserves_length];
-  char *notify_s[reserves_length];
+  bool need_update = false;
 
   if (GNUNET_OK !=
       TEH_PG_preflight (pg))
@@ -589,13 +437,6 @@ TEH_PG_reserves_in_insert (
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Creating reserve %s with expiration in %s\n",
-              TALER_B2S (&(reserves->reserve_pub)),
-              GNUNET_STRINGS_relative_time_to_string (
-                pg->idle_reserve_expiration_time,
-                GNUNET_NO));
-
   if (GNUNET_OK !=
       TEH_PG_start_read_committed (pg,
                                    "READ_COMMITED"))
@@ -604,144 +445,74 @@ TEH_PG_reserves_in_insert (
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
-  /* Optimistically assume this is a new reserve, create balance for the first
-     time; we do this before adding the actual transaction to "reserves_in",
-     as for a new reserve it can't be a duplicate 'add' operation, and as
-     the 'add' operation needs the reserve entry as a foreign key. */
-  for (unsigned int i = 0; i<reserves_length; i++)
   {
-    const struct TALER_EXCHANGEDB_ReserveInInfo *reserve = &reserves[i];
+    unsigned int i = 0;
 
-    notify_s[i] = compute_notify_on_reserve (reserve->reserve_pub);
-  }
-
-  unsigned int i = 0;
-
-  while (i < reserves_length)
-  {
-    unsigned int bs = GNUNET_MIN (batch_size,
-                                  reserves_length - i);
-    if (bs >= 8)
+    while (i < reserves_length)
     {
-      qs1 = insert8 (pg,
-                     &reserves[i],
-                     gc,
-                     &notify_s[i],
-                     reserve_expiration,
-                     &transaction_duplicate[i],
-                     &conflicts[i],
-                     &reserve_uuid[i]);
-
-      if (qs1<0)
+      enum GNUNET_DB_QueryStatus qs;
+      enum GNUNET_DB_QueryStatus
+      (*fun)(struct PostgresClosure *pg,
+             struct GNUNET_TIME_Timestamp gc,
+             struct GNUNET_TIME_Timestamp reserve_expiration,
+             struct ReserveRecord *rr);
+      unsigned int lim;
+      unsigned int bs;
+
+      bs = GNUNET_MIN (batch_size,
+                       reserves_length - i);
+      switch (bs)
       {
-        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                    "Failed to create reserve batch_8 (%d)\n",
-                    qs1);
-        results[i] = qs1;
-        return qs1;
+      case 7:
+      case 6:
+      case 5:
+      case 4:
+        fun = &insert4;
+        lim = 4;
+        break;
+      case 3:
+      case 2:
+        fun = &insert2;
+        lim = 2;
+        break;
+      case 1:
+        fun = &insert1;
+        lim = 1;
+        break;
+      case 0:
+        GNUNET_assert (0);
+        break;
+      default:
+        fun = insert8;
+        lim = 8;
+        break;
       }
-      need_update |= conflicts[i];
-      need_update |= conflicts[i + 1];
-      need_update |= conflicts[i + 2];
-      need_update |= conflicts[i + 3];
-      need_update |= conflicts[i + 4];
-      need_update |= conflicts[i + 5];
-      need_update |= conflicts[i + 6];
-      need_update |= conflicts[i + 7];
-      for (unsigned int j = 0; j<8; j++)
-        results[i + j] = transaction_duplicate[i + j]
-          ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
-          : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-      i += 8;
-      continue;
-    }
-    switch (bs)
-    {
-    case 7:
-    case 6:
-    case 5:
-    case 4:
-      qs4 = insert4 (pg,
-                     &reserves[i],
-                     gc,
-                     &notify_s[i],
-                     reserve_expiration,
-                     &transaction_duplicate[i],
-                     &conflicts[i],
-                     &reserve_uuid[i]);
-      if (qs4<0)
+
+      qs = fun (pg,
+                gc,
+                reserve_expiration,
+                &rr[i]);
+      if (qs < 0)
       {
         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                    "Failed to create reserve batch_4 (%d)\n",
-                    qs4);
-        results[i] = qs4;
-        return qs4;
+                    "Failed to create reserve batch_%u (%d)\n",
+                    lim,
+                    qs);
+        results[i] = qs;
+        return qs;
       }
-      need_update |= conflicts[i];
-      need_update |= conflicts[i + 1];
-      need_update |= conflicts[i + 2];
-      need_update |= conflicts[i + 3];
-      for (unsigned int j = 0; j<4; j++)
-        results[i + j] = transaction_duplicate[i + j]
-          ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
-          : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-      i += 4;
-      break;
-    case 3:
-    case 2:
-      qs5 = insert2 (pg,
-                     &reserves[i],
-                     gc,
-                     &notify_s[i],
-                     reserve_expiration,
-                     &transaction_duplicate[i],
-                     &conflicts[i],
-                     &reserve_uuid[i]);
-      if (qs5<0)
+      for (unsigned int j = 0; j<lim; j++)
       {
-        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                    "Failed to create reserve batch_2 (%d)\n",
-                    qs5);
-        results[i] = qs5;
-        return qs5;
-      }
-      need_update |= conflicts[i];
-      need_update |= conflicts[i + 1];
-      for (unsigned int j = 0; j<2; j++)
-        results[i + j] = transaction_duplicate[i + j]
+        need_update |= rr[i + j].conflicts;
+        results[i + j] = rr[i + j].transaction_duplicate
           ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
           : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-      i += 2;
-      break;
-    case 1:
-      qs2 = insert1 (pg,
-                     &reserves[i],
-                     gc,
-                     &notify_s[i],
-                     reserve_expiration,
-                     &transaction_duplicate[i],
-                     &conflicts[i],
-                     &reserve_uuid[i]);
-      if (qs2<0)
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                    "Failed to create reserve batch_1 (%d)\n)",
-                    qs2);
-        results[i] = qs2;
-        return qs2;
       }
-      need_update |= conflicts[i];
-      results[i] = (transaction_duplicate[i])
-        ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
-        : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-      i += 1;
-      break;
-    case 0:
-      GNUNET_assert (0);
-      break;
-    }
-  } /* end while */
-  // commit
+      i += lim;
+      continue;
+    } /* end while */
+  } /* end scope i */
+
   {
     enum GNUNET_DB_QueryStatus cs;
 
@@ -753,19 +524,16 @@ TEH_PG_reserves_in_insert (
       return cs;
     }
   }
+
   if (! need_update)
+    return reserves_length;
+
+  if (GNUNET_OK !=
+      TEH_PG_start (pg,
+                    "reserve-insert-continued"))
   {
-    goto exit;
-  }
-  // begin serializable
-  {
-    if (GNUNET_OK !=
-        TEH_PG_start (pg,
-                      "reserve-insert-continued"))
-    {
-      GNUNET_break (0);
-      return GNUNET_DB_STATUS_HARD_ERROR;
-    }
+    GNUNET_break (0);
+    return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
   PREPARE (pg,
@@ -776,19 +544,18 @@ TEH_PG_reserves_in_insert (
            " ($1,$2,$3,$4,$5,$6,$7,$8);");
   for (unsigned int i = 0; i<reserves_length; i++)
   {
-    if (! conflicts[i])
+    if (! rr[i].conflicts)
       continue;
     {
       bool duplicate;
-      struct TALER_PaytoHashP h_payto;
       struct GNUNET_PQ_QueryParam params[] = {
-        GNUNET_PQ_query_param_auto_from_type (reserves[i].reserve_pub),
+        GNUNET_PQ_query_param_auto_from_type (rr[i].reserve->reserve_pub),
         GNUNET_PQ_query_param_timestamp (&reserve_expiration),
-        GNUNET_PQ_query_param_uint64 (&reserves[i].wire_reference),
-        TALER_PQ_query_param_amount (reserves[i].balance),
-        GNUNET_PQ_query_param_string (reserves[i].exchange_account_name),
-        GNUNET_PQ_query_param_auto_from_type (&h_payto),
-        GNUNET_PQ_query_param_string (notify_s[i]),
+        GNUNET_PQ_query_param_uint64 (&rr[i].reserve->wire_reference),
+        TALER_PQ_query_param_amount (rr[i].reserve->balance),
+        GNUNET_PQ_query_param_string (rr[i].reserve->exchange_account_name),
+        GNUNET_PQ_query_param_auto_from_type (&rr[i].h_payto),
+        GNUNET_PQ_query_param_string (rr[i].notify_s),
         GNUNET_PQ_query_param_end
       };
       struct GNUNET_PQ_ResultSpec rs[] = {
@@ -796,21 +563,19 @@ TEH_PG_reserves_in_insert (
                                     &duplicate),
         GNUNET_PQ_result_spec_end
       };
-      enum GNUNET_DB_QueryStatus qs3;
-
-      TALER_payto_hash (reserves[i].sender_account_details,
-                        &h_payto);
-      qs3 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                      "reserves_update",
-                                                      params,
-                                                      rs);
-      if (qs3<0)
+      enum GNUNET_DB_QueryStatus qs;
+
+      qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                     "reserves_update",
+                                                     params,
+                                                     rs);
+      if (qs < 0)
       {
         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                     "Failed to update reserves (%d)\n",
-                    qs3);
-        results[i] = qs3;
-        return qs3;
+                    qs);
+        results[i] = qs;
+        return qs;
       }
       results[i] = duplicate
           ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
@@ -819,20 +584,49 @@ TEH_PG_reserves_in_insert (
   }
 
   {
-    enum GNUNET_DB_QueryStatus cs;
+    enum GNUNET_DB_QueryStatus cs = TEH_PG_commit (pg);
 
-    cs = TEH_PG_commit (pg);
-    if (cs < 0)
-    {
-      for (unsigned int i = 0; i<reserves_length; i++)
-        GNUNET_free (notify_s[i]);
+    if (0 > cs)
       return cs;
-    }
   }
+  return reserves_length;
+}
 
-exit:
-  for (unsigned int i = 0; i<reserves_length; i++)
-    GNUNET_free (notify_s[i]);
 
-  return reserves_length;
+enum GNUNET_DB_QueryStatus
+TEH_PG_reserves_in_insert (
+  void *cls,
+  const struct TALER_EXCHANGEDB_ReserveInInfo *reserves,
+  unsigned int reserves_length,
+  unsigned int batch_size,
+  enum GNUNET_DB_QueryStatus *results)
+{
+  struct PostgresClosure *pg = cls;
+  struct ReserveRecord rrs[reserves_length];
+  enum GNUNET_DB_QueryStatus qs;
+
+  for (unsigned int i = 0; i<reserves_length; i++)
+  {
+    const struct TALER_EXCHANGEDB_ReserveInInfo *reserve = &reserves[i];
+    struct ReserveRecord *rr = &rrs[i];
+
+    rr->reserve = reserve;
+    TALER_payto_hash (reserves->sender_account_details,
+                      &rr->h_payto);
+    rr->notify_s = compute_notify_on_reserve (reserve->reserve_pub);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Creating reserve %s with expiration in %s\n",
+                TALER_B2S (&reserve->reserve_pub),
+                GNUNET_STRINGS_relative_time_to_string (
+                  pg->idle_reserve_expiration_time,
+                  false));
+  }
+  qs = transact (pg,
+                 rrs,
+                 reserves_length,
+                 batch_size,
+                 results);
+  for (unsigned int i = 0; i<reserves_length; i++)
+    GNUNET_free (rrs[i].notify_s);
+  return qs;
 }
diff --git a/src/testing/testing_api_cmd_exec_wirewatch.c 
b/src/testing/testing_api_cmd_exec_wirewatch.c
index 2517bf74..32d23a17 100644
--- a/src/testing/testing_api_cmd_exec_wirewatch.c
+++ b/src/testing/testing_api_cmd_exec_wirewatch.c
@@ -34,7 +34,6 @@
  */
 struct WirewatchState
 {
-
   /**
    * Process for the wirewatcher.
    */
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index 986358ed..1865a112 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -353,7 +353,7 @@ maint_child_death (void *cls)
 
   while (TALER_TESTING_cmd_is_batch (cmd))
     cmd = TALER_TESTING_cmd_batch_get_current (cmd);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Got SIGCHLD for `%s'.\n",
               cmd->label);
   is->child_death_task = NULL;

-- 
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]