gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 95/277: db work for POST /transfers


From: gnunet
Subject: [taler-merchant] 95/277: db work for POST /transfers
Date: Sun, 05 Jul 2020 20:50:08 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit 02faacad3cd56e3266be625980920e420f61250f
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed May 6 21:41:59 2020 +0200

    db work for POST /transfers
---
 .../taler-merchant-httpd_private-post-transfers.c  |  18 ++
 src/backenddb/merchant-0001.sql                    |   2 -
 src/backenddb/plugin_merchantdb_postgres.c         | 255 ++++++++++++++++++++-
 src/include/taler_merchantdb_plugin.h              |  22 +-
 4 files changed, 284 insertions(+), 13 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_private-post-transfers.c 
b/src/backend/taler-merchant-httpd_private-post-transfers.c
index 2f22d05..5c3a0e3 100644
--- a/src/backend/taler-merchant-httpd_private-post-transfers.c
+++ b/src/backend/taler-merchant-httpd_private-post-transfers.c
@@ -1013,6 +1013,7 @@ TMH_private_post_transfers (const struct 
TMH_RequestHandler *rh,
   /* reply not in database, ensure the POST is in the database, and
      start work to obtain the reply from the exchange */
   qs = TMH_db->insert_transfer (TMH_db->cls,
+                                rctx->hc->instance->settings.id,
                                 rctx->exchange_url,
                                 &rctx->wtid,
                                 &rctx->amount,
@@ -1029,6 +1030,23 @@ TMH_private_post_transfers (const struct 
TMH_RequestHandler *rh,
                                        TALER_EC_POST_TRANSFER_DB_STORE_ERROR,
                                        "Fail to update database with transfer 
record");
   }
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+  {
+    uint64_t account_serial;
+
+    /* Either the record already exists (we should ignore this), or
+       the INSERT failed because we did not find the account based on
+       the given payto-URI and the instance. */
+    qs = TMH_db->lookup_account (TMH_db->cls,
+                                 rctx->hc->instance->settings.id,
+                                 rctx->payto_uri,
+                                 &account_serial);
+    if (0 >= qs)
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_NOT_FOUND,
+                                         
TALER_EC_POST_TRANSFER_ACCOUNT_NOT_FOUND,
+                                         "Instance does not have this bank 
account");
+  }
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Suspending POST /private/transfers handling while working with 
exchange\n");
diff --git a/src/backenddb/merchant-0001.sql b/src/backenddb/merchant-0001.sql
index 3feb347..55cef42 100644
--- a/src/backenddb/merchant-0001.sql
+++ b/src/backenddb/merchant-0001.sql
@@ -368,8 +368,6 @@ COMMENT ON COLUMN merchant_transfers.confirmed
 CREATE TABLE IF NOT EXISTS merchant_transfer_signatures
   (credit_serial BIGINT PRIMARY KEY
      REFERENCES merchant_transfers (credit_serial) ON DELETE CASCADE
-  ,account_serial BIGINT NOT NULL
-     REFERENCES merchant_accounts (account_serial) ON DELETE CASCADE
   ,signkey_serial BIGINT NOT NULL
      REFERENCES merchant_exchange_signing_keys (signkey_serial) ON DELETE 
CASCADE
   ,execution_time INT8 NOT NULL
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index e6bc530..acb32e9 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -2696,6 +2696,7 @@ postgres_lookup_order_by_fulfillment (void *cls,
  * Insert information about a wire transfer the merchant has received.
  *
  * @param cls closure
+ * @param instance_id the instance that received the transfer
  * @param exchange_url which exchange made the transfer
  * @param wtid identifier of the wire transfer
  * @param credit_amount how much did we receive
@@ -2707,12 +2708,64 @@ postgres_lookup_order_by_fulfillment (void *cls,
 static enum GNUNET_DB_QueryStatus
 postgres_insert_transfer (
   void *cls,
+  const char *instance_id,
   const char *exchange_url,
   const struct TALER_WireTransferIdentifierRawP *wtid,
   const struct TALER_Amount *credit_amount,
   const char *payto_uri,
   bool confirmed)
 {
+  struct PostgresClosure *pg = cls;
+  uint8_t confirmed8 = confirmed;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (exchange_url),
+    GNUNET_PQ_query_param_auto_from_type (wtid),
+    TALER_PQ_query_param_amount (credit_amount),
+    GNUNET_PQ_query_param_string (payto_uri),
+    GNUNET_PQ_query_param_auto_from_type (&confirmed8),
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_end
+  };
+
+  check_connection (pg);
+  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "insert_transfer",
+                                             params);
+}
+
+
+/**
+ * Lookup account serial by payto URI.
+ *
+ * @param cls closure
+ * @param instance_id instance to lookup the account from
+ * @param payto_uri what is the merchant's bank account to lookup
+ * @param[out] account_serial serial number of the account
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_lookup_account (void *cls,
+                         const char *instance_id,
+                         const char *payto_uri,
+                         uint64_t *account_serial)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_string (payto_uri),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_uint64 ("account_serial",
+                                  account_serial),
+    GNUNET_PQ_result_spec_end
+  };
+
+  check_connection (pg);
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "lookup_account",
+                                                   params,
+                                                   rs);
 }
 
 
@@ -2720,6 +2773,7 @@ postgres_insert_transfer (
  * Insert information about a wire transfer the merchant has received.
  *
  * @param cls closure
+ * @param instance_id instance to provide transfer details for
  * @param exchange_url which exchange made the transfer
  * @param payto_uri what is the merchant's bank account that received the 
transfer
  * @param wtid identifier of the wire transfer
@@ -2729,11 +2783,123 @@ postgres_insert_transfer (
 static enum GNUNET_DB_QueryStatus
 postgres_insert_transfer_details (
   void *cls,
-  const char *exchange_url,   // FIXME: do we need the URL? We have 
exchange_pub!
+  const char *instance_id,
+  const char *exchange_url,
   const char *payto_uri,
   const struct TALER_WireTransferIdentifierRawP *wtid,
   const struct TALER_EXCHANGE_TransferData *td)
 {
+  struct PostgresClosure *pg = cls;
+  enum GNUNET_DB_QueryStatus qs;
+  uint64_t credit_serial;
+  unsigned int retries;
+
+  retries = 0;
+  check_connection (pg);
+RETRY:
+  if (MAX_RETRIES < ++retries)
+    return GNUNET_DB_STATUS_SOFT_ERROR;
+  if (GNUNET_OK !=
+      postgres_start (pg,
+                      "insert transfer details"))
+  {
+    GNUNET_break (0);
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  }
+
+  /* lookup credit serial */
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_string (exchange_url),
+      GNUNET_PQ_query_param_string (payto_uri),
+      GNUNET_PQ_query_param_string (instance_id),
+      GNUNET_PQ_query_param_auto_from_type (wtid),
+      TALER_PQ_query_param_amount (&td->total_amount),
+      GNUNET_PQ_query_param_end
+    };
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_uint64 ("credit_serial",
+                                    &credit_serial),
+      GNUNET_PQ_result_spec_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "lookup_credit_serial",
+                                                   params,
+                                                   rs);
+    if (0 > qs)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      postgres_rollback (pg);
+      if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+        goto RETRY;
+      return qs;
+    }
+    if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+    {
+      /* account does not exists, fail! */
+      postgres_rollback (pg);
+      return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+    }
+  }
+
+  /* update merchant_transfer_signatures table */
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_uint64 (&credit_serial),
+      GNUNET_PQ_query_param_absolute_time (&td->execution_time),
+      GNUNET_PQ_query_param_auto_from_type (&td->exchange_sig),
+      GNUNET_PQ_query_param_auto_from_type (&td->exchange_pub),
+      GNUNET_PQ_query_param_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "insert_transfer_signature",
+                                             params);
+    if (0 > qs)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      postgres_rollback (pg);
+      if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+        goto RETRY;
+      return qs;
+    }
+  }
+
+  /* Update transfer-coin association table */
+  for (unsigned int i = 0; i<td->details_length; i++)
+  {
+    const struct TALER_TrackTransferDetails *d = &td->details[i];
+    uint32_t i32 = (uint32_t) i;
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_uint64 (&credit_serial),
+      GNUNET_PQ_query_param_uint32 (&i32),
+      TALER_PQ_query_param_amount (&d->coin_value),
+      TALER_PQ_query_param_amount (&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_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "insert_transfer_to_coin_mapping",
+                                             params);
+    if (0 > qs)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      postgres_rollback (pg);
+      if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+        goto RETRY;
+      return qs;
+    }
+  }
+  qs = postgres_commit (pg);
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+    return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+  GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+  if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+    goto RETRY;
+  return qs;
 }
 
 
@@ -5604,17 +5770,86 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
                             "           FROM merchant_instances"
                             "          WHERE merchant_id=$1)",
                             3),
-
+    /* for postgres_insert_transfer() */
+    GNUNET_PQ_make_prepare ("insert_transfer",
+                            "INSERT INTO merchant_transfers"
+                            "(exchange_url"
+                            ",wtid"
+                            ",credit_amount_val"
+                            ",credit_amount_frac"
+                            ",account_serial"
+                            ",confirmed)"
+                            "SELECT"
+                            " $1, $2, $3, $4, account_serial, $6"
+                            " FROM merchant_accounts"
+                            " WHERE payto_uri=$5"
+                            "   AND merchant_serial="
+                            "        (SELECT merchant_serial"
+                            "           FROM merchant_instances"
+                            "          WHERE merchant_id=$7)",
+                            7),
+    /* for postgres_lookup_account() */
+    GNUNET_PQ_make_prepare ("lookup_account",
+                            "SELECT"
+                            " account_serial"
+                            " FROM merchant_accounts"
+                            " WHERE payto_uri=$2"
+                            "   AND merchant_serial="
+                            "        (SELECT merchant_serial"
+                            "           FROM merchant_instances"
+                            "          WHERE merchant_id=$1)",
+                            2),
+    /* for postgres_insert_transfer_details() */
+    GNUNET_PQ_make_prepare ("lookup_credit_serial",
+                            "SELECT"
+                            " credit_serial"
+                            " FROM merchant_transfers"
+                            " WHERE exchange_url=$1"
+                            "   AND wtid=$4"
+                            "   AND credit_account_val=$5"
+                            "   AND credit_account_frac=$6"
+                            "   AND account_serial="
+                            "        (SELECT account_serial"
+                            "           FROM merchant_accounts"
+                            "          WHERE payto_uri=$2"
+                            "            AND exchange_url=$1"
+                            "            AND merchant_serial="
+                            "            (SELECT merchant_serial"
+                            "               FROM merchant_instances"
+                            "              WHERE merchant_id=$3))",
+                            2),
+    /* for postgres_insert_transfer_details() */
+    GNUNET_PQ_make_prepare ("insert_transfer_signature",
+                            "INSERT INTO merchant_transfer_signatures"
+                            "(credit_serial"
+                            ",signkey_serial"
+                            ",execution_time"
+                            ",exchange_sig) "
+                            "SELECT $1, signkey_serial, $2, $3"
+                            " FROM merchant_exchange_signing_keys"
+                            " WHERE exchange_pub=$4"
+                            "  ORDER BY start_date DESC"
+                            "  LIMIT 1",
+                            4),
+    /* for postgres_insert_transfer_details() */
+    GNUNET_PQ_make_prepare ("insert_transfer_to_coin_mapping",
+                            "INSERT INTO merchant_transfer_to_coin"
+                            "(deposit_serial"
+                            ",credit_serial"
+                            ",offset_in_exchange_list"
+                            ",exchange_deposit_value_val"
+                            ",exchange_deposit_value_frac"
+                            ",exchange_deposit_fee_val"
+                            ",exchange_deposit_fee_frac) "
+                            "SELECT deposit_serial, $1, $2, $3, $4, $5, $6"
+                            " FROM merchant_deposits"
+                            " JOIN merchant_contract_terms USING 
(order_serial)"
+                            " WHERE coin_pub=$7"
+                            "   AND h_contract_terms=$8",
+                            8),
     /* OLD API: */
 
 #if 0
-    GNUNET_PQ_make_prepare ("insert_transfer",
-                            "INSERT INTO merchant_transfers"
-                            "(h_contract_terms"
-                            ",coin_pub"
-                            ",wtid) VALUES "
-                            "($1, $2, $3)",
-                            3),
     GNUNET_PQ_make_prepare ("insert_contract_terms",
                             "INSERT INTO merchant_contract_terms"
                             "(order_id"
@@ -5942,8 +6177,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
   plugin->insert_refund_proof = &postgres_insert_refund_proof;
   plugin->lookup_refund_proof = &postgres_lookup_refund_proof;
   plugin->lookup_order_by_fulfillment = &postgres_lookup_order_by_fulfillment;
-  /* WIP: */
   plugin->insert_transfer = &postgres_insert_transfer;
+  plugin->lookup_account = &postgres_lookup_account;
   plugin->insert_transfer_details = &postgres_insert_transfer_details;
   plugin->lookup_wire_fee = &postgres_lookup_wire_fee;
 
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index e0f7699..94fe618 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -1199,6 +1199,7 @@ struct TALER_MERCHANTDB_Plugin
    * Insert information about a wire transfer the merchant has received.
    *
    * @param cls closure
+   * @param instance_id instance to lookup the order from
    * @param exchange_url which exchange made the transfer
    * @param wtid identifier of the wire transfer
    * @param credit_amount how much did we receive
@@ -1210,6 +1211,7 @@ struct TALER_MERCHANTDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_transfer)(
     void *cls,
+    const char *instance_id,
     const char *exchange_url,
     const struct TALER_WireTransferIdentifierRawP *wtid,
     const struct TALER_Amount *credit_amount,
@@ -1217,10 +1219,27 @@ struct TALER_MERCHANTDB_Plugin
     bool confirmed);
 
 
+  /**
+   * Lookup account serial by payto URI.
+   *
+   * @param cls closure
+   * @param instance_id instance to lookup the account from
+   * @param payto_uri what is the merchant's bank account to lookup
+   * @param[out] account_serial serial number of the account
+   * @return transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*lookup_account)(void *cls,
+                    const char *instance_id,
+                    const char *payto_uri,
+                    uint64_t *account_serial);
+
+
   /**
    * Insert information about a wire transfer the merchant has received.
    *
    * @param cls closure
+   * @param instance_id instance to provide transfer details for
    * @param exchange_url which exchange made the transfer
    * @param payto_uri what is the merchant's bank account that received the 
transfer
    * @param wtid identifier of the wire transfer
@@ -1230,7 +1249,8 @@ struct TALER_MERCHANTDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*insert_transfer_details)(
     void *cls,
-    const char *exchange_url, // FIXME: do we need the URL? We have 
exchange_pub!
+    const char *instance_id,
+    const char *exchange_url,
     const char *payto_uri,
     const struct TALER_WireTransferIdentifierRawP *wtid,
     const struct TALER_EXCHANGE_TransferData *td);

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