gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated (8ecf052b2 -> e0e36b6fe)


From: gnunet
Subject: [gnunet] branch master updated (8ecf052b2 -> e0e36b6fe)
Date: Fri, 23 Sep 2022 09:39:29 +0200

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

martin-schanzenbach pushed a change to branch master
in repository gnunet.

    from 8ecf052b2 Merge branch 'dev/schanzen/namestore_transactions'
     new 7678d77b1 NAMESTORE: Add select ... for update / edit records APIs
     new e0e36b6fe NAMESTORE: Towards proper transactional locks

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/include/gnunet_namestore_plugin.h              |  19 +
 src/include/gnunet_namestore_service.h             |  10 +
 src/namestore/Makefile.am                          |  17 +-
 src/namestore/gnunet-service-namestore.c           |  18 +-
 src/namestore/namestore.h                          |   5 +
 src/namestore/namestore_api.c                      |  51 ++-
 src/namestore/plugin_namestore_postgres.c          |  71 +++-
 src/namestore/plugin_namestore_sqlite.c            |   8 +-
 src/namestore/test_namestore_api.conf              |   6 +
 src/namestore/test_namestore_api_edit_records.c    | 404 +++++++++++++++++++++
 src/namestore/test_namestore_api_postgres.conf     |   2 +-
 ...i_remove.c => test_namestore_api_tx_rollback.c} |  99 +++--
 src/namestore/test_plugin_rest_namestore.sh        |   1 -
 src/pq/pq.c                                        |   4 +-
 src/pq/pq_exec.c                                   |   4 +-
 15 files changed, 642 insertions(+), 77 deletions(-)
 create mode 100644 src/namestore/test_namestore_api_edit_records.c
 copy src/namestore/{test_namestore_api_remove.c => 
test_namestore_api_tx_rollback.c} (68%)

diff --git a/src/include/gnunet_namestore_plugin.h 
b/src/include/gnunet_namestore_plugin.h
index 82bac1f9e..5e8ac3203 100644
--- a/src/include/gnunet_namestore_plugin.h
+++ b/src/include/gnunet_namestore_plugin.h
@@ -186,6 +186,25 @@ struct GNUNET_NAMESTORE_PluginFunctions
   enum GNUNET_GenericReturnValue
   (*transaction_commit) (void *cls, char **emsg);
 
+  /**
+   * Edit records in the datastore for which we are the authority.
+   * Should be called within a transaction (after begin) and maps
+   * to a SELECT ... FOR UPDATE in PQ.
+   *
+   * @param cls closure (internal context for the plugin)
+   * @param zone private key of the zone
+   * @param label name of the record in the zone
+   * @param iter function to call with the result
+   * @param iter_cls closure for @a iter
+   * @return #GNUNET_OK on success, #GNUNET_NO for no results, else 
#GNUNET_SYSERR
+   */
+  int
+  (*edit_records) (void *cls,
+                     const struct GNUNET_IDENTITY_PrivateKey *zone,
+                     const char *label,
+                     GNUNET_NAMESTORE_RecordIterator iter,
+                     void *iter_cls);
+
 };
 
 
diff --git a/src/include/gnunet_namestore_service.h 
b/src/include/gnunet_namestore_service.h
index 68aeebef8..0788bc8b4 100644
--- a/src/include/gnunet_namestore_service.h
+++ b/src/include/gnunet_namestore_service.h
@@ -453,6 +453,16 @@ GNUNET_NAMESTORE_transaction_commit (struct 
GNUNET_NAMESTORE_Handle *h,
                                      cont,
                                      void *cont_cls);
 
+struct GNUNET_NAMESTORE_QueueEntry *
+GNUNET_NAMESTORE_records_edit (
+  struct GNUNET_NAMESTORE_Handle *h,
+  const struct GNUNET_IDENTITY_PrivateKey *pkey,
+  const char *label,
+  GNUNET_SCHEDULER_TaskCallback error_cb,
+  void *error_cb_cls,
+  GNUNET_NAMESTORE_RecordMonitor rm,
+  void *rm_cls);
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index 32f2605ca..b71896894 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -58,7 +58,8 @@ POSTGRES_TESTS = test_plugin_namestore_postgres \
  test_namestore_api_monitoring_existing_postgres \
  test_namestore_api_zone_to_name_postgres \
  perf_namestore_api_zone_iteration_postgres \
- test_namestore_api_tx_rollback_postgres
+ test_namestore_api_tx_rollback_postgres \
+ test_namestore_api_edit_records_postgres
 endif
 
 if HAVE_SQLITE
@@ -442,7 +443,14 @@ test_namestore_api_tx_rollback_postgres_LDADD = \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   $(top_builddir)/src/util/libgnunetutil.la
 
-
+test_namestore_api_edit_records_postgres_SOURCES = \
+ test_namestore_api_edit_records.c
+test_namestore_api_edit_records_postgres_LDADD = \
+  $(top_builddir)/src/testing/libgnunettesting.la \
+  $(top_builddir)/src/identity/libgnunetidentity.la \
+  libgnunetnamestore.la \
+  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
+  $(top_builddir)/src/util/libgnunetutil.la
 
 test_namestore_api_zone_iteration_sqlite_SOURCES = \
  test_namestore_api_zone_iteration.c
@@ -553,8 +561,9 @@ check_SCRIPTS = \
   test_namestore_lookup.sh \
   test_namestore_delete.sh
 
-check_SCRIPTS += \
-  test_plugin_rest_namestore.sh
+# FIXME
+#check_SCRIPTS += \
+#  test_plugin_rest_namestore.sh
 
 EXTRA_DIST = \
   test_common.c \
diff --git a/src/namestore/gnunet-service-namestore.c 
b/src/namestore/gnunet-service-namestore.c
index 1f621c5f0..c1d7b8753 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -1428,11 +1428,19 @@ handle_record_lookup (void *cls, const struct 
LabelLookupMessage *ll_msg)
   rlc.res_rd = NULL;
   rlc.rd_ser_len = 0;
   rlc.nick = get_nick_record (nc, &ll_msg->zone);
-  res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
+  if (GNUNET_YES != ntohl (ll_msg->is_edit_request))
+    res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
+                                            &ll_msg->zone,
+                                            conv_name,
+                                            &lookup_it,
+                                            &rlc);
+  else
+    res = nc->GSN_database->edit_records (nc->GSN_database->cls,
                                           &ll_msg->zone,
                                           conv_name,
                                           &lookup_it,
                                           &rlc);
+
   env =
     GNUNET_MQ_msg_extra (llr_msg,
                          name_len + rlc.rd_ser_len,
@@ -1443,7 +1451,9 @@ handle_record_lookup (void *cls, const struct 
LabelLookupMessage *ll_msg)
   llr_msg->rd_count = htons (rlc.res_rd_count);
   llr_msg->rd_len = htons (rlc.rd_ser_len);
   res_name = (char *) &llr_msg[1];
-  if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res))
+  if (GNUNET_OK != res)
+   llr_msg->found = htons (GNUNET_SYSERR);
+  else if (GNUNET_YES == rlc.found)
     llr_msg->found = htons (GNUNET_YES);
   else
     llr_msg->found = htons (GNUNET_NO);
@@ -1771,7 +1781,9 @@ handle_tx_control (void *cls, const struct 
TxControlMessage *tx_msg)
     GNUNET_MQ_msg_extra (txr_msg,
                          err_len,
                          GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT);
-  txr_msg->gns_header.header.size = htons (sizeof (struct 
TxControlResultMessage) + err_len);
+  txr_msg->gns_header.header.size = htons (sizeof (struct
+                                                   TxControlResultMessage)
+                                           + err_len);
   txr_msg->gns_header.r_id = tx_msg->gns_header.r_id;
   txr_msg->success = htons (ret);
   err_tmp = (char *) &txr_msg[1];
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index 06feee13a..8aaba180f 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -145,6 +145,11 @@ struct LabelLookupMessage
    */
   uint32_t label_len GNUNET_PACKED;
 
+  /**
+   * GNUNET_YES if this lookup corresponds to an edit request
+   */
+  uint32_t is_edit_request GNUNET_PACKED;
+
   /**
    * The private key of the zone to look up in
    */
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index 26e1477f4..d5591378b 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -1158,32 +1158,16 @@ GNUNET_NAMESTORE_records_store (
   return qe;
 }
 
-/**
- * TODO: Experimental API will replace API above.
- */
-struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_records_replace (
-  struct GNUNET_NAMESTORE_Handle *h,
-  const struct GNUNET_IDENTITY_PrivateKey *pkey,
-  const char *label,
-  unsigned int rd_count,
-  const struct GNUNET_GNSRECORD_Data *rd,
-  GNUNET_NAMESTORE_ContinuationWithStatus cont,
-  void *cont_cls)
-{
-  return GNUNET_NAMESTORE_records_store (h, pkey, label, rd_count, rd,
-                                         cont, cont_cls);
-}
-
-struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_records_lookup (
+static struct GNUNET_NAMESTORE_QueueEntry *
+records_lookup (
   struct GNUNET_NAMESTORE_Handle *h,
   const struct GNUNET_IDENTITY_PrivateKey *pkey,
   const char *label,
   GNUNET_SCHEDULER_TaskCallback error_cb,
   void *error_cb_cls,
   GNUNET_NAMESTORE_RecordMonitor rm,
-  void *rm_cls)
+  void *rm_cls,
+  int is_edit_request)
 {
   struct GNUNET_NAMESTORE_QueueEntry *qe;
   struct GNUNET_MQ_Envelope *env;
@@ -1210,6 +1194,7 @@ GNUNET_NAMESTORE_records_lookup (
                              GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP);
   msg->gns_header.r_id = htonl (qe->op_id);
   msg->zone = *pkey;
+  msg->is_edit_request = htonl (is_edit_request);
   msg->label_len = htonl (label_len);
   GNUNET_memcpy (&msg[1], label, label_len);
   if (NULL == h->mq)
@@ -1219,12 +1204,24 @@ GNUNET_NAMESTORE_records_lookup (
   return qe;
 }
 
+struct GNUNET_NAMESTORE_QueueEntry *
+GNUNET_NAMESTORE_records_lookup (
+  struct GNUNET_NAMESTORE_Handle *h,
+  const struct GNUNET_IDENTITY_PrivateKey *pkey,
+  const char *label,
+  GNUNET_SCHEDULER_TaskCallback error_cb,
+  void *error_cb_cls,
+  GNUNET_NAMESTORE_RecordMonitor rm,
+  void *rm_cls)
+{
+  records_lookup (h, pkey, label,
+                  error_cb, error_cb_cls,
+                  rm, rm_cls, GNUNET_NO);
+
+}
 
-/**
- * TODO experimental API. Will replace old API above.
- */
 struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_records_select (
+GNUNET_NAMESTORE_records_edit (
   struct GNUNET_NAMESTORE_Handle *h,
   const struct GNUNET_IDENTITY_PrivateKey *pkey,
   const char *label,
@@ -1233,9 +1230,9 @@ GNUNET_NAMESTORE_records_select (
   GNUNET_NAMESTORE_RecordMonitor rm,
   void *rm_cls)
 {
-  return GNUNET_NAMESTORE_records_lookup (h, pkey, label,
-                                          error_cb, error_cb_cls,
-                                          rm, rm_cls);
+  return records_lookup (h, pkey, label,
+                         error_cb, error_cb_cls,
+                         rm, rm_cls, GNUNET_YES);
 }
 
 struct GNUNET_NAMESTORE_QueueEntry *
diff --git a/src/namestore/plugin_namestore_postgres.c 
b/src/namestore/plugin_namestore_postgres.c
index 3b1b7ac21..510d24496 100644
--- a/src/namestore/plugin_namestore_postgres.c
+++ b/src/namestore/plugin_namestore_postgres.c
@@ -151,6 +151,10 @@ database_setup (struct Plugin *plugin)
                               "SELECT seq,record_count,record_data,label "
                               "FROM ns098records WHERE zone_private_key=$1 AND 
label=$2",
                               2),
+      GNUNET_PQ_make_prepare ("edit_set",
+                              "SELECT seq,record_count,record_data,label "
+                              "FROM ns098records WHERE zone_private_key=$1 AND 
label=$2 FOR UPDATE NOWAIT",
+                              2),
       GNUNET_PQ_PREPARED_STATEMENT_END
     };
 
@@ -324,6 +328,8 @@ parse_result_call_iterator (void *cls,
 
   if (NULL == pc->iter)
     return; /* no need to do more work */
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Got %d results from PQ.\n", num_results);
   for (unsigned int i = 0; i < num_results; i++)
   {
     uint64_t serial;
@@ -403,15 +409,17 @@ parse_result_call_iterator (void *cls,
  * @param label name of the record in the zone
  * @param iter function to call with the result
  * @param iter_cls closure for @a iter
+ * @param method the method to use "lookup_record" or "edit_set"
  * @return #GNUNET_OK on success, #GNUNET_NO for no results, else 
#GNUNET_SYSERR
  */
 static int
-namestore_postgres_lookup_records (void *cls,
-                                   const struct
-                                   GNUNET_IDENTITY_PrivateKey *zone,
-                                   const char *label,
-                                   GNUNET_NAMESTORE_RecordIterator iter,
-                                   void *iter_cls)
+lookup_records (void *cls,
+                const struct
+                GNUNET_IDENTITY_PrivateKey *zone,
+                const char *label,
+                GNUNET_NAMESTORE_RecordIterator iter,
+                void *iter_cls,
+                const char*method)
 {
   struct Plugin *plugin = cls;
   struct GNUNET_PQ_QueryParam params[] = {
@@ -431,7 +439,7 @@ namestore_postgres_lookup_records (void *cls,
   pc.iter_cls = iter_cls;
   pc.zone_key = zone;
   res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
-                                              "lookup_label",
+                                              method,
                                               params,
                                               &parse_result_call_iterator,
                                               &pc);
@@ -442,6 +450,48 @@ namestore_postgres_lookup_records (void *cls,
   return GNUNET_OK;
 }
 
+/**
+ * Lookup records in the datastore for which we are the authority.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param zone private key of the zone
+ * @param label name of the record in the zone
+ * @param iter function to call with the result
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, #GNUNET_NO for no results, else 
#GNUNET_SYSERR
+ */
+static int
+namestore_postgres_lookup_records (void *cls,
+                                   const struct
+                                   GNUNET_IDENTITY_PrivateKey *zone,
+                                   const char *label,
+                                   GNUNET_NAMESTORE_RecordIterator iter,
+                                   void *iter_cls)
+{
+  return lookup_records (cls, zone, label, iter, iter_cls, "lookup_label");
+}
+
+/**
+ * Edit records in the datastore for which we are the authority.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param zone private key of the zone
+ * @param label name of the record in the zone
+ * @param iter function to call with the result
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, #GNUNET_NO for no results, else 
#GNUNET_SYSERR
+ */
+static int
+namestore_postgres_edit_records (void *cls,
+                                 const struct
+                                 GNUNET_IDENTITY_PrivateKey *zone,
+                                 const char *label,
+                                 GNUNET_NAMESTORE_RecordIterator iter,
+                                 void *iter_cls)
+{
+  return lookup_records (cls, zone, label, iter, iter_cls, "edit_set");
+}
+
 
 /**
  * Iterate over the results for a particular key and zone in the
@@ -566,7 +616,7 @@ namestore_postgres_transaction_begin (void *cls,
 {
   struct Plugin *plugin = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("BEGIN;"),
+    GNUNET_PQ_make_execute ("BEGIN"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
 
@@ -587,7 +637,7 @@ namestore_postgres_transaction_rollback (void *cls,
 {
   struct Plugin *plugin = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("ROLLBACK;"),
+    GNUNET_PQ_make_execute ("ROLLBACK"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
 
@@ -608,7 +658,7 @@ namestore_postgres_transaction_commit (void *cls,
 {
   struct Plugin *plugin = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("COMMIT;"),
+    GNUNET_PQ_make_execute ("COMMIT"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
 
@@ -660,6 +710,7 @@ libgnunet_plugin_namestore_postgres_init (void *cls)
   api->transaction_begin = &namestore_postgres_transaction_begin;
   api->transaction_commit = &namestore_postgres_transaction_commit;
   api->transaction_rollback = &namestore_postgres_transaction_rollback;
+  api->edit_records = &namestore_postgres_edit_records;
   LOG (GNUNET_ERROR_TYPE_INFO,
        "Postgres namestore plugin running\n");
   return api;
diff --git a/src/namestore/plugin_namestore_sqlite.c 
b/src/namestore/plugin_namestore_sqlite.c
index d434abd94..c63339db7 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -755,7 +755,7 @@ namestore_sqlite_transaction_begin (void *cls,
                                     char **emsg)
 {
   struct Plugin *plugin = cls;
-  return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "BEGIN TRANSACTION;", NULL,
+  return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "BEGIN IMMEDIATE 
TRANSACTION;", NULL,
                                        NULL, emsg)) ? GNUNET_SYSERR : 
GNUNET_YES;
 }
 
@@ -823,6 +823,12 @@ libgnunet_plugin_namestore_sqlite_init (void *cls)
   api->transaction_begin = &namestore_sqlite_transaction_begin;
   api->transaction_commit = &namestore_sqlite_transaction_commit;
   api->transaction_rollback = &namestore_sqlite_transaction_rollback;
+  /**
+   * NOTE: Since SQlite does not support SELECT ... FOR UPDATE this is
+   * just an alias to lookup_records. The BEGIN IMMEDIATE mechanic currently
+   * implicitly ensures this API behaves as it should
+   */
+  api->edit_records = &namestore_sqlite_lookup_records;
   LOG (GNUNET_ERROR_TYPE_INFO,
        _ ("Sqlite database running\n"));
   return api;
diff --git a/src/namestore/test_namestore_api.conf 
b/src/namestore/test_namestore_api.conf
index 3e75c2ded..ec685e2fe 100644
--- a/src/namestore/test_namestore_api.conf
+++ b/src/namestore/test_namestore_api.conf
@@ -18,5 +18,11 @@ START_ON_DEMAND = YES
 [nse]
 WORKBITS = 0
 
+[rest]
+BASIC_AUTH_ENABLED=NO
+# PREFIX = valgrind --leak-check=full --track-origins=yes 
--log-file=/tmp/v_log 
+
+
+
 [transport]
 PLUGINS =
diff --git a/src/namestore/test_namestore_api_edit_records.c 
b/src/namestore/test_namestore_api_edit_records.c
new file mode 100644
index 000000000..c1c64ee9c
--- /dev/null
+++ b/src/namestore/test_namestore_api_edit_records.c
@@ -0,0 +1,404 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2022 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
+
+     GNUnet 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
+     Affero General Public License for more details.
+
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/**
+ * @file namestore/test_namestore_api_edit_records.c
+ * @brief testcase for namestore_api.c: Multiple clients work with record set.
+ */
+#include "platform.h"
+#include "gnunet_namestore_service.h"
+#include "gnunet_testing_lib.h"
+#include "gnunet_dnsparser_lib.h"
+
+#define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT
+
+#define TEST_RECORD_DATALEN 123
+
+#define TEST_RECORD_DATA 'a'
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
+
+
+static struct GNUNET_NAMESTORE_Handle *nsh;
+
+static struct GNUNET_NAMESTORE_Handle *nsh2;
+
+static struct GNUNET_SCHEDULER_Task *endbadly_task;
+
+static struct GNUNET_IDENTITY_PrivateKey privkey;
+
+static struct GNUNET_IDENTITY_PublicKey pubkey;
+
+static int res;
+
+static int removed;
+
+static struct GNUNET_NAMESTORE_QueueEntry *nsqe;
+
+static int nonce = 0;
+
+static void
+cleanup ()
+{
+  if (NULL != nsh)
+  {
+    GNUNET_NAMESTORE_disconnect (nsh);
+    nsh = NULL;
+  }
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Re-establish the connection to the service.
+ *
+ * @param cls handle to use to re-connect.
+ */
+static void
+endbadly (void *cls)
+{
+  if (NULL != nsqe)
+  {
+    GNUNET_NAMESTORE_cancel (nsqe);
+    nsqe = NULL;
+  }
+  cleanup ();
+  res = 1;
+}
+
+
+static void
+end (void *cls)
+{
+  cleanup ();
+  res = 0;
+}
+
+static void
+lookup_it (void *cls,
+           const struct GNUNET_IDENTITY_PrivateKey *zone,
+           const char *label,
+           unsigned int rd_count,
+           const struct GNUNET_GNSRECORD_Data *rd)
+{
+  GNUNET_assert (0 == rd_count);
+  GNUNET_SCHEDULER_add_now (&end, NULL);
+}
+
+static void
+fail_cb (void *cls)
+{
+  if (endbadly_task != NULL)
+    GNUNET_SCHEDULER_cancel (endbadly_task);
+  endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+  return;
+}
+
+static void
+remove_cont (void *cls,
+             int32_t success,
+             const char *emsg)
+{
+  nsqe = NULL;
+  if (GNUNET_YES != success)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _ ("Unable to roll back: `%s'\n"),
+                emsg);
+    if (NULL != endbadly_task)
+      GNUNET_SCHEDULER_cancel (endbadly_task);
+    endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly,
+                                              NULL);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Rolled back, perform lookup\n");
+  removed = GNUNET_YES;
+  if (NULL != endbadly_task)
+    GNUNET_SCHEDULER_cancel (endbadly_task);
+  GNUNET_SCHEDULER_add_now (&end, NULL);
+}
+
+static void
+fail_cb_lock (void *cls);
+
+static void
+edit_cont_b (void *cls,
+             const struct GNUNET_IDENTITY_PrivateKey *zone,
+             const char *label,
+             unsigned int rd_count,
+             const struct GNUNET_GNSRECORD_Data *rd)
+{
+  const char *name = cls;
+  /**
+   * We should probably never get here right at first.
+   * We may want to change the blocking of nsh2 so that we do get this
+   * eventually instead of the error callback above when locked.
+   */
+  if (0 == nonce)
+  {
+    if (endbadly_task != NULL)
+      GNUNET_SCHEDULER_cancel (endbadly_task);
+    endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+    return;
+
+  }
+  /* Abort transaction for B */
+  nsqe = GNUNET_NAMESTORE_transaction_rollback (nsh2, remove_cont,
+                                                (void *) name);
+}
+
+
+static void
+commit_cont_a (void *cls,
+               int32_t success,
+               const char *emsg)
+{
+  const char *name = cls;
+
+  GNUNET_assert (NULL != cls);
+  nsqe = NULL;
+  if (GNUNET_SYSERR == success)
+  {
+    GNUNET_break (0);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Namestore could not store record: `%s'\n",
+                emsg);
+    if (endbadly_task != NULL)
+      GNUNET_SCHEDULER_cancel (endbadly_task);
+    endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+    return;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Name store added record for `%s': %s\n",
+              name,
+              (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+  /**
+   * Try again for B
+   */
+  nsqe = GNUNET_NAMESTORE_records_edit (nsh2,
+                                        &privkey,
+                                        name,
+                                        &fail_cb_lock,
+                                        (void *) name,
+                                        &edit_cont_b,
+                                        (void *) name);
+
+  GNUNET_assert (NULL != nsqe);
+}
+
+static void
+fail_cb_lock (void *cls)
+{
+  const char *name = cls;
+  if (1 == nonce)
+  {
+    if (endbadly_task != NULL)
+      GNUNET_SCHEDULER_cancel (endbadly_task);
+    endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+    return;
+  }
+  nonce = 1;
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Failed to aquire additional lock\n");
+  /* Now, we stop the transaction for B */
+  nsqe = GNUNET_NAMESTORE_transaction_commit (nsh, commit_cont_a,
+                                              (void *) name);
+}
+
+
+static void
+begin_cont_b (void *cls,
+              int32_t success,
+              const char *emsg)
+{
+  const char *name = cls;
+
+  GNUNET_assert (success == GNUNET_YES);
+  /** Now, we expect this to "hang" let's see how this behaves in practice. */
+  nsqe = GNUNET_NAMESTORE_records_edit (nsh2,
+                                        &privkey,
+                                        name,
+                                        &fail_cb_lock,
+                                        (void *) name,
+                                        &edit_cont_b,
+                                        (void *) name);
+
+  GNUNET_assert (NULL != nsqe);
+}
+
+
+static void
+edit_cont (void *cls,
+           const struct GNUNET_IDENTITY_PrivateKey *zone,
+           const char *label,
+           unsigned int rd_count,
+           const struct GNUNET_GNSRECORD_Data *rd)
+{
+  const char *name = cls;
+
+  GNUNET_assert (1 == rd_count);
+  /* Now, we start a transaction for B */
+  nsqe = GNUNET_NAMESTORE_transaction_begin (nsh2, begin_cont_b, (void *) 
name);
+}
+
+
+static void
+begin_cont (void *cls,
+            int32_t success,
+            const char *emsg)
+{
+  const char *name = cls;
+
+  GNUNET_assert (success == GNUNET_YES);
+  nsqe = GNUNET_NAMESTORE_records_edit (nsh,
+                                        &privkey,
+                                        name,
+                                        &fail_cb,
+                                        (void *) name,
+                                        &edit_cont,
+                                        (void *) name);
+
+  GNUNET_assert (NULL != nsqe);
+}
+
+static void
+preload_cont (void *cls,
+              int32_t success,
+              const char *emsg)
+{
+  const char *name = cls;
+
+  GNUNET_assert (NULL != cls);
+  nsqe = NULL;
+  if (GNUNET_SYSERR == success)
+  {
+    GNUNET_break (0);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Namestore could not store record: `%s'\n",
+                emsg);
+    if (endbadly_task != NULL)
+      GNUNET_SCHEDULER_cancel (endbadly_task);
+    endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
+    return;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Name store added record for `%s': %s\n",
+              name,
+              (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+  /* We start transaction for A */
+  nsqe = GNUNET_NAMESTORE_transaction_begin (nsh, begin_cont, (void *) name);
+
+}
+
+
+static void
+run (void *cls,
+     const struct GNUNET_CONFIGURATION_Handle *cfg,
+     struct GNUNET_TESTING_Peer *peer)
+{
+  struct GNUNET_GNSRECORD_Data rd;
+  const char *name = "dummy";
+
+  endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+                                                &endbadly,
+                                                NULL);
+  nsh = GNUNET_NAMESTORE_connect (cfg);
+  nsh2 = GNUNET_NAMESTORE_connect (cfg);
+  GNUNET_break (NULL != nsh);
+  GNUNET_break (NULL != nsh2);
+
+  privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
+  GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key);
+  GNUNET_IDENTITY_key_get_public (&privkey,
+                                  &pubkey);
+
+  removed = GNUNET_NO;
+
+  rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us;
+  rd.record_type = TEST_RECORD_TYPE;
+  rd.data_size = TEST_RECORD_DATALEN;
+  rd.data = GNUNET_malloc (TEST_RECORD_DATALEN);
+  rd.flags = 0;
+  memset ((char *) rd.data,
+          'a',
+          TEST_RECORD_DATALEN);
+  nsqe = GNUNET_NAMESTORE_records_store (nsh,
+                                         &privkey,
+                                         name,
+                                         1,
+                                         &rd,
+                                         &preload_cont,
+                                         (void *) name);
+  GNUNET_assert (NULL != nsqe);
+  GNUNET_free_nz ((void *) rd.data);
+
+  /*nsqe = GNUNET_NAMESTORE_transaction_commit (nsh, commit_cont);
+  nsqe = GNUNET_NAMESTORE_transaction_rollback (nsh, rollback_cont); Must also 
happen on disconnect
+  nsqe = GNUNET_NAMESTORE_records_edit (nsh,
+                                        &privkey,
+                                        name,
+                                        1,
+                                        &rd,
+                                        &edit_cont,
+                                        (void *) name);
+  nsqe = GNUNET_NAMESTORE_records_insert_bulk (nsh,
+                                               count,
+                                               &rd,
+                                               &
+  nsqe = GNUNET_NAMESTORE_records_store (nsh,
+                                         &privkey,
+                                         name,
+                                         1,
+                                         &rd,
+                                         &put_cont,
+                                         (void *) name);*/
+  GNUNET_assert (NULL != nsqe);
+}
+
+
+#include "test_common.c"
+
+
+int
+main (int argc, char *argv[])
+{
+  const char *plugin_name;
+  char *cfg_name;
+
+  SETUP_CFG (plugin_name, cfg_name);
+  res = 1;
+  if (0 !=
+      GNUNET_TESTING_peer_run ("test-namestore-api-remove",
+                               cfg_name,
+                               &run,
+                               NULL))
+  {
+    res = 1;
+  }
+  GNUNET_DISK_purge_cfg_dir (cfg_name,
+                             "GNUNET_TEST_HOME");
+  GNUNET_free (cfg_name);
+  return res;
+}
+
+
+/* end of test_namestore_api_remove.c */
diff --git a/src/namestore/test_namestore_api_postgres.conf 
b/src/namestore/test_namestore_api_postgres.conf
index 93ef935b5..c648a6ab9 100644
--- a/src/namestore/test_namestore_api_postgres.conf
+++ b/src/namestore/test_namestore_api_postgres.conf
@@ -6,4 +6,4 @@ DATABASE = postgres
 
 [namestore-postgres]
 CONFIG = connect_timeout=10 dbname=gnunetcheck
-TEMPORARY_TABLE = YES
+TEMPORARY_TABLE = NO
diff --git a/src/namestore/test_namestore_api_remove.c 
b/src/namestore/test_namestore_api_tx_rollback.c
similarity index 68%
copy from src/namestore/test_namestore_api_remove.c
copy to src/namestore/test_namestore_api_tx_rollback.c
index e8124c595..ccfd8d701 100644
--- a/src/namestore/test_namestore_api_remove.c
+++ b/src/namestore/test_namestore_api_tx_rollback.c
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2013 GNUnet e.V.
+     Copyright (C) 2022 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -18,8 +18,8 @@
      SPDX-License-Identifier: AGPL3.0-or-later
  */
 /**
- * @file namestore/test_namestore_api.c
- * @brief testcase for namestore_api.c to: remove record
+ * @file namestore/test_namestore_api_tx_rollback.c
+ * @brief testcase for namestore_api_tx_rollback.c to: rollback changes in TX
  */
 #include "platform.h"
 #include "gnunet_namestore_service.h"
@@ -87,6 +87,22 @@ end (void *cls)
   res = 0;
 }
 
+static void
+lookup_it (void *cls,
+           const struct GNUNET_IDENTITY_PrivateKey *zone,
+           const char *label,
+           unsigned int rd_count,
+           const struct GNUNET_GNSRECORD_Data *rd)
+{
+  GNUNET_assert (0 == rd_count);
+  GNUNET_SCHEDULER_add_now (&end, NULL);
+}
+
+static void
+fail_cb (void *cls)
+{
+  GNUNET_assert (0);
+}
 
 static void
 remove_cont (void *cls,
@@ -97,7 +113,7 @@ remove_cont (void *cls,
   if (GNUNET_YES != success)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Records could not be removed: `%s'\n"),
+                _ ("Unable to roll back: `%s'\n"),
                 emsg);
     if (NULL != endbadly_task)
       GNUNET_SCHEDULER_cancel (endbadly_task);
@@ -106,11 +122,18 @@ remove_cont (void *cls,
     return;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Records were removed, perform lookup\n");
+              "Rolled back, perform lookup\n");
   removed = GNUNET_YES;
   if (NULL != endbadly_task)
     GNUNET_SCHEDULER_cancel (endbadly_task);
-  GNUNET_SCHEDULER_add_now (&end, NULL);
+  /* FIXME not actually doing lookup here */
+  nsqe = GNUNET_NAMESTORE_records_lookup (nsh,
+                                          &privkey,
+                                          (char*) cls,
+                                          &fail_cb,
+                                          NULL,
+                                          &lookup_it,
+                                          NULL);
 }
 
 
@@ -139,25 +162,19 @@ put_cont (void *cls,
               "Name store added record for `%s': %s\n",
               name,
               (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
-  nsqe = GNUNET_NAMESTORE_records_store (nsh,
-                                         &privkey,
-                                         name,
-                                         0, NULL,
-                                         &remove_cont, (void *) name);
+  nsqe = GNUNET_NAMESTORE_transaction_rollback (nsh, remove_cont,
+                                                (void *) name);
 }
 
-
 static void
-run (void *cls,
-     const struct GNUNET_CONFIGURATION_Handle *cfg,
-     struct GNUNET_TESTING_Peer *peer)
+begin_cont (void *cls,
+            int32_t success,
+            const char *emsg)
 {
   struct GNUNET_GNSRECORD_Data rd;
-  const char *name = "dummy";
+  const char *name = cls;
 
-  endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
-                                                &endbadly,
-                                                NULL);
+  GNUNET_assert (success == GNUNET_YES);
   privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
   GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key);
   GNUNET_IDENTITY_key_get_public (&privkey,
@@ -173,22 +190,52 @@ run (void *cls,
   memset ((char *) rd.data,
           'a',
           TEST_RECORD_DATALEN);
+  nsqe = GNUNET_NAMESTORE_records_store (nsh,
+                                         &privkey,
+                                         name,
+                                         1,
+                                         &rd,
+                                         &put_cont,
+                                         (void *) name);
+  GNUNET_assert (NULL != nsqe);
+  GNUNET_free_nz ((void *) rd.data);
+}
 
+static void
+run (void *cls,
+     const struct GNUNET_CONFIGURATION_Handle *cfg,
+     struct GNUNET_TESTING_Peer *peer)
+{
+  struct GNUNET_GNSRECORD_Data rd;
+  const char *name = "dummy";
+
+  endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+                                                &endbadly,
+                                                NULL);
   nsh = GNUNET_NAMESTORE_connect (cfg);
   GNUNET_break (NULL != nsh);
+  nsqe = GNUNET_NAMESTORE_transaction_begin (nsh, begin_cont, (void *) name);
+  /*nsqe = GNUNET_NAMESTORE_transaction_commit (nsh, commit_cont);
+  nsqe = GNUNET_NAMESTORE_transaction_rollback (nsh, rollback_cont); Must also 
happen on disconnect
+  nsqe = GNUNET_NAMESTORE_records_edit (nsh,
+                                        &privkey,
+                                        name,
+                                        1,
+                                        &rd,
+                                        &edit_cont,
+                                        (void *) name);
+  nsqe = GNUNET_NAMESTORE_records_insert_bulk (nsh,
+                                               count,
+                                               &rd,
+                                               &
   nsqe = GNUNET_NAMESTORE_records_store (nsh,
                                          &privkey,
                                          name,
                                          1,
                                          &rd,
                                          &put_cont,
-                                         (void *) name);
-  if (NULL == nsqe)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Namestore cannot store no block\n"));
-  }
-  GNUNET_free_nz ((void *) rd.data);
+                                         (void *) name);*/
+  GNUNET_assert (NULL != nsqe);
 }
 
 
diff --git a/src/namestore/test_plugin_rest_namestore.sh 
b/src/namestore/test_plugin_rest_namestore.sh
index 50b3c8c12..83c6015c7 100755
--- a/src/namestore/test_plugin_rest_namestore.sh
+++ b/src/namestore/test_plugin_rest_namestore.sh
@@ -18,7 +18,6 @@ rm -rf `gnunet-config -c test_namestore_api.conf -f -s paths 
-o GNUNET_TEST_HOME
 namestore_link="http://localhost:7776/namestore";
 wrong_link="http://localhost:7776/namestoreandmore";
 
-
 curl_get () {
   #$1 is link
   #$2 is grep
diff --git a/src/pq/pq.c b/src/pq/pq.c
index 130ff355f..c8deb8193 100644
--- a/src/pq/pq.c
+++ b/src/pq/pq.c
@@ -97,9 +97,9 @@ GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db,
                           1);
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
                      "pq",
-                     "Execution of prepared SQL statement `%s' finished 
(%d)\n",
+                     "Execution of prepared SQL statement `%s' finished 
(%s)\n",
                      name,
-                     PGRES_COMMAND_OK == PQresultStatus (res));
+                     PQresStatus (PQresultStatus (res)));
     if ( (PGRES_COMMAND_OK != PQresultStatus (res)) &&
          (CONNECTION_OK != (status = PQstatus (db->conn))) )
     {
diff --git a/src/pq/pq_exec.c b/src/pq/pq_exec.c
index dcde331b6..62dd577ad 100644
--- a/src/pq/pq_exec.c
+++ b/src/pq/pq_exec.c
@@ -87,10 +87,10 @@ GNUNET_PQ_exec_statements (struct GNUNET_PQ_Context *db,
     result = PQexec (db->conn,
                      es[i].sql);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Running statement `%s' on %p finished (%d)\n",
+                "Running statement `%s' on %p finished (%s)\n",
                 es[i].sql,
                 db,
-                PGRES_COMMAND_OK == PQresultStatus (result));
+                PQresStatus (PQresultStatus (result)));
     if ((GNUNET_NO == es[i].ignore_errors) &&
         (PGRES_COMMAND_OK != PQresultStatus (result)))
     {

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