gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: combine deposit confirmation sig


From: gnunet
Subject: [taler-merchant] branch master updated: combine deposit confirmation signatures into one big signature
Date: Sun, 24 Sep 2023 19:03:44 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 08b26236 combine deposit confirmation signatures into one big signature
08b26236 is described below

commit 08b2623684a09bf5bb1e30282b1fd314df02b3e7
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Sep 24 19:03:37 2023 +0200

    combine deposit confirmation signatures into one big signature
---
 .../taler-merchant-httpd_post-orders-ID-abort.c    |   5 +-
 .../taler-merchant-httpd_post-orders-ID-pay.c      | 235 ++++++++++++---------
 .../taler-merchant-httpd_private-get-orders-ID.c   |  15 +-
 src/backenddb/Makefile.am                          |   1 +
 src/backenddb/merchant-0001.sql                    |  50 +++--
 src/backenddb/pg_increase_refund.c                 |  15 +-
 src/backenddb/pg_insert_deposit.c                  |  69 ++----
 src/backenddb/pg_insert_deposit.h                  |  33 ++-
 src/backenddb/pg_insert_transfer_details.c         |  60 +++---
 src/backenddb/pg_lookup_deposits.c                 |  23 +-
 src/backenddb/pg_refund_coin.c                     |  14 +-
 src/backenddb/plugin_merchantdb_postgres.c         | 167 +++++++++------
 src/backenddb/test_merchantdb.c                    | 124 ++++-------
 src/include/taler_merchantdb_plugin.h              | 132 +++++++-----
 src/testing/test_merchant_transfer_tracking.sh     |   7 +-
 15 files changed, 502 insertions(+), 448 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
index 09ac8acb..7b6bc7b5 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
@@ -619,7 +619,6 @@ find_next_exchange (struct AbortContext *ac)
  * @param amount_with_fee amount the exchange will deposit for this coin
  * @param deposit_fee fee the exchange will charge for this coin
  * @param refund_fee fee the exchange will charge for refunding this coin
- * @param wire_fee wire fee the exchange of this coin charges
  */
 static void
 refund_coins (void *cls,
@@ -627,8 +626,7 @@ refund_coins (void *cls,
               const struct TALER_CoinSpendPublicKeyP *coin_pub,
               const struct TALER_Amount *amount_with_fee,
               const struct TALER_Amount *deposit_fee,
-              const struct TALER_Amount *refund_fee,
-              const struct TALER_Amount *wire_fee)
+              const struct TALER_Amount *refund_fee)
 {
   struct AbortContext *ac = cls;
   struct GNUNET_TIME_Timestamp now;
@@ -636,7 +634,6 @@ refund_coins (void *cls,
   (void) amount_with_fee;
   (void) deposit_fee;
   (void) refund_fee;
-  (void) wire_fee;
   now = GNUNET_TIME_timestamp_get ();
   for (unsigned int i = 0; i<ac->coins_cnt; i++)
   {
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index fd17f029..c99a6c64 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -89,11 +89,6 @@ struct DepositConfirmation
    */
   struct TALER_Amount refund_fee;
 
-  /**
-   * Wire fee charged by the exchange of this coin.
-   */
-  struct TALER_Amount wire_fee;
-
   /**
    * If a minimum age was required (i. e. pc->minimum_age is large enough),
    * this is the signature of the minimum age (as a single uint8_t), using the
@@ -901,6 +896,107 @@ check_kyc (struct PayContext *pc,
 }
 
 
+/**
+ * Do database transaction for a completed batch deposit.
+ *
+ * @param eg group that completed
+ * @param dr response from the server
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+batch_deposit_transaction (const struct ExchangeGroup *eg,
+                           const struct TALER_EXCHANGE_BatchDepositResult *dr)
+{
+  const struct PayContext *pc = eg->pc;
+  enum GNUNET_DB_QueryStatus qs;
+  struct TALER_Amount total_without_fees = { 0 };
+  uint64_t b_dep_serial;
+  uint32_t off = 0;
+  bool found = false;
+
+  for (unsigned int i = 0; i<pc->coins_cnt; i++)
+  {
+    struct DepositConfirmation *dc = &pc->dc[i];
+    struct TALER_Amount amount_without_fees;
+
+    /* might want to group deposits by batch more explicitly ... */
+    if (0 != strcmp (eg->exchange_url,
+                     dc->exchange_url))
+      continue;
+    if (dc->found_in_db)
+      continue;
+    GNUNET_assert (0 <=
+                   TALER_amount_subtract (&amount_without_fees,
+                                          &dc->cdd.amount,
+                                          &dc->deposit_fee));
+    if (! found)
+    {
+      found = true;
+      total_without_fees = amount_without_fees;
+    }
+    else
+    {
+      GNUNET_assert (
+        0 <=
+        TALER_amount_add (&total_without_fees,
+                          &total_without_fees,
+                          &amount_without_fees));
+    }
+  }
+  qs = TMH_db->insert_deposit_confirmation (
+    TMH_db->cls,
+    pc->hc->instance->settings.id,
+    dr->details.ok.deposit_timestamp,
+    &pc->h_contract_terms,
+    eg->exchange_url,
+    &total_without_fees,
+    &eg->wire_fee,
+    &pc->wm->h_wire,
+    dr->details.ok.exchange_sig,
+    dr->details.ok.exchange_pub,
+    &b_dep_serial);
+  if (qs <= 0)
+    return qs; /* Entire batch already known or failure, we're done */
+
+  if (! found)
+  {
+    /* All coins already done, but the batch was not? Invariant violation! */
+    GNUNET_break (0);
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  }
+
+  for (unsigned int i = 0; i<pc->coins_cnt; i++)
+  {
+    struct DepositConfirmation *dc = &pc->dc[i];
+
+    /* might want to group deposits by batch more explicitly ... */
+    if (0 != strcmp (eg->exchange_url,
+                     dc->exchange_url))
+      continue;
+    if (dc->found_in_db)
+      continue;
+    /* NOTE: We might want to check if the order was fully paid concurrently
+       by some other wallet here, and if so, issue an auto-refund. Right now,
+       it is possible to over-pay if two wallets literally make a concurrent
+       payment, as the earlier check for 'paid' is not in the same transaction
+       scope as this 'insert' operation. */
+    qs = TMH_db->insert_deposit (
+      TMH_db->cls,
+      off++, /* might want to group deposits by batch more explicitly ... */
+      b_dep_serial,
+      &dc->cdd.coin_pub,
+      &dc->cdd.coin_sig,
+      &dc->cdd.amount,
+      &dc->deposit_fee,
+      &dc->refund_fee);
+    if (qs < 0)
+      return qs;
+    GNUNET_break (qs > 0);
+  }
+  return qs;
+}
+
+
 /**
  * Handle case where the batch deposit completed
  * with a status of #MHD_HTTP_OK.
@@ -924,8 +1020,6 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg,
               pc->hc->instance->settings.id);
   for (unsigned int r = 0; r<MAX_RETRIES; r++)
   {
-    unsigned int j = 0;
-
     TMH_db->preflight (TMH_db->cls);
     if (GNUNET_OK !=
         TMH_db->start (TMH_db->cls,
@@ -940,50 +1034,19 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg,
           TMH_pack_exchange_reply (&dr->hr)));
       return;
     }
-    for (unsigned int i = 0; i<pc->coins_cnt; i++)
+    qs = batch_deposit_transaction (eg,
+                                    dr);
+    if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
     {
-      struct DepositConfirmation *dc = &pc->dc[i];
-
-      if (0 != strcmp (eg->exchange_url,
-                       pc->dc[i].exchange_url))
-        continue;
-      if (dc->found_in_db)
-        continue;
-      /* NOTE: We might want to check if the order was fully paid concurrently
-         by some other wallet here, and if so, issue an auto-refund. Right now,
-         it is possible to over-pay if two wallets literally make a concurrent
-         payment, as the earlier check for 'paid' is not in the same 
transaction
-         scope as this 'insert' operation. */
-      GNUNET_assert (j < dr->details.ok.num_signatures);
-      qs = TMH_db->insert_deposit (
-        TMH_db->cls,
-        pc->hc->instance->settings.id,
-        dr->details.ok.deposit_timestamp,
-        &pc->h_contract_terms,
-        &dc->cdd.coin_pub,
-        dc->exchange_url,
-        &dc->cdd.amount,
-        &dc->deposit_fee,
-        &dc->refund_fee,
-        &dc->wire_fee,
-        &pc->wm->h_wire,
-        &dr->details.ok.exchange_sigs[j++],
-        dr->details.ok.exchange_pub);
-      if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
-      {
-        TMH_db->rollback (TMH_db->cls);
-        break;
-      }
-      if (0 > qs)
-      {
-        /* Always report on hard error as well to enable diagnostics */
-        GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
-        /* Forward error including 'proof' for the body */
-        resume_pay_with_error (pc,
-                               TALER_EC_GENERIC_DB_STORE_FAILED,
-                               "insert_deposit");
-        return;
-      }
+      TMH_db->rollback (TMH_db->cls);
+      continue;
+    }
+    if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+    {
+      GNUNET_break (0);
+      resume_pay_with_error (pc,
+                             TALER_EC_GENERIC_DB_COMMIT_FAILED,
+                             "batch_deposit_transaction");
     }
     qs = TMH_db->commit (TMH_db->cls);
     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -999,7 +1062,7 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg,
                              "insert_deposit");
     }
     break; /* DB transaction succeeded */
-  } /* FOR DB retries */
+  }
   if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   {
     resume_pay_with_error (pc,
@@ -1387,7 +1450,6 @@ AGE_FAIL:
                        eg->exchange_url))
         continue;
       cdds[i] = dc->cdd;
-      dc->wire_fee = eg->wire_fee;
     }
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Initiating batch deposit with %u coins\n",
@@ -1509,7 +1571,6 @@ start_batch_deposits (struct PayContext *pc)
  * @param amount_with_fee amount the exchange will deposit for this coin
  * @param deposit_fee fee the exchange will charge for this coin
  * @param refund_fee fee the exchange will charge for refunding this coin
- * @param wire_fee wire fee the exchange of this coin charges
  */
 static void
 check_coin_paid (void *cls,
@@ -1517,8 +1578,7 @@ check_coin_paid (void *cls,
                  const struct TALER_CoinSpendPublicKeyP *coin_pub,
                  const struct TALER_Amount *amount_with_fee,
                  const struct TALER_Amount *deposit_fee,
-                 const struct TALER_Amount *refund_fee,
-                 const struct TALER_Amount *wire_fee)
+                 const struct TALER_Amount *refund_fee)
 {
   struct PayContext *pc = cls;
 
@@ -1551,7 +1611,6 @@ check_coin_paid (void *cls,
                                      deposit_fee));
     dc->deposit_fee = *deposit_fee;
     dc->refund_fee = *refund_fee;
-    dc->wire_fee = *wire_fee;
     dc->cdd.amount = *amount_with_fee;
     dc->found_in_db = true;
     pc->pending--;
@@ -1623,8 +1682,33 @@ check_payment_sufficient (struct PayContext *pc)
             (0 == pc->amount.fraction));
   }
 
+  total_wire_fee = pc->egs[0]->wire_fee;
+  for (unsigned int i = 1; i < pc->num_exchanges; i++)
+  {
+    if (GNUNET_OK !=
+        TALER_amount_cmp_currency (&total_wire_fee,
+                                   &pc->egs[i]->wire_fee))
+    {
+      GNUNET_break_op (0);
+      resume_pay_with_error (pc,
+                             TALER_EC_GENERIC_CURRENCY_MISMATCH,
+                             total_wire_fee.currency);
+      return false;
+    }
+    if (0 >
+        TALER_amount_add (&total_wire_fee,
+                          &total_wire_fee,
+                          &pc->egs[i]->wire_fee))
+    {
+      GNUNET_break (0);
+      resume_pay_with_error (pc,
+                             
TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED,
+                             "could not add exchange wire fee to total");
+      return false;
+    }
+  }
+
   acc_fee = pc->dc[0].deposit_fee;
-  total_wire_fee = pc->dc[0].wire_fee;
   acc_amount = pc->dc[0].cdd.amount;
 
   /**
@@ -1663,43 +1747,6 @@ check_payment_sufficient (struct PayContext *pc)
       return false;
     }
 
-    /* If exchange differs, add wire fee */
-    {
-      bool new_exchange = true;
-
-      for (unsigned int j = 0; j<i; j++)
-        if (0 == strcasecmp (dc->exchange_url,
-                             pc->dc[j].exchange_url))
-        {
-          new_exchange = false;
-          break;
-        }
-
-      if (! new_exchange)
-        continue;
-
-      if (GNUNET_OK !=
-          TALER_amount_cmp_currency (&total_wire_fee,
-                                     &dc->wire_fee))
-      {
-        GNUNET_break_op (0);
-        resume_pay_with_error (pc,
-                               TALER_EC_GENERIC_CURRENCY_MISMATCH,
-                               total_wire_fee.currency);
-        return false;
-      }
-      if (0 >
-          TALER_amount_add (&total_wire_fee,
-                            &total_wire_fee,
-                            &dc->wire_fee))
-      {
-        GNUNET_break (0);
-        resume_pay_with_error (pc,
-                               
TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED,
-                               "could not add exchange wire fee to total");
-        return false;
-      }
-    }
   } /* deposit loop */
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/backend/taler-merchant-httpd_private-get-orders-ID.c 
b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
index f732dc84..20ed5fa7 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -804,13 +804,14 @@ process_refunds_cb (void *cls,
  *        @a wtid over the total amount happened?
  */
 static void
-process_transfer_details (void *cls,
-                          const struct TALER_WireTransferIdentifierRawP *wtid,
-                          const char *exchange_url,
-                          struct GNUNET_TIME_Timestamp execution_time,
-                          const struct TALER_Amount *deposit_value,
-                          const struct TALER_Amount *deposit_fee,
-                          bool transfer_confirmed)
+process_transfer_details (
+  void *cls,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const char *exchange_url,
+  struct GNUNET_TIME_Timestamp execution_time,
+  const struct TALER_Amount *deposit_value,
+  const struct TALER_Amount *deposit_fee,
+  bool transfer_confirmed)
 {
   struct GetOrderRequestContext *gorc = cls;
   json_t *wire_details = gorc->wire_details;
diff --git a/src/backenddb/Makefile.am b/src/backenddb/Makefile.am
index 64b9883e..22041a1d 100644
--- a/src/backenddb/Makefile.am
+++ b/src/backenddb/Makefile.am
@@ -125,6 +125,7 @@ libtaler_plugin_merchantdb_postgres_la_SOURCES = \
   pg_lookup_deposits.h pg_lookup_deposits.c \
   pg_insert_exchange_signkey.h pg_insert_exchange_signkey.c \
   pg_insert_deposit.h pg_insert_deposit.c \
+  pg_insert_deposit_confirmation.h pg_insert_deposit_confirmation.c \
   pg_lookup_refunds.h pg_lookup_refunds.c \
   pg_mark_contract_paid.h pg_mark_contract_paid.c \
   pg_refund_coin.h pg_refund_coin.c \
diff --git a/src/backenddb/merchant-0001.sql b/src/backenddb/merchant-0001.sql
index 4e2b0639..d6b25d8d 100644
--- a/src/backenddb/merchant-0001.sql
+++ b/src/backenddb/merchant-0001.sql
@@ -383,35 +383,61 @@ CREATE INDEX IF NOT EXISTS 
merchant_contract_terms_by_merchant_session_and_fulfi
 
 ---------------- Payment and refunds ---------------------------
 
-CREATE TABLE IF NOT EXISTS merchant_deposits
-  (deposit_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
+CREATE TABLE IF NOT EXISTS merchant_deposit_confirmations
+  (deposit_confirmation_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY 
KEY
   ,order_serial BIGINT
      REFERENCES merchant_contract_terms (order_serial) ON DELETE CASCADE
   ,deposit_timestamp INT8 NOT NULL
-  ,coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)
   ,exchange_url TEXT NOT NULL
-  ,amount_with_fee taler_amount_currency NOT NULL
-  ,deposit_fee taler_amount_currency NOT NULL
-  ,refund_fee taler_amount_currency NOT NULL
+  ,total_without_fee taler_amount_currency NOT NULL
   ,wire_fee taler_amount_currency NOT NULL
   ,signkey_serial BIGINT NOT NULL
      REFERENCES merchant_exchange_signing_keys (signkey_serial) ON DELETE 
CASCADE
   ,exchange_sig BYTEA NOT NULL CHECK (LENGTH(exchange_sig)=64)
   ,account_serial BIGINT NOT NULL
      REFERENCES merchant_accounts (account_serial) ON DELETE CASCADE
-  ,UNIQUE (order_serial, coin_pub)
+  ,UNIQUE (order_serial, exchange_sig)
   );
-COMMENT ON TABLE merchant_deposits
+COMMENT ON TABLE merchant_deposit_confirmations
   IS 'Table with the deposit confirmations for each coin we deposited at the 
exchange';
-COMMENT ON COLUMN merchant_deposits.signkey_serial
+COMMENT ON COLUMN merchant_deposit_confirmations.signkey_serial
   IS 'Online signing key of the exchange on the deposit confirmation';
-COMMENT ON COLUMN merchant_deposits.deposit_timestamp
+COMMENT ON COLUMN merchant_deposit_confirmations.deposit_timestamp
   IS 'Time when the exchange generated the deposit confirmation';
-COMMENT ON COLUMN merchant_deposits.exchange_sig
+COMMENT ON COLUMN merchant_deposit_confirmations.exchange_sig
   IS 'Signature of the exchange over the deposit confirmation';
-COMMENT ON COLUMN merchant_deposits.wire_fee
+COMMENT ON COLUMN merchant_deposit_confirmations.wire_fee
   IS 'We MAY want to see if we should try to get this via 
merchant_exchange_wire_fees (not sure, may be too complicated with the date 
range, etc.)';
 
+
+CREATE TABLE IF NOT EXISTS merchant_deposits
+  (deposit_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
+  ,coin_offset INT4 NOT NULL
+  ,deposit_confirmation_serial BIGINT NOT NULL
+   REFERENCES merchant_deposit_confirmations (deposit_confirmation_serial) ON 
DELETE CASCADE
+  ,coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)
+  ,coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)
+  ,amount_with_fee taler_amount_currency NOT NULL
+  ,deposit_fee taler_amount_currency NOT NULL
+  ,refund_fee taler_amount_currency NOT NULL
+  ,UNIQUE (deposit_confirmation_serial, coin_pub)
+  );
+COMMENT ON TABLE merchant_deposits
+  IS 'Table with the deposit details for each coin we deposited at the 
exchange';
+COMMENT ON COLUMN merchant_deposits.coin_offset
+  IS 'Offset of this coin in the batch';
+COMMENT ON COLUMN merchant_deposits.deposit_confirmation_serial
+  IS 'Reference to the deposit confirmation of the exchange';
+COMMENT ON COLUMN merchant_deposits.coin_pub
+  IS 'Public key of the coin that was deposited';
+COMMENT ON COLUMN merchant_deposits.amount_with_fee
+  IS 'Total amount (incl. fee) of the coin that was deposited';
+COMMENT ON COLUMN merchant_deposits.deposit_fee
+  IS 'Deposit fee (for this coin) that was paid';
+COMMENT ON COLUMN merchant_deposits.refund_fee
+  IS 'How high would the refund fee be (for this coin)';
+
+
 CREATE TABLE IF NOT EXISTS merchant_refunds
   (refund_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
   ,order_serial BIGINT NOT NULL
diff --git a/src/backenddb/pg_increase_refund.c 
b/src/backenddb/pg_increase_refund.c
index 5fd548d7..d274b1e9 100644
--- a/src/backenddb/pg_increase_refund.c
+++ b/src/backenddb/pg_increase_refund.c
@@ -364,7 +364,7 @@ process_deposits_for_refund_cb (
         GNUNET_PQ_query_param_auto_from_type (&rcd[i].coin_pub),
         GNUNET_PQ_query_param_string (ctx->reason),
         TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                     increment),
+                                                   increment),
         GNUNET_PQ_query_param_end
       };
 
@@ -451,20 +451,21 @@ TMH_PG_increase_refund (void *cls,
   PREPARE (pg,
            "find_deposits_for_refund",
            "SELECT"
-           " coin_pub"
-           ",order_serial"
-           ",amount_with_fee"
-           " FROM merchant_deposits"
+           " dep.coin_pub"
+           ",dco.order_serial"
+           ",dep.amount_with_fee"
+           " FROM merchant_deposits dep"
+           " JOIN merchant_deposit_confirmations dco"
+           "   USING (deposit_confirmation_serial)"
            " WHERE order_serial="
            "  (SELECT order_serial"
            "     FROM merchant_contract_terms"
            "    WHERE order_id=$2"
-           "      AND paid=TRUE"
+           "      AND paid"
            "      AND merchant_serial="
            "        (SELECT merchant_serial"
            "           FROM merchant_instances"
            "          WHERE merchant_id=$1))");
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Asked to refund %s on order %s\n",
               TALER_amount2s (refund),
diff --git a/src/backenddb/pg_insert_deposit.c 
b/src/backenddb/pg_insert_deposit.c
index f99c6f44..8e77e24a 100644
--- a/src/backenddb/pg_insert_deposit.c
+++ b/src/backenddb/pg_insert_deposit.c
@@ -30,85 +30,46 @@
 enum GNUNET_DB_QueryStatus
 TMH_PG_insert_deposit (
   void *cls,
-  const char *instance_id,
-  struct GNUNET_TIME_Timestamp deposit_timestamp,
-  const struct TALER_PrivateContractHashP *h_contract_terms,
+  uint32_t offset,
+  uint64_t deposit_confirmation_serial,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
-  const char *exchange_url,
+  const struct TALER_CoinSpendSignatureP *coin_sig,
   const struct TALER_Amount *amount_with_fee,
   const struct TALER_Amount *deposit_fee,
-  const struct TALER_Amount *refund_fee,
-  const struct TALER_Amount *wire_fee,
-  const struct TALER_MerchantWireHashP *h_wire,
-  const struct TALER_ExchangeSignatureP *exchange_sig,
-  const struct TALER_ExchangePublicKeyP *exchange_pub)
+  const struct TALER_Amount *refund_fee)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
-    GNUNET_PQ_query_param_timestamp (&deposit_timestamp), /* $3 */
+    GNUNET_PQ_query_param_uint64 (&deposit_confirmation_serial),
+    GNUNET_PQ_query_param_uint32 (&offset),
     GNUNET_PQ_query_param_auto_from_type (coin_pub),
-    GNUNET_PQ_query_param_string (exchange_url),
+    GNUNET_PQ_query_param_auto_from_type (coin_sig),
     TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                 amount_with_fee),       /* $6 */
+                                               amount_with_fee),
     TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                 deposit_fee),        /* $7 */
+                                               deposit_fee),
     TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                 refund_fee),       /* $8 */
-    TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                 wire_fee),        /* $9 */
-    GNUNET_PQ_query_param_auto_from_type (h_wire), /* $10 */
-    GNUNET_PQ_query_param_auto_from_type (exchange_sig), /* $11 */
-    GNUNET_PQ_query_param_auto_from_type (exchange_pub), /* $12 */
+                                               refund_fee),
     GNUNET_PQ_query_param_end
   };
 
   /* no preflight check here, run in transaction by caller! */
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Storing deposit for instance `%s' h_contract_terms `%s', 
coin_pub: `%s', amount_with_fee: %s\n",
-              instance_id,
-              GNUNET_h2s (&h_contract_terms->hash),
+              "Storing deposit for coin_pub: `%s', amount_with_fee: %s\n",
               TALER_B2S (coin_pub),
               TALER_amount2s (amount_with_fee));
   check_connection (pg);
   PREPARE (pg,
            "insert_deposit",
-           "WITH md AS"
-           "  (SELECT account_serial, merchant_serial"
-           "   FROM merchant_accounts"
-           "   WHERE h_wire=$10"
-           "    AND merchant_serial="
-           "     (SELECT merchant_serial"
-           "        FROM merchant_instances"
-           "        WHERE merchant_id=$1))"
-           ", ed AS"
-           "  (SELECT signkey_serial"
-           "   FROM merchant_exchange_signing_keys"
-           "   WHERE exchange_pub=$12"
-           "   ORDER BY start_date DESC"
-           "   LIMIT 1)"
            "INSERT INTO merchant_deposits"
-           "(order_serial"
-           ",deposit_timestamp"
+           "(deposit_confirmation_serial"
+           ",coin_offset"
            ",coin_pub"
-           ",exchange_url"
+           ",coin_sig"
            ",amount_with_fee"
            ",deposit_fee"
            ",refund_fee"
-           ",wire_fee"
-           ",exchange_sig"
-           ",signkey_serial"
-           ",account_serial)"
-           " SELECT "
-           "   order_serial"
-           "  ,$3, $4, $5, $6, $7, $8, $9, $11"
-           "  ,ed.signkey_serial"
-           "  ,md.account_serial"
-           "  FROM merchant_contract_terms"
-           "   JOIN md USING (merchant_serial)"
-           "   FULL OUTER JOIN ed ON TRUE"
-           "  WHERE h_contract_terms=$2");
+           ") VALUES ($1, $2, $3, $4, $5, $6, $7)");
   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
                                              "insert_deposit",
                                              params);
diff --git a/src/backenddb/pg_insert_deposit.h 
b/src/backenddb/pg_insert_deposit.h
index 999d9367..94af2bf4 100644
--- a/src/backenddb/pg_insert_deposit.h
+++ b/src/backenddb/pg_insert_deposit.h
@@ -29,34 +29,25 @@
  * Insert payment confirmation from the exchange into the database.
  *
  * @param cls closure
- * @param instance_id instance to lookup deposits for
- * @param deposit_timestamp time when the exchange generated the deposit 
confirmation
- * @param h_contract_terms proposal data's hashcode
+ * @param offset offset of the coin in the batch
+ * @param deposit_confirmation_serial which deposit confirmation is this coin 
part of
  * @param coin_pub public key of the coin
- * @param exchange_url URL of the exchange that issued @a coin_pub
+ * @param coin_sig signature of the coin
  * @param amount_with_fee amount the exchange will deposit for this coin
  * @param deposit_fee fee the exchange will charge for this coin
  * @param wire_fee wire fee the exchange charges
  * @param refund_fee fee the exchange charges to refund this coin
- * @param h_wire hash of the wire details of the target account of the merchant
- * @param exchange_sig signature from exchange that coin was accepted
- * @param exchange_pub signgin key that was used for @a exchange_sig
  * @return transaction status
  */
 enum GNUNET_DB_QueryStatus
-TMH_PG_insert_deposit (void *cls,
-                       const char *instance_id,
-                       struct GNUNET_TIME_Timestamp deposit_timestamp,
-                       const struct
-                       TALER_PrivateContractHashP *h_contract_terms,
-                       const struct TALER_CoinSpendPublicKeyP *coin_pub,
-                       const char *exchange_url,
-                       const struct TALER_Amount *amount_with_fee,
-                       const struct TALER_Amount *deposit_fee,
-                       const struct TALER_Amount *refund_fee,
-                       const struct TALER_Amount *wire_fee,
-                       const struct TALER_MerchantWireHashP *h_wire,
-                       const struct TALER_ExchangeSignatureP *exchange_sig,
-                       const struct TALER_ExchangePublicKeyP *exchange_pub);
+TMH_PG_insert_deposit (
+  void *cls,
+  uint32_t offset,
+  uint64_t deposit_confirmation_serial,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_CoinSpendSignatureP *coin_sig,
+  const struct TALER_Amount *amount_with_fee,
+  const struct TALER_Amount *deposit_fee,
+  const struct TALER_Amount *refund_fee);
 
 #endif
diff --git a/src/backenddb/pg_insert_transfer_details.c 
b/src/backenddb/pg_insert_transfer_details.c
index a4f69989..66859649 100644
--- a/src/backenddb/pg_insert_transfer_details.c
+++ b/src/backenddb/pg_insert_transfer_details.c
@@ -87,35 +87,47 @@ TMH_PG_insert_transfer_details (
            ",offset_in_exchange_list"
            ",exchange_deposit_value"
            ",exchange_deposit_fee) "
-           "SELECT deposit_serial, $1, $2, $3, $4"
-           " FROM merchant_deposits"
-           " JOIN merchant_contract_terms USING (order_serial)"
-           " WHERE coin_pub=$5"
-           "   AND h_contract_terms=$6"
-           "   AND merchant_serial="
+           "SELECT dep.deposit_serial, $1, $2, $3, $4"
+           " FROM merchant_deposits dep"
+           " JOIN merchant_deposit_confirmations dcon"
+           "   USING (deposit_confirmation_serial)"
+           " JOIN merchant_contract_terms cterm"
+           "   USING (order_serial)"
+           " WHERE dep.coin_pub=$5"
+           "   AND cterm.h_contract_terms=$6"
+           "   AND cterm.merchant_serial="
            "     (SELECT merchant_serial"
            "        FROM merchant_instances"
            "       WHERE merchant_id=$7)");
   PREPARE (pg,
            "update_wired_by_coin_pub",
-           "WITH os AS" /* select orders affected by the coin */
-           "(SELECT order_serial"
-           "   FROM merchant_deposits"
-           "  WHERE coin_pub=$1)"
+           "WITH affected_orders AS" /* select orders affected by the coin */
+           "(SELECT mcon.order_serial"
+           "   FROM merchant_deposits dep"
+           /* Next 2 joins ensure transfers exist in the first place */
+           "   JOIN merchant_deposit_to_transfer"
+           "     USING (deposit_serial)"
+           "   JOIN merchant_transfers mtrans"
+           "     USING (credit_serial)"
+           "   JOIN merchant_deposit_confirmations mcon"
+           "     USING (deposit_confirmation_serial)"
+           "  WHERE dep.coin_pub=$1)"
            "UPDATE merchant_contract_terms "
            " SET wired=TRUE "
            " WHERE order_serial IN "
-           "  (SELECT order_serial FROM merchant_deposits" /* only orders for 
which NO un-wired coin exists*/
+           "  (SELECT order_serial"
+           "    FROM merchant_deposit_confirmations dcon"
+           "    JOIN affected_orders"
+           "      USING (order_serial)"
            "    WHERE NOT EXISTS "
-           "    (SELECT order_serial FROM merchant_deposits" /* orders for 
which ANY un-wired coin exists */
-           "       JOIN os USING (order_serial)" /* filter early */
-           "      WHERE deposit_serial NOT IN"
-           "      (SELECT deposit_serial " /* all coins associated with order 
that WERE wired */
-           "         FROM merchant_deposits "
-           "         JOIN os USING (order_serial)" /* filter early */
-           "         JOIN merchant_deposit_to_transfer USING (deposit_serial)"
-           "         JOIN merchant_transfers USING (credit_serial)"
-           "        WHERE confirmed=TRUE)))");
+           "    (SELECT 1"
+           "       FROM merchant_deposits dep"
+           "       JOIN merchant_deposit_to_transfer"
+           "         USING (deposit_serial)"
+           "       JOIN merchant_transfers mtrans"
+           "         USING (credit_serial)"
+           "      WHERE dep.deposit_confirmation_serial = 
dcon.deposit_confirmation_serial"
+           "        AND NOT mtrans.confirmed))");
 
 RETRY:
   if (MAX_RETRIES < ++retries)
@@ -175,9 +187,9 @@ RETRY:
     struct GNUNET_PQ_QueryParam params[] = {
       GNUNET_PQ_query_param_uint64 (&credit_serial),
       TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                   &td->total_amount),
+                                                 &td->total_amount),
       TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                   &td->wire_fee),
+                                                 &td->wire_fee),
       GNUNET_PQ_query_param_timestamp (&td->execution_time),
       GNUNET_PQ_query_param_auto_from_type (&td->exchange_sig),
       GNUNET_PQ_query_param_auto_from_type (&td->exchange_pub),
@@ -219,9 +231,9 @@ RETRY:
       GNUNET_PQ_query_param_uint64 (&credit_serial),
       GNUNET_PQ_query_param_uint64 (&i64),
       TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                   &d->coin_value),
+                                                 &d->coin_value),
       TALER_PQ_query_param_amount_with_currency (pg->conn,
-                                   &d->coin_fee),       /* deposit fee */
+                                                 &d->coin_fee), /* deposit fee 
*/
       GNUNET_PQ_query_param_auto_from_type (&d->coin_pub),
       GNUNET_PQ_query_param_auto_from_type (&d->h_contract_terms),
       GNUNET_PQ_query_param_string (instance_id),
diff --git a/src/backenddb/pg_lookup_deposits.c 
b/src/backenddb/pg_lookup_deposits.c
index 242d7bbb..2440f62c 100644
--- a/src/backenddb/pg_lookup_deposits.c
+++ b/src/backenddb/pg_lookup_deposits.c
@@ -73,7 +73,6 @@ lookup_deposits_cb (void *cls,
     struct TALER_Amount amount_with_fee;
     struct TALER_Amount deposit_fee;
     struct TALER_Amount refund_fee;
-    struct TALER_Amount wire_fee;
     char *exchange_url;
     struct GNUNET_PQ_ResultSpec rs[] = {
       GNUNET_PQ_result_spec_string ("exchange_url",
@@ -86,8 +85,6 @@ lookup_deposits_cb (void *cls,
                                                  &deposit_fee),
       TALER_PQ_result_spec_amount_with_currency ("refund_fee",
                                                  &refund_fee),
-      TALER_PQ_result_spec_amount_with_currency ("wire_fee",
-                                                 &wire_fee),
       GNUNET_PQ_result_spec_end
     };
 
@@ -105,8 +102,7 @@ lookup_deposits_cb (void *cls,
              &coin_pub,
              &amount_with_fee,
              &deposit_fee,
-             &refund_fee,
-             &wire_fee);
+             &refund_fee);
     GNUNET_PQ_cleanup_result (rs);
   }
   ldc->qs = num_results;
@@ -142,14 +138,15 @@ TMH_PG_lookup_deposits (
   PREPARE (pg,
            "lookup_deposits",
            "SELECT"
-           " exchange_url"
-           ",coin_pub"
-           ",amount_with_fee"
-           ",deposit_fee"
-           ",refund_fee"
-           ",wire_fee"
-           " FROM merchant_deposits"
-           " WHERE order_serial="
+           " dcom.exchange_url"
+           ",dep.coin_pub"
+           ",dep.amount_with_fee"
+           ",dep.deposit_fee"
+           ",dep.refund_fee"
+           " FROM merchant_deposits dep"
+           " JOIN merchant_deposit_confirmations dcom"
+           "   USING (deposit_confirmation_serial)"
+           " WHERE dcom.order_serial="
            "     (SELECT order_serial"
            "        FROM merchant_contract_terms"
            "        WHERE h_contract_terms=$2"
diff --git a/src/backenddb/pg_refund_coin.c b/src/backenddb/pg_refund_coin.c
index afbcebcc..1bde2974 100644
--- a/src/backenddb/pg_refund_coin.c
+++ b/src/backenddb/pg_refund_coin.c
@@ -53,15 +53,17 @@ TMH_PG_refund_coin (void *cls,
            ",refund_amount"
            ") "
            "SELECT "
-           " order_serial"
+           " dcon.order_serial"
            ",0" /* rtransaction_id always 0 for /abort */
            ",$3"
-           ",coin_pub"
+           ",dep.coin_pub"
            ",$5"
-           ",amount_with_fee"
-           " FROM merchant_deposits"
-           " WHERE coin_pub=$4"
-           "   AND order_serial="
+           ",dep.amount_with_fee"
+           " FROM merchant_deposits dep"
+           " JOIN merchant_deposit_confirmations dcon"
+           "   USING (deposit_confirmation_serial)"
+           " WHERE dep.coin_pub=$4"
+           "   AND dcon.order_serial="
            "  (SELECT order_serial"
            "     FROM merchant_contract_terms"
            "    WHERE h_contract_terms=$2"
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index 3682e5c1..30def849 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -89,6 +89,7 @@
 #include "pg_lookup_deposits.h"
 #include "pg_insert_exchange_signkey.h"
 #include "pg_insert_deposit.h"
+#include "pg_insert_deposit_confirmation.h"
 #include "pg_lookup_refunds.h"
 #include "pg_mark_contract_paid.h"
 #include "pg_select_account_by_uri.h"
@@ -3060,52 +3061,65 @@ postgres_connect (void *cls)
     /* for postgres_lookup_deposits_by_order() */
     GNUNET_PQ_make_prepare ("lookup_deposits_by_order",
                             "SELECT"
-                            " deposit_serial"
-                            ",exchange_url"
-                            ",h_wire"
-                            ",amount_with_fee"
-                            ",deposit_fee"
-                            ",coin_pub"
-                            " FROM merchant_deposits"
-                            "  JOIN merchant_accounts USING (account_serial)"
-                            " WHERE order_serial=$1"),
+                            " dep.deposit_serial"
+                            ",mcon.exchange_url"
+                            ",acc.h_wire"
+                            ",dep.amount_with_fee"
+                            ",dep.deposit_fee"
+                            ",dep.coin_pub"
+                            " FROM merchant_deposits dep"
+                            " JOIN merchant_deposit_confirmations mcon"
+                            "   USING(deposit_confirmation_serial)"
+                            " JOIN merchant_accounts acc"
+                            "   USING (account_serial)"
+                            " WHERE mcon.order_serial=$1"),
     /* for postgres_lookup_transfer_details_by_order() */
     GNUNET_PQ_make_prepare ("lookup_transfer_details_by_order",
                             "SELECT"
                             " md.deposit_serial"
-                            ",md.exchange_url"
+                            ",mcon.exchange_url"
                             ",mt.wtid"
-                            ",exchange_deposit_value"
-                            ",exchange_deposit_fee"
-                            ",deposit_timestamp"
+                            ",mtc.exchange_deposit_value"
+                            ",mtc.exchange_deposit_fee"
+                            ",mcon.deposit_timestamp"
                             ",mt.confirmed AS transfer_confirmed"
-                            " FROM merchant_transfer_to_coin"
-                            " JOIN merchant_deposits AS md USING 
(deposit_serial)"
-                            " JOIN merchant_transfers AS mt USING 
(credit_serial)"
-                            " WHERE deposit_serial IN"
-                            "  (SELECT deposit_serial"
-                            "   FROM merchant_deposits"
-                            "   WHERE order_serial=$1)"),
+                            " FROM merchant_transfer_to_coin mtc"
+                            " JOIN merchant_deposits md"
+                            "   USING (deposit_serial)"
+                            " JOIN merchant_deposit_confirmations mcon"
+                            "   USING (deposit_confirmation_serial)"
+                            " JOIN merchant_transfers mt"
+                            "   USING (credit_serial)"
+                            " JOIN merchant_accounts acc"
+                            "   ON (acc.account_serial = mt.account_serial)"
+                            /* Check that all this is for the same instance */
+                            " JOIN merchant_contract_terms contracts"
+                            "   USING (merchant_serial, order_serial)"
+                            " WHERE mcon.order_serial=$1"),
     /* for postgres_mark_order_wired() */
     GNUNET_PQ_make_prepare ("mark_order_wired",
                             "UPDATE merchant_contract_terms SET"
-                            " wired=true"
+                            " wired=TRUE"
                             " WHERE order_serial=$1"),
     /* for postgres_lookup_refunds_detailed() */
     GNUNET_PQ_make_prepare ("lookup_refunds_detailed",
                             "SELECT"
-                            " refund_serial"
-                            ",refund_timestamp"
-                            ",coin_pub"
-                            ",merchant_deposits.exchange_url"
-                            ",rtransaction_id"
-                            ",reason"
-                            ",refund_amount"
+                            " ref.refund_serial"
+                            ",ref.refund_timestamp"
+                            ",dep.coin_pub"
+                            ",mcon.exchange_url"
+                            ",ref.rtransaction_id"
+                            ",ref.reason"
+                            ",ref.refund_amount"
                             ",merchant_refund_proofs.exchange_sig IS NULL AS 
pending"
-                            " FROM merchant_refunds"
-                            "   JOIN merchant_deposits USING (order_serial, 
coin_pub)"
-                            "   LEFT JOIN merchant_refund_proofs USING 
(refund_serial)"
-                            " WHERE order_serial="
+                            " FROM merchant_deposit_confirmations mcon"
+                            " JOIN merchant_deposits dep"
+                            "   USING (deposit_confirmation_serial)"
+                            " JOIN merchant_refunds ref"
+                            "   USING (order_serial, coin_pub)"
+                            " LEFT JOIN merchant_refund_proofs"
+                            "   USING (refund_serial)"
+                            " WHERE mcon.order_serial="
                             "  (SELECT order_serial"
                             "     FROM merchant_contract_terms"
                             "    WHERE h_contract_terms=$2"
@@ -3197,23 +3211,28 @@ postgres_connect (void *cls)
     /* for postgres_lookup_deposits_by_contract_and_coin() */
     GNUNET_PQ_make_prepare ("lookup_deposits_by_contract_and_coin",
                             "SELECT"
-                            " exchange_url"
-                            ",amount_with_fee"
-                            ",deposit_fee"
-                            ",refund_fee"
-                            ",wire_fee"
-                            ",h_wire"
-                            ",deposit_timestamp"
-                            ",refund_deadline"
-                            ",exchange_sig"
-                            ",exchange_pub"
-                            " FROM merchant_contract_terms"
-                            "  JOIN merchant_deposits USING (order_serial)"
-                            "  JOIN merchant_exchange_signing_keys USING 
(signkey_serial)"
-                            "  JOIN merchant_accounts USING (account_serial)"
+                            " mcon.exchange_url"
+                            ",dep.amount_with_fee"
+                            ",dep.deposit_fee"
+                            ",dep.refund_fee"
+                            ",mcon.wire_fee"
+                            ",acc.h_wire"
+                            ",mcon.deposit_timestamp"
+                            ",mct.refund_deadline"
+                            ",mcon.exchange_sig"
+                            ",msig.exchange_pub"
+                            " FROM merchant_contract_terms mct"
+                            "  JOIN merchant_deposit_confirmations mcon"
+                            "    USING (order_serial)"
+                            "  JOIN merchant_deposits dep"
+                            "    USING (deposit_confirmation_serial)"
+                            "  JOIN merchant_exchange_signing_keys msig"
+                            "    USING (signkey_serial)"
+                            "  JOIN merchant_accounts acc"
+                            "    USING (account_serial)"
                             " WHERE h_contract_terms=$2"
-                            "   AND coin_pub=$3"
-                            "   AND merchant_contract_terms.merchant_serial="
+                            "   AND dep.coin_pub=$3"
+                            "   AND mct.merchant_serial="
                             "     (SELECT merchant_serial"
                             "        FROM merchant_instances"
                             "       WHERE merchant_id=$1)"),
@@ -3235,29 +3254,39 @@ postgres_connect (void *cls)
     /* for postgres_lookup_transfer_summary() */
     GNUNET_PQ_make_prepare ("lookup_transfer_summary",
                             "SELECT"
-                            " order_id"
-                            ",exchange_deposit_value"
-                            ",exchange_deposit_fee"
-                            " FROM merchant_transfers"
-                            "  JOIN merchant_transfer_to_coin USING 
(credit_serial)"
-                            "  JOIN merchant_deposits USING (deposit_serial)"
-                            "  JOIN merchant_contract_terms USING 
(order_serial)"
-                            " WHERE wtid=$2"
-                            "   AND merchant_transfers.exchange_url=$1"),
+                            " mct.order_id"
+                            ",mtc.exchange_deposit_value"
+                            ",mtc.exchange_deposit_fee"
+                            " FROM merchant_transfers mtr"
+                            "  JOIN merchant_transfer_to_coin mtc"
+                            "    USING (credit_serial)"
+                            "  JOIN merchant_deposits dep"
+                            "    USING (deposit_serial)"
+                            "  JOIN merchant_deposit_confirmations mcon"
+                            "    USING (deposit_confirmation_serial)"
+                            "  JOIN merchant_contract_terms mct"
+                            "    USING (order_serial)"
+                            " WHERE mtr.wtid=$2"
+                            "   AND mtr.exchange_url=$1"),
     /* for postgres_lookup_transfer_details() */
     GNUNET_PQ_make_prepare ("lookup_transfer_details",
                             "SELECT"
-                            " merchant_contract_terms.h_contract_terms"
-                            
",merchant_transfer_to_coin.offset_in_exchange_list"
-                            ",merchant_deposits.coin_pub"
-                            ",exchange_deposit_value"
-                            ",exchange_deposit_fee"
-                            " FROM merchant_transfer_to_coin"
-                            "  JOIN merchant_deposits USING (deposit_serial)"
-                            "  JOIN merchant_contract_terms USING 
(order_serial)"
-                            "  JOIN merchant_transfers USING (credit_serial)"
-                            " WHERE merchant_transfers.wtid=$2"
-                            "   AND merchant_transfers.exchange_url=$1"),
+                            " mterm.h_contract_terms"
+                            ",mtcoin.offset_in_exchange_list"
+                            ",dep.coin_pub"
+                            ",mtcoin.exchange_deposit_value"
+                            ",mtcoin.exchange_deposit_fee"
+                            " FROM merchant_transfer_to_coin mtcoin"
+                            " JOIN merchant_deposits dep"
+                            "   USING (deposit_serial)"
+                            " JOIN merchant_deposit_confirmations mcon"
+                            "   USING (deposit_confirmation_serial)"
+                            " JOIN merchant_contract_terms mterm"
+                            "   USING (order_serial)"
+                            " JOIN merchant_transfers mtr"
+                            "   USING (credit_serial)"
+                            " WHERE mtr.wtid=$2"
+                            "   AND mtr.exchange_url=$1"),
     /* For postgres_insert_reserve() */
     GNUNET_PQ_make_prepare ("insert_reserve_key",
                             "INSERT INTO merchant_reward_reserve_keys"
@@ -3786,6 +3815,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
     = &TMH_PG_lookup_deposits;
   plugin->insert_exchange_signkey
     = &TMH_PG_insert_exchange_signkey;
+  plugin->insert_deposit_confirmation
+    = &TMH_PG_insert_deposit_confirmation;
   plugin->insert_deposit
     = &TMH_PG_insert_deposit;
   plugin->lookup_refunds
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index 4c2ef5c9..94f47f70 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -304,9 +304,6 @@ lookup_instances_cb (void *cls,
 }
 
 
-
-
-
 /**
  * Tests @e insert_instance.
  *
@@ -2358,6 +2355,11 @@ struct DepositData
    */
   struct TALER_CoinSpendPublicKeyP coin_pub;
 
+  /**
+   * Signature of the coin that has been deposited.
+   */
+  struct TALER_CoinSpendSignatureP coin_sig;
+
   /**
    * URL of the exchange.
    */
@@ -2396,39 +2398,6 @@ struct DepositData
 };
 
 
-/**
- * Private key for my_sign_cb().
- */
-static const struct TALER_ExchangePrivateKeyP *msc_exchange_priv;
-
-/**
- * Function that signs the message in @a purpose with the
- * exchange's signing key from #msc_exchange_priv.
- *
- * The @a purpose data is the beginning of the data of which the signature is
- * to be created. The `size` field in @a purpose must correctly indicate the
- * number of bytes of the data structure, including its header. *
- * @param purpose the message to sign
- * @param[out] pub set to the current public signing key of the exchange
- * @param[out] sig signature over purpose using current signing key
- * @return #TALER_EC_NONE on success
- */
-static enum TALER_ErrorCode
-my_sign_cb (
-  const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
-  struct TALER_ExchangePublicKeyP *pub,
-  struct TALER_ExchangeSignatureP *sig)
-{
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CRYPTO_eddsa_sign_ (&msc_exchange_priv->eddsa_priv,
-                                            purpose,
-                                            &sig->eddsa_signature));
-  GNUNET_CRYPTO_eddsa_key_get_public (&msc_exchange_priv->eddsa_priv,
-                                      &pub->eddsa_pub);
-  return TALER_EC_NONE;
-}
-
-
 /**
  * Generates deposit data for an order.
  *
@@ -2448,7 +2417,6 @@ make_deposit (const struct InstanceData *instance,
   struct TALER_CoinSpendPrivateKeyP coin_priv;
   struct GNUNET_TIME_Timestamp now;
   struct TALER_Amount amount_without_fee;
-  struct TALER_ExchangePublicKeyP exchange_pub;
 
   now = GNUNET_TIME_timestamp_get ();
   deposit->timestamp = now;
@@ -2476,22 +2444,12 @@ make_deposit (const struct InstanceData *instance,
                                         &deposit->amount_with_fee,
                                         &deposit->deposit_fee));
   deposit->h_wire = account->h_wire;
-  msc_exchange_priv = &signkey->exchange_priv;
-  GNUNET_assert (TALER_EC_NONE ==
-                 TALER_exchange_online_deposit_confirmation_sign (
-                   &my_sign_cb,
-                   &deposit->h_contract_terms,
-                   &deposit->h_wire,
-                   NULL,
-                   now,
-                   now,
-                   now,
-                   &amount_without_fee,
-                   &deposit->coin_pub,
-                   &instance->merchant_pub,
-                   &exchange_pub,
-                   &deposit->exchange_sig));
-  msc_exchange_priv = NULL;
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+                              &deposit->exchange_sig,
+                              sizeof (deposit->exchange_sig));
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+                              &deposit->coin_sig,
+                              sizeof (deposit->coin_sig));
 }
 
 
@@ -2534,21 +2492,38 @@ test_insert_deposit (const struct InstanceData 
*instance,
                      const struct DepositData *deposit,
                      enum GNUNET_DB_QueryStatus expected_result)
 {
-  TEST_COND_RET_ON_FAIL (expected_result ==
-                         plugin->insert_deposit (plugin->cls,
-                                                 instance->instance.id,
-                                                 deposit->timestamp,
-                                                 &deposit->h_contract_terms,
-                                                 &deposit->coin_pub,
-                                                 deposit->exchange_url,
-                                                 &deposit->amount_with_fee,
-                                                 &deposit->deposit_fee,
-                                                 &deposit->refund_fee,
-                                                 &deposit->wire_fee,
-                                                 &deposit->h_wire,
-                                                 &deposit->exchange_sig,
-                                                 &signkey->exchange_pub),
-                         "Insert deposit failed\n");
+  uint64_t row;
+  struct TALER_Amount awf;
+
+  GNUNET_assert (0 <=
+                 TALER_amount_subtract (&awf,
+                                        &deposit->amount_with_fee,
+                                        &deposit->deposit_fee));
+  TEST_COND_RET_ON_FAIL (
+    expected_result ==
+    plugin->insert_deposit_confirmation (plugin->cls,
+                                         instance->instance.id,
+                                         deposit->timestamp,
+                                         &deposit->h_contract_terms,
+                                         deposit->exchange_url,
+                                         &awf,
+                                         &deposit->wire_fee,
+                                         &deposit->h_wire,
+                                         &deposit->exchange_sig,
+                                         &signkey->exchange_pub,
+                                         &row),
+    "Insert deposit confirmation failed\n");
+  TEST_COND_RET_ON_FAIL (
+    expected_result ==
+    plugin->insert_deposit (plugin->cls,
+                            0,
+                            row,
+                            &deposit->coin_pub,
+                            &deposit->coin_sig,
+                            &deposit->amount_with_fee,
+                            &deposit->deposit_fee,
+                            &deposit->refund_fee),
+    "Insert deposit failed\n");
   return 0;
 }
 
@@ -2588,7 +2563,6 @@ struct TestLookupDeposits_Closure
  * @param amount_with_fee amount of the deposit with fees.
  * @param deposit_fee fee charged for the deposit.
  * @param refund_fee fee charged in case of a refund.
- * @param wire_fee fee charged when the money is wired.
  */
 static void
 lookup_deposits_cb (void *cls,
@@ -2596,8 +2570,7 @@ lookup_deposits_cb (void *cls,
                     const struct TALER_CoinSpendPublicKeyP *coin_pub,
                     const struct TALER_Amount *amount_with_fee,
                     const struct TALER_Amount *deposit_fee,
-                    const struct TALER_Amount *refund_fee,
-                    const struct TALER_Amount *wire_fee)
+                    const struct TALER_Amount *refund_fee)
 {
   struct TestLookupDeposits_Closure *cmp = cls;
   if (NULL == cmp)
@@ -2625,14 +2598,7 @@ lookup_deposits_cb (void *cls,
            refund_fee)) &&
         (0 ==
          TALER_amount_cmp (&cmp->deposits_to_cmp[i].refund_fee,
-                           refund_fee)) &&
-        (GNUNET_OK ==
-         TALER_amount_cmp_currency (
-           &cmp->deposits_to_cmp[i].wire_fee,
-           wire_fee)) &&
-        (0 ==
-         TALER_amount_cmp (&cmp->deposits_to_cmp[i].wire_fee,
-                           wire_fee)))
+                           refund_fee)))
     {
       cmp->results_matching[i] += 1;
     }
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index fb05bf1c..fd29edba 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -370,7 +370,7 @@ struct TALER_MERCHANTDB_TemplateDetails
    * In this template contract, we can have additional information.
    */
   json_t *template_contract;
-  
+
   /**
    * ID of the OTP device linked to the template, or NULL.
    */
@@ -606,7 +606,6 @@ typedef void
  * @param amount_with_fee amount the exchange will deposit for this coin
  * @param deposit_fee fee the exchange will charge for this coin
  * @param refund_fee fee the exchange will charge for refunding this coin
- * @param wire_fee wire fee the exchange charges
  */
 typedef void
 (*TALER_MERCHANTDB_DepositsCallback)(
@@ -615,8 +614,7 @@ typedef void
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   const struct TALER_Amount *amount_with_fee,
   const struct TALER_Amount *deposit_fee,
-  const struct TALER_Amount *refund_fee,
-  const struct TALER_Amount *wire_fee);
+  const struct TALER_Amount *refund_fee);
 
 
 /**
@@ -1348,7 +1346,7 @@ struct TALER_MERCHANTDB_Plugin
     const struct TALER_MerchantWireHashP *h_wire,
     const char *credit_facade_url,
     const json_t *credit_facade_credentials);
-  
+
 
   /**
    * Obtain information about an instance's accounts.
@@ -1384,15 +1382,15 @@ struct TALER_MERCHANTDB_Plugin
     struct TALER_MERCHANTDB_AccountDetails *ad);
 
 
-    /**
-   * Obtain detailed information about an instance's account.
-   *
-   * @param cls closure
-   * @param id identifier of the instance
-   * @param payto_uri URI of the account
-   * @param[out] ad account details returned
-   * @return database result code
-   */
+  /**
+ * Obtain detailed information about an instance's account.
+ *
+ * @param cls closure
+ * @param id identifier of the instance
+ * @param payto_uri URI of the account
+ * @param[out] ad account details returned
+ * @return database result code
+ */
   enum GNUNET_DB_QueryStatus
   (*select_account_by_uri)(
     void *cls,
@@ -1944,36 +1942,60 @@ struct TALER_MERCHANTDB_Plugin
 
 
   /**
-   * Insert payment confirmation from the exchange into the database.
+   * Insert deposit confirmation from the exchange into the database.
    *
    * @param cls closure
    * @param instance_id instance to lookup deposits for
    * @param deposit_timestamp time when the exchange generated the deposit 
confirmation
    * @param h_contract_terms proposal data's hashcode
-   * @param coin_pub public key of the coin
    * @param exchange_url URL of the exchange that issued @a coin_pub
-   * @param amount_with_fee amount the exchange will deposit for this coin
-   * @param deposit_fee fee the exchange will charge for this coin
+   * @param total_without_fees deposited total in the batch without fees
    * @param wire_fee wire fee the exchange charges
    * @param h_wire hash of the wire details of the target account of the 
merchant
    * @param exchange_sig signature from exchange that coin was accepted
    * @param exchange_pub signing key that was used for @a exchange_sig
+   * @param[out] batch_deposit_serial_id set to the table row
    * @return transaction status
    */
   enum GNUNET_DB_QueryStatus
-  (*insert_deposit)(void *cls,
-                    const char *instance_id,
-                    struct GNUNET_TIME_Timestamp deposit_timestamp,
-                    const struct TALER_PrivateContractHashP *h_contract_terms,
-                    const struct TALER_CoinSpendPublicKeyP *coin_pub,
-                    const char *exchange_url,
-                    const struct TALER_Amount *amount_with_fee,
-                    const struct TALER_Amount *deposit_fee,
-                    const struct TALER_Amount *refund_fee,
-                    const struct TALER_Amount *wire_fee,
-                    const struct TALER_MerchantWireHashP *h_wire,
-                    const struct TALER_ExchangeSignatureP *exchange_sig,
-                    const struct TALER_ExchangePublicKeyP *exchange_pub);
+  (*insert_deposit_confirmation)(
+    void *cls,
+    const char *instance_id,
+    struct GNUNET_TIME_Timestamp deposit_timestamp,
+    const struct TALER_PrivateContractHashP *h_contract_terms,
+    const char *exchange_url,
+    const struct TALER_Amount *total_without_fees,
+    const struct TALER_Amount *wire_fee,
+    const struct TALER_MerchantWireHashP *h_wire,
+    const struct TALER_ExchangeSignatureP *exchange_sig,
+    const struct TALER_ExchangePublicKeyP *exchange_pub,
+    uint64_t *batch_deposit_serial_id);
+
+
+  /**
+   * Insert information about coin deposited as part of
+   * a batch into the database.
+   *
+   * @param cls closure
+   * @param offset offset of the coin in the batch
+   * @param deposit_confirmation_serial_id deposit confirmation for the batch 
the coin is part of
+   * @param coin_pub public key of the coin
+   * @param coin_sig deposit signature of the coin
+   * @param amount_with_fee amount the exchange will deposit for this coin
+   * @param deposit_fee fee the exchange will charge for this coin
+   * @param refund_fee fee the exchange will charge for refunds of coin
+   * @return transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_deposit)(
+    void *cls,
+    uint32_t offset,
+    uint64_t deposit_confirmation_serial_id,
+    const struct TALER_CoinSpendPublicKeyP *coin_pub,
+    const struct TALER_CoinSpendSignatureP *coin_sig,
+    const struct TALER_Amount *amount_with_fee,
+    const struct TALER_Amount *deposit_fee,
+    const struct TALER_Amount *refund_fee);
 
 
   /**
@@ -3057,9 +3079,9 @@ struct TALER_MERCHANTDB_Plugin
    *           if template unknown.
    */
   enum GNUNET_DB_QueryStatus
-  (*delete_otp) (void *cls,
-                 const char *instance_id,
-                 const char *otp_id);
+  (*delete_otp)(void *cls,
+                const char *instance_id,
+                const char *otp_id);
 
   /**
    * Insert details about a particular OTP device.
@@ -3071,10 +3093,10 @@ struct TALER_MERCHANTDB_Plugin
    * @return database result code
    */
   enum GNUNET_DB_QueryStatus
-  (*insert_otp) (void *cls,
-                 const char *instance_id,
-                 const char *otp_id,
-                 const struct TALER_MERCHANTDB_OtpDeviceDetails *td);
+  (*insert_otp)(void *cls,
+                const char *instance_id,
+                const char *otp_id,
+                const struct TALER_MERCHANTDB_OtpDeviceDetails *td);
 
 
   /**
@@ -3089,10 +3111,10 @@ struct TALER_MERCHANTDB_Plugin
    *         does not yet exist.
    */
   enum GNUNET_DB_QueryStatus
-  (*update_otp) (void *cls,
-                 const char *instance_id,
-                 const char *otp_id,
-                 const struct TALER_MERCHANTDB_OtpDeviceDetails *td);
+  (*update_otp)(void *cls,
+                const char *instance_id,
+                const char *otp_id,
+                const struct TALER_MERCHANTDB_OtpDeviceDetails *td);
 
   /**
    * Lookup all of the OTP devices the given instance has configured.
@@ -3104,10 +3126,10 @@ struct TALER_MERCHANTDB_Plugin
    * @return database result code
    */
   enum GNUNET_DB_QueryStatus
-  (*lookup_otp_devices) (void *cls,
-                         const char *instance_id,
-                         TALER_MERCHANTDB_OtpDeviceCallback cb,
-                         void *cb_cls);
+  (*lookup_otp_devices)(void *cls,
+                        const char *instance_id,
+                        TALER_MERCHANTDB_OtpDeviceCallback cb,
+                        void *cb_cls);
 
 
   /**
@@ -3121,10 +3143,10 @@ struct TALER_MERCHANTDB_Plugin
    * @return database result code
    */
   enum GNUNET_DB_QueryStatus
-  (*select_otp) (void *cls,
-                 const char *instance_id,
-                 const char *otp_id,
-                 struct TALER_MERCHANTDB_OtpDeviceDetails *td);
+  (*select_otp)(void *cls,
+                const char *instance_id,
+                const char *otp_id,
+                struct TALER_MERCHANTDB_OtpDeviceDetails *td);
 
 
   /**
@@ -3136,12 +3158,12 @@ struct TALER_MERCHANTDB_Plugin
    * @param[out] serial set to the OTP device serial number   * @return 
database result code
    */
   enum GNUNET_DB_QueryStatus
-  (*select_otp_serial) (void *cls,
-                        const char *instance_id,
-                        const char *otp_id,
-                        uint64_t *serial);
+  (*select_otp_serial)(void *cls,
+                       const char *instance_id,
+                       const char *otp_id,
+                       uint64_t *serial);
+
 
-  
   /**
    * Update details about a particular template.
    *
diff --git a/src/testing/test_merchant_transfer_tracking.sh 
b/src/testing/test_merchant_transfer_tracking.sh
index dfd5f5d2..0e999f25 100755
--- a/src/testing/test_merchant_transfer_tracking.sh
+++ b/src/testing/test_merchant_transfer_tracking.sh
@@ -245,10 +245,6 @@ taler-exchange-aggregator -y -c $CONF -T ${TO_SLEEP}000000 
-t -L INFO &> aggrega
 taler-exchange-transfer -c $CONF -t -L INFO &> transfer.log
 echo " DONE"
 
-echo -n "waiting for Nexus and Sandbox to settle the payment .."
-sleep 3
-echo " DONE"
-
 echo -n "Obtaining wire transfer details from bank..."
 
 if [ 1 = "$USE_FAKEBANK" ]
@@ -260,6 +256,9 @@ then
     TARGET_PAYTO=$(echo "$BANKDATA" | jq -r 
.outgoing_transactions[0].credit_account)
     TARGET=$(echo "$TARGET_PAYTO" | awk -F = '{print $2}')
 else
+    echo -n "waiting for Nexus and Sandbox to settle the payment .."
+    sleep 3
+    echo " DONE"
     # Emulating the previous pybank-based logic of getting
     # the wire transfer information _via the exchange_ bank
     # account.  NOTE: grabbing tx == 0, since the latest

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