gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] 02/02: Added appropriate response on contract-conflict


From: gnunet
Subject: [taler-exchange] 02/02: Added appropriate response on contract-conflict during deposit
Date: Sat, 23 Dec 2023 23:36:18 +0100

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

oec pushed a commit to branch master
in repository exchange.

commit 234b0cd56f69305f27ac5f6cd3828c0d115dcd0f
Author: Özgür Kesim <oec-taler@kesim.org>
AuthorDate: Sat Dec 23 23:33:22 2023 +0100

    Added appropriate response on contract-conflict during deposit
    
    In case of a detected conflict during deposit, because
    (merchant_pub, h_contract_terms) already existed, with different other
    field values, we now provide the client an error response that contains
    the h_wire.  This way, the client can retrieve further details about the
    conflicting transaction via
    /deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB
    
    Fixes #8002
---
 src/exchange/taler-exchange-httpd_batch-deposit.c | 24 +++++--
 src/exchange/taler-exchange-httpd_responses.c     | 15 +++++
 src/exchange/taler-exchange-httpd_responses.h     | 17 +++++
 src/exchangedb/Makefile.am                        |  1 +
 src/exchangedb/exchange_do_deposit.sql            |  1 -
 src/exchangedb/pg_do_deposit.c                    |  1 -
 src/exchangedb/pg_get_wire_hash_for_contract.c    | 81 +++++++++++++++++++++++
 src/exchangedb/pg_get_wire_hash_for_contract.h    | 46 +++++++++++++
 src/exchangedb/plugin_exchangedb_postgres.c       |  3 +
 src/include/taler_exchangedb_plugin.h             | 19 ++++++
 10 files changed, 202 insertions(+), 6 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c 
b/src/exchange/taler-exchange-httpd_batch-deposit.c
index 835a974f..84f27dd9 100644
--- a/src/exchange/taler-exchange-httpd_batch-deposit.c
+++ b/src/exchange/taler-exchange-httpd_batch-deposit.c
@@ -250,13 +250,29 @@ batch_deposit_transaction (void *cls,
               in_conflict ? "in conflict" : "no conflict");
   if (in_conflict)
   {
-    /* FIXME: #8002 conflicting contract != insufficient funds */
+    struct TALER_MerchantWireHashP h_wire;
+
+    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
+        TEH_plugin->get_wire_hash_for_contract (
+          TEH_plugin->cls,
+          &bd->merchant_pub,
+          &bd->h_contract_terms,
+          &h_wire))
+    {
+      TALER_LOG_WARNING (
+        "Failed to retrieve conflicting contract details from database\n");
+      *mhd_ret = TALER_MHD_reply_with_error (connection,
+                                             MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                             TALER_EC_GENERIC_DB_STORE_FAILED,
+                                             "batch-deposit");
+      return qs;
+    }
+
     *mhd_ret
-      = TEH_RESPONSE_reply_coin_insufficient_funds (
+      = TEH_RESPONSE_reply_coin_conflicting_contract (
           connection,
           TALER_EC_EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT,
-          &bd->cdis[0 /* SEE FIXME-#8002 Oec above! */].coin.denom_pub_hash,
-          &bd->cdis[0 /* SEE FIXME-#8002 Oec above! */].coin.coin_pub);
+          &h_wire);
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   if (! balance_ok)
diff --git a/src/exchange/taler-exchange-httpd_responses.c 
b/src/exchange/taler-exchange-httpd_responses.c
index a6d2c7ff..8993ea50 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -179,6 +179,21 @@ TEH_RESPONSE_reply_coin_insufficient_funds (
 }
 
 
+MHD_RESULT
+TEH_RESPONSE_reply_coin_conflicting_contract (
+  struct MHD_Connection *connection,
+  enum TALER_ErrorCode ec,
+  const struct TALER_MerchantWireHashP *h_wire)
+{
+  return TALER_MHD_REPLY_JSON_PACK (
+    connection,
+    TALER_ErrorCode_get_http_status_safe (ec),
+    GNUNET_JSON_pack_data_auto ("h_wire",
+                                h_wire),
+    TALER_JSON_pack_ec (ec));
+}
+
+
 MHD_RESULT
 TEH_RESPONSE_reply_coin_denomination_conflict (
   struct MHD_Connection *connection,
diff --git a/src/exchange/taler-exchange-httpd_responses.h 
b/src/exchange/taler-exchange-httpd_responses.h
index 57aeefe4..24b24621 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -182,6 +182,23 @@ TEH_RESPONSE_reply_coin_denomination_conflict (
   const struct TALER_DenominationPublicKey *prev_denom_pub,
   const struct TALER_DenominationSignature *prev_denom_sig);
 
+/**
+ * Send the salted hash of the merchant's bank account from conflicting
+ * contract.  With this information, the merchant's private key and
+ * the hash of the contract terms, the client can retrieve more details
+ * about the conflicting deposit
+ *
+ * @param connection connection to the client
+ * @param ec error code to return
+ * @param h_wire the salted hash of the merchant's bank account
+ * @return MHD result code
+ */
+MHD_RESULT
+TEH_RESPONSE_reply_coin_conflicting_contract (
+  struct MHD_Connection *connection,
+  enum TALER_ErrorCode ec,
+  const struct TALER_MerchantWireHashP *h_wire);
+
 /**
  * Send proof that a request is invalid to client because of
  * a conflicting value for the age commitment hash of a coin.
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index 847f2d88..89e6d9c9 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -117,6 +117,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
   pg_get_policy_details.h pg_get_policy_details.c \
   pg_persist_policy_details.h pg_persist_policy_details.c \
   pg_do_deposit.h pg_do_deposit.c \
+  pg_get_wire_hash_for_contract.h pg_get_wire_hash_for_contract.c \
   pg_add_policy_fulfillment_proof.h pg_add_policy_fulfillment_proof.c \
   pg_do_melt.h pg_do_melt.c \
   pg_do_refund.h pg_do_refund.c \
diff --git a/src/exchangedb/exchange_do_deposit.sql 
b/src/exchangedb/exchange_do_deposit.sql
index 7116117f..1156c7de 100644
--- a/src/exchangedb/exchange_do_deposit.sql
+++ b/src/exchangedb/exchange_do_deposit.sql
@@ -142,7 +142,6 @@ THEN
   IF NOT FOUND
   THEN
     -- Deposit exists, but with *strange* differences. Not allowed.
-    -- FIXME #8002:  Surely we need to provide the client more data in this 
case.
     out_conflict=TRUE;
     RETURN;
   END IF;
diff --git a/src/exchangedb/pg_do_deposit.c b/src/exchangedb/pg_do_deposit.c
index 64e7886a..0ba45b62 100644
--- a/src/exchangedb/pg_do_deposit.c
+++ b/src/exchangedb/pg_do_deposit.c
@@ -83,7 +83,6 @@ TEH_PG_do_deposit (
       GNUNET_PQ_result_spec_uint32 ("insufficient_balance_coin_index",
                                     bad_balance_index),
       balance_ok),
-    /* FIXME #8002:  We need more data to communicate the conflict to the 
client */
     GNUNET_PQ_result_spec_bool ("conflicted",
                                 ctr_conflict),
     GNUNET_PQ_result_spec_end
diff --git a/src/exchangedb/pg_get_wire_hash_for_contract.c 
b/src/exchangedb/pg_get_wire_hash_for_contract.c
new file mode 100644
index 00000000..5ff092a6
--- /dev/null
+++ b/src/exchangedb/pg_get_wire_hash_for_contract.c
@@ -0,0 +1,81 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2023 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file exchangedb/pg_get_wire_hash_for_contract.c
+ * @brief Implementation of the get_wire_hash_for_contract function for 
Postgres
+ * @author Özgür Kesim
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_exchangedb_plugin.h"
+#include "taler_pq_lib.h"
+#include "pg_get_wire_hash_for_contract.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_get_wire_hash_for_contract (
+  void *cls,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  struct TALER_MerchantWireHashP *h_wire)
+{
+  struct PostgresClosure *pg = cls;
+  enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (merchant_pub),
+    GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+    GNUNET_PQ_query_param_end
+  };
+  char *payto_uri;
+  struct TALER_WireSaltP wire_salt;
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
+                                          &wire_salt),
+    GNUNET_PQ_result_spec_string ("payto_uri",
+                                  &payto_uri),
+    GNUNET_PQ_result_spec_end
+  };
+
+  /* check if the necessary records exist and get them */
+  PREPARE (pg,
+           "get_wire_hash_for_contract",
+           "SELECT"
+           "bdep.wire_salt"
+           ",wt.payto_uri"
+           " FROM coin_deposits"
+           "    JOIN batch_deposits bdep"
+           "      USING (batch_deposit_serial_id)"
+           "    JOIN wire_targets wt"
+           "      USING (wire_target_h_payto)"
+           " WHERE bdep.merchant_pub=$1"
+           "   AND bdep.h_contract_terms=$2");
+  /* NOTE: above query might be more efficient if we computed the shard
+     from the merchant_pub and included that in the query */
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                 "get_wire_hash_for_contract",
+                                                 params,
+                                                 rs);
+  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+  {
+    TALER_merchant_wire_signature_hash (payto_uri,
+                                        &wire_salt,
+                                        h_wire);
+    GNUNET_PQ_cleanup_result (rs);
+  }
+  return qs;
+}
diff --git a/src/exchangedb/pg_get_wire_hash_for_contract.h 
b/src/exchangedb/pg_get_wire_hash_for_contract.h
new file mode 100644
index 00000000..f95cd29c
--- /dev/null
+++ b/src/exchangedb/pg_get_wire_hash_for_contract.h
@@ -0,0 +1,46 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file exchangedb/pg_get_wire_hash_for_contract.h
+ * @brief implementation of the get_wire_hash_for_contract function for 
Postgres
+ * @author Özgür Kesim
+ */
+#ifndef PG_GET_WIRE_HASH_FOR_CONTRACT_H
+#define PG_GET_WIRE_HASH_FOR_CONTRACT_H
+
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_exchangedb_plugin.h"
+
+/**
+ * Try to get the salted hash of a merchant's bank account to a deposit
+ * contract. This is necessary in the event of a conflict with a given
+ * (merchant_pub, h_contract_terms) during deposit.
+ *
+ * @param cls closure
+ * @param merchant_pub merchant public key
+ * @param h_contract_terms hash of the proposal data
+ * @param[out] h_wire salted hash of a merchant's bank account
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_get_wire_hash_for_contract (
+  void *cls,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  struct TALER_MerchantWireHashP *h_wire);
+
+#endif
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 7d9044a1..4e7bccbd 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -121,6 +121,7 @@
 #include "pg_get_policy_details.h"
 #include "pg_persist_policy_details.h"
 #include "pg_do_deposit.h"
+#include "pg_get_wire_hash_for_contract.h"
 #include "pg_add_policy_fulfillment_proof.h"
 #include "pg_do_melt.h"
 #include "pg_do_refund.h"
@@ -584,6 +585,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
     = &TEH_PG_persist_policy_details;
   plugin->do_deposit
     = &TEH_PG_do_deposit;
+  plugin->get_wire_hash_for_contract
+    = &TEH_PG_get_wire_hash_for_contract;
   plugin->add_policy_fulfillment_proof
     = &TEH_PG_add_policy_fulfillment_proof;
   plugin->do_melt
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 25d3b17f..7f7105a0 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -4399,6 +4399,25 @@ struct TALER_EXCHANGEDB_Plugin
                              struct TALER_DenominationHashP *denom_hash);
 
 
+  /**
+   * Try to retrieve the solated hash of the merchant's bank account to a
+   * deposit contract. Used in case of conflicts for a given (merchant_pub,
+   * h_contract_terms) to provide the client the necessary input to retrieve
+   * more details about the conflict.
+   *
+   * @param cls the plugin closure
+   * @param merchant_pub public key of the merchant
+   * @param h_contract_terms contract to check for
+   * @param[out] h_wire hash of the wire details
+   */
+  enum GNUNET_DB_QueryStatus
+    (*get_wire_hash_for_contract)(
+    void *cls,
+    const struct TALER_MerchantPublicKeyP *merchant_pub,
+    const struct TALER_PrivateContractHashP *h_contract_terms,
+    struct TALER_MerchantWireHashP *h_wire);
+
+
   /**
    * Check if we have the specified deposit already in the database.
    *

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