gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [gnunet] branch master updated (1672c85ad -> 8ecf052b2)
Date: Fri, 23 Sep 2022 06:01:04 +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 1672c85ad -fix: FS needs to be run as user service
     new e1d8213bb NAMESTORE: Start transactional API
     new 49d5c4da4 NAMESTORE: Remove unneeded functions and renames.
     new d78b7864d NAMESTORE: Fix existing monitoring test race condition
     new 127ad07a3 NAMESTORE: Use a per client database connection
     new 52babbd64 NAMESTORE: Add begin, commit and rollback API messages
     new 764871dcb NAMESTORE: Remove head based database
     new e238c132f NAMESTORE: Add tx API for postgres
     new 8ecf052b2 Merge branch 'dev/schanzen/namestore_transactions'

The 8 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              |  52 +-
 src/include/gnunet_namestore_service.h             |  96 +--
 src/include/gnunet_protocols.h                     |  22 +
 src/namestore/Makefile.am                          | 222 +-----
 src/namestore/gnunet-service-namestore.c           | 201 +++--
 src/namestore/namestore.h                          |  48 ++
 src/namestore/namestore_api.c                      | 128 +++-
 src/namestore/perf_namestore_api_flat.conf         |  10 -
 src/namestore/plugin_namestore_flat.c              | 818 ---------------------
 src/namestore/plugin_namestore_postgres.c          |  81 +-
 src/namestore/plugin_namestore_sqlite.c            |  95 ++-
 src/namestore/test_namestore_api_flat.conf         |   7 -
 .../test_namestore_api_monitoring_existing.c       |  38 +-
 src/namestore/test_plugin_namestore_flat.conf      |   2 -
 14 files changed, 529 insertions(+), 1291 deletions(-)
 delete mode 100644 src/namestore/perf_namestore_api_flat.conf
 delete mode 100644 src/namestore/plugin_namestore_flat.c
 delete mode 100644 src/namestore/test_namestore_api_flat.conf
 delete mode 100644 src/namestore/test_plugin_namestore_flat.conf

diff --git a/src/include/gnunet_namestore_plugin.h 
b/src/include/gnunet_namestore_plugin.h
index 9301c29fe..82bac1f9e 100644
--- a/src/include/gnunet_namestore_plugin.h
+++ b/src/include/gnunet_namestore_plugin.h
@@ -160,63 +160,31 @@ struct GNUNET_NAMESTORE_PluginFunctions
    * Start a transaction in the database
    *
    * @param cls closure (internal context for the plugin)
-   * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, 
#GNUNET_SYSERR on error
+   * @param emsg message. On error, string will be allocated and must be freed.
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
    */
   enum GNUNET_GenericReturnValue
-  (*transaction_begin) (void *cls);
+  (*transaction_begin) (void *cls, char **emsg);
 
   /**
-   * Abort a transaction in the database
+   * Abort and roll back a transaction in the database
    *
    * @param cls closure (internal context for the plugin)
-   * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, 
#GNUNET_SYSERR on error
+   * @param emsg message. On error, string will be allocated and must be freed.
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
    */
   enum GNUNET_GenericReturnValue
-  (*transaction_abort) (void *cls);
+  (*transaction_rollback) (void *cls, char **emsg);
 
   /**
    * Commit a transaction in the database
    *
    * @param cls closure (internal context for the plugin)
-   * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, 
#GNUNET_SYSERR on error
+   * @param emsg message. On error, string will be allocated and must be freed.
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
    */
   enum GNUNET_GenericReturnValue
-  (*transaction_commit) (void *cls);
-
-  /**
-   * Replace a record in the datastore for which we are the authority.
-   * Removes any existing record in the same zone with the same name.
-   *
-   * @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 rd_count number of entries in @a rd array, 0 to delete all records
-   * @param rd array of records with data to store
-   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
-   */
-  int
-  (*replace_records) (void *cls,
-                    const struct GNUNET_IDENTITY_PrivateKey *zone,
-                    const char *label,
-                    unsigned int rd_count,
-                    const struct GNUNET_GNSRECORD_Data *rd);
-
-  /**
-   * 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
-   */
-  int
-  (*select_records) (void *cls,
-                     const struct GNUNET_IDENTITY_PrivateKey *zone,
-                     const char *label,
-                     GNUNET_NAMESTORE_RecordIterator iter,
-                     void *iter_cls);
+  (*transaction_commit) (void *cls, char **emsg);
 
 };
 
diff --git a/src/include/gnunet_namestore_service.h 
b/src/include/gnunet_namestore_service.h
index 15d3be727..68aeebef8 100644
--- a/src/include/gnunet_namestore_service.h
+++ b/src/include/gnunet_namestore_service.h
@@ -70,6 +70,16 @@ struct GNUNET_NAMESTORE_Handle;
  */
 struct GNUNET_NAMESTORE_ZoneIterator;
 
+/**
+ * Transaction control types.
+ * They roughly correspond to DB transaction controls
+ */
+enum GNUNET_NAMESTORE_TxControl
+{
+  GNUNET_NAMESTORE_TX_BEGIN = 0,
+  GNUNET_NAMESTORE_TX_COMMIT = 1,
+  GNUNET_NAMESTORE_TX_ROLLBACK = 2,
+};
 
 /**
  * Connect to the namestore service.
@@ -404,98 +414,44 @@ GNUNET_NAMESTORE_zone_monitor_stop (struct 
GNUNET_NAMESTORE_ZoneMonitor *zm);
  * Begin a namestore transaction.
  *
  * @param h handle to the namestore
- * @param error_cb function to call on error (i.e. disconnect or unable to get 
lock)
- *        the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
+ * @param cont function to call on result
+ * @param cont_cls closure for @a cont
  * @return handle to abort the request
  */
 struct GNUNET_NAMESTORE_QueueEntry *
 GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h,
-                                    GNUNET_SCHEDULER_TaskCallback error_cb,
-                                    void *error_cb_cls);
+                                    GNUNET_NAMESTORE_ContinuationWithStatus
+                                    cont,
+                                    void *cont_cls);
 
 /**
  * Begin rollback all actions in a transaction.
  * Reverts all actions performed since #GNUNET_NAMESTORE_transaction_begin
  *
  * @param h handle to the namestore
- * @param error_cb function to call on error (i.e. disconnect or unable to get 
lock)
- *        the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
+ * @param cont function to call on result
+ * @param cont_cls closure for @a cont
  * @return handle to abort the request
  */
 struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_transaction_abort (struct GNUNET_NAMESTORE_Handle *h,
-                                    GNUNET_SCHEDULER_TaskCallback error_cb,
-                                    void *error_cb_cls);
+GNUNET_NAMESTORE_transaction_rollback (struct GNUNET_NAMESTORE_Handle *h,
+                                     GNUNET_NAMESTORE_ContinuationWithStatus
+                                     cont,
+                                     void *cont_cls);
 /**
  * Commit a namestore transaction.
  * Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin
  *
  * @param h handle to the namestore
- * @param error_cb function to call on error (i.e. disconnect or unable to get 
lock)
- *        the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
- * @return handle to abort the request
- */
-struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h,
-                                     GNUNET_SCHEDULER_TaskCallback error_cb,
-                                     void *error_cb_cls);
-
-/**
- * Lookup an item in the namestore.
- *
- * @param h handle to the namestore
- * @param pkey private key of the zone
- * @param label name that is being mapped
- * @param error_cb function to call on error (i.e. disconnect)
- *        the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
- * @param rm function to call with the result (with 0 records if we don't have 
that label);
- *        the handle is afterwards invalid
- * @param rm_cls closure for @a rm
- * @return handle to abort the request
- */
-struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_records_select (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);
-
-
-/**
- * Creates, deletes or updates an item in the namestore.
- * If the item is already present, it is replaced with the new record set.
- * Use an empty array to remove all records under the given name.
- *
- * The continuation is called after the value has been stored in the
- * database. Monitors may be notified asynchronously (basically with
- * a buffer). However, if any monitor is consistently too slow to
- * keep up with the changes, calling @a cont will be delayed until the
- * monitors do keep up.
- *
- * @param h handle to the namestore
- * @param pkey private key of the zone
- * @param label name that is being mapped
- * @param rd_count number of records in the 'rd' array
- * @param rd array of records with data to store
- * @param cont continuation to call when done
+ * @param cont function to call on result
  * @param cont_cls closure for @a cont
  * @return handle to abort the request
  */
 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);
+GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h,
+                                     GNUNET_NAMESTORE_ContinuationWithStatus
+                                     cont,
+                                     void *cont_cls);
 
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index dc66a0401..509c97fb2 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -3603,6 +3603,28 @@ extern "C" {
 
 
/*********************************************************************************/
 
+/*********************************************************************************/
+/**********************************  NAMESTORE (cont.)  
**************************/
+/*********************************************************************************/
+/* NAMESTORE: message types 1750-1800
+ */
+
+/**
+ * Message type for Begin, Commit or Rollback
+ */
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL 1750
+
+/**
+ * Return status message for control message
+ */
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT 1751
+
+/**
+ * Open and lock records for editing message
+ */
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_EDIT 1752
+
+
 /**
  * Type used to match 'all' message types.
  */
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index 51708dd67..32f2605ca 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -15,26 +15,6 @@ if USE_COVERAGE
   XLIBS = -lgcov
 endif
 
-HEAP_PLUGIN = libgnunet_plugin_namestore_flat.la
-HEAP_TESTS = test_plugin_namestore_flat \
- test_namestore_api_store_flat \
- test_namestore_api_store_update_flat \
- test_namestore_api_remove_flat \
- test_namestore_api_zone_iteration_flat \
- test_namestore_api_lookup_nick_flat \
- test_namestore_api_monitoring_flat \
- test_namestore_api_lookup_public_flat \
- test_namestore_api_lookup_private_flat \
- test_namestore_api_lookup_shadow_flat \
- test_namestore_api_lookup_shadow_filter_flat \
- test_namestore_api_remove_not_existing_record_flat \
- test_namestore_api_zone_iteration_nick_flat \
- test_namestore_api_zone_iteration_specific_zone_flat \
- test_namestore_api_zone_iteration_stop_flat \
- test_namestore_api_monitoring_existing_flat \
- test_namestore_api_zone_to_name_flat \
- perf_namestore_api_zone_iteration_flat
-
 if HAVE_SQLITE
 SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la
 SQLITE_TESTS = test_plugin_namestore_sqlite \
@@ -54,7 +34,8 @@ SQLITE_TESTS = test_plugin_namestore_sqlite \
  test_namestore_api_zone_iteration_stop_sqlite \
  test_namestore_api_monitoring_existing_sqlite \
  test_namestore_api_zone_to_name_sqlite \
- perf_namestore_api_zone_iteration_sqlite
+ perf_namestore_api_zone_iteration_sqlite \
+ test_namestore_api_tx_rollback_sqlite
 endif
 
 if HAVE_POSTGRESQL
@@ -76,14 +57,14 @@ POSTGRES_TESTS = test_plugin_namestore_postgres \
  test_namestore_api_zone_iteration_stop_postgres \
  test_namestore_api_monitoring_existing_postgres \
  test_namestore_api_zone_to_name_postgres \
- perf_namestore_api_zone_iteration_postgres
+ perf_namestore_api_zone_iteration_postgres \
+ test_namestore_api_tx_rollback_postgres
 endif
 
 if HAVE_SQLITE
 check_PROGRAMS = \
  $(SQLITE_TESTS) \
- $(POSTGRES_TESTS) \
- $(HEAP_TESTS)
+ $(POSTGRES_TESTS)
 endif
 
 if ENABLE_TEST_RUN
@@ -113,7 +94,6 @@ libexec_PROGRAMS += \
 plugin_LTLIBRARIES = \
   $(SQLITE_PLUGIN) \
   $(POSTGRES_PLUGIN) \
-  $(HEAP_PLUGIN) \
   $(REST_PLUGIN)
 
 
@@ -195,18 +175,6 @@ gnunet_service_namestore_LDADD = \
 
 
 
-libgnunet_plugin_namestore_flat_la_SOURCES = \
-  plugin_namestore_flat.c
-libgnunet_plugin_namestore_flat_la_LIBADD = \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/statistics/libgnunetstatistics.la \
-  $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
-  $(LTLIBINTL)
-libgnunet_plugin_namestore_flat_la_LDFLAGS = \
- $(GN_PLUGIN_LDFLAGS)
-
-
 libgnunet_plugin_namestore_sqlite_la_SOURCES = \
   plugin_namestore_sqlite.c
 libgnunet_plugin_namestore_sqlite_la_LIBADD = \
@@ -231,15 +199,6 @@ libgnunet_plugin_namestore_postgres_la_LIBADD = \
 libgnunet_plugin_namestore_postgres_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS) $(POSTGRESQL_LDFLAGS)
 
-test_namestore_api_store_flat_SOURCES = \
- test_namestore_api_store.c
-test_namestore_api_store_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  libgnunetnamestore.la
-
 test_namestore_api_store_sqlite_SOURCES = \
  test_namestore_api_store.c
 test_namestore_api_store_sqlite_LDADD = \
@@ -258,16 +217,6 @@ test_namestore_api_store_postgres_LDADD = \
   $(top_builddir)/src/identity/libgnunetidentity.la \
   libgnunetnamestore.la
 
-test_namestore_api_store_update_flat_SOURCES = \
- test_namestore_api_store_update.c
-test_namestore_api_store_update_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/namecache/libgnunetnamecache.la \
-  libgnunetnamestore.la
-
 test_namestore_api_store_update_sqlite_SOURCES = \
  test_namestore_api_store_update.c
 test_namestore_api_store_update_sqlite_LDADD = \
@@ -288,16 +237,6 @@ test_namestore_api_store_update_postgres_LDADD = \
   $(top_builddir)/src/namecache/libgnunetnamecache.la \
   libgnunetnamestore.la
 
-test_namestore_api_lookup_public_flat_SOURCES = \
- test_namestore_api_lookup_public.c
-test_namestore_api_lookup_public_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/namecache/libgnunetnamecache.la \
-  libgnunetnamestore.la
-
 test_namestore_api_lookup_public_sqlite_SOURCES = \
  test_namestore_api_lookup_public.c
 test_namestore_api_lookup_public_sqlite_LDADD = \
@@ -338,26 +277,6 @@ test_namestore_api_lookup_nick_postgres_LDADD = \
   $(top_builddir)/src/namecache/libgnunetnamecache.la \
   libgnunetnamestore.la
 
-test_namestore_api_lookup_nick_flat_SOURCES = \
- test_namestore_api_lookup_nick.c
-test_namestore_api_lookup_nick_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/namecache/libgnunetnamecache.la \
-  libgnunetnamestore.la
-
-test_namestore_api_lookup_private_flat_SOURCES = \
- test_namestore_api_lookup_private.c
-test_namestore_api_lookup_private_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/namecache/libgnunetnamecache.la \
-  libgnunetnamestore.la
-
 test_namestore_api_lookup_private_sqlite_SOURCES = \
  test_namestore_api_lookup_private.c
 test_namestore_api_lookup_private_sqlite_LDADD = \
@@ -378,16 +297,6 @@ test_namestore_api_lookup_private_postgres_LDADD = \
   $(top_builddir)/src/namecache/libgnunetnamecache.la \
   libgnunetnamestore.la
 
-test_namestore_api_lookup_shadow_flat_SOURCES = \
- test_namestore_api_lookup_shadow.c
-test_namestore_api_lookup_shadow_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/namecache/libgnunetnamecache.la \
-  libgnunetnamestore.la
-
 test_namestore_api_lookup_shadow_sqlite_SOURCES = \
  test_namestore_api_lookup_shadow.c
 test_namestore_api_lookup_shadow_sqlite_LDADD = \
@@ -408,16 +317,6 @@ test_namestore_api_lookup_shadow_postgres_LDADD = \
   $(top_builddir)/src/namecache/libgnunetnamecache.la \
   libgnunetnamestore.la
 
-test_namestore_api_lookup_shadow_filter_flat_SOURCES = \
- test_namestore_api_lookup_shadow_filter.c
-test_namestore_api_lookup_shadow_filter_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/namecache/libgnunetnamecache.la \
-  libgnunetnamestore.la
-
 test_namestore_api_lookup_shadow_filter_sqlite_SOURCES = \
  test_namestore_api_lookup_shadow_filter.c
 test_namestore_api_lookup_shadow_filter_sqlite_LDADD = \
@@ -455,24 +354,6 @@ test_namestore_api_remove_postgres_LDADD = \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   libgnunetnamestore.la
 
-test_namestore_api_remove_flat_SOURCES = \
- test_namestore_api_remove.c
-test_namestore_api_remove_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  libgnunetnamestore.la
-
-test_namestore_api_remove_not_existing_record_flat_SOURCES = \
- test_namestore_api_remove_not_existing_record.c
-test_namestore_api_remove_not_existing_record_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  libgnunetnamestore.la
-
 test_namestore_api_remove_not_existing_record_sqlite_SOURCES = \
  test_namestore_api_remove_not_existing_record.c
 test_namestore_api_remove_not_existing_record_sqlite_LDADD = \
@@ -491,14 +372,6 @@ 
test_namestore_api_remove_not_existing_record_postgres_LDADD = \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   libgnunetnamestore.la
 
-test_namestore_api_zone_to_name_flat_SOURCES = \
- test_namestore_api_zone_to_name.c
-test_namestore_api_zone_to_name_flat_LDADD = \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  libgnunetnamestore.la
-
 test_namestore_api_zone_to_name_sqlite_SOURCES = \
  test_namestore_api_zone_to_name.c
 test_namestore_api_zone_to_name_sqlite_LDADD = \
@@ -515,15 +388,6 @@ test_namestore_api_zone_to_name_postgres_LDADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
   libgnunetnamestore.la
 
-test_namestore_api_monitoring_flat_SOURCES = \
- test_namestore_api_monitoring.c
-test_namestore_api_monitoring_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  libgnunetnamestore.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  $(top_builddir)/src/util/libgnunetutil.la
-
 test_namestore_api_monitoring_sqlite_SOURCES = \
  test_namestore_api_monitoring.c
 test_namestore_api_monitoring_sqlite_LDADD = \
@@ -542,15 +406,6 @@ test_namestore_api_monitoring_postgres_LDADD = \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   $(top_builddir)/src/util/libgnunetutil.la
 
-test_namestore_api_monitoring_existing_flat_SOURCES = \
- test_namestore_api_monitoring_existing.c
-test_namestore_api_monitoring_existing_flat_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_monitoring_existing_sqlite_SOURCES = \
  test_namestore_api_monitoring_existing.c
 test_namestore_api_monitoring_existing_sqlite_LDADD = \
@@ -569,14 +424,25 @@ test_namestore_api_monitoring_existing_postgres_LDADD = \
   $(top_builddir)/src/identity/libgnunetidentity.la \
   $(top_builddir)/src/util/libgnunetutil.la
 
-test_namestore_api_zone_iteration_flat_SOURCES = \
- test_namestore_api_zone_iteration.c
-test_namestore_api_zone_iteration_flat_LDADD = \
+test_namestore_api_tx_rollback_sqlite_SOURCES = \
+ test_namestore_api_tx_rollback.c
+test_namestore_api_tx_rollback_sqlite_LDADD = \
   $(top_builddir)/src/testing/libgnunettesting.la \
   $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
+  libgnunetnamestore.la \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  libgnunetnamestore.la
+  $(top_builddir)/src/util/libgnunetutil.la
+
+test_namestore_api_tx_rollback_postgres_SOURCES = \
+ test_namestore_api_tx_rollback.c
+test_namestore_api_tx_rollback_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
@@ -614,24 +480,6 @@ perf_namestore_api_zone_iteration_sqlite_LDADD = \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   libgnunetnamestore.la
 
-perf_namestore_api_zone_iteration_flat_SOURCES = \
- perf_namestore_api_zone_iteration.c
-perf_namestore_api_zone_iteration_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  libgnunetnamestore.la
-
-test_namestore_api_zone_iteration_nick_flat_SOURCES = \
- test_namestore_api_zone_iteration_nick.c
-test_namestore_api_zone_iteration_nick_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  libgnunetnamestore.la
-
 test_namestore_api_zone_iteration_nick_sqlite_SOURCES = \
  test_namestore_api_zone_iteration_nick.c
 test_namestore_api_zone_iteration_nick_sqlite_LDADD = \
@@ -650,15 +498,6 @@ test_namestore_api_zone_iteration_nick_postgres_LDADD = \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   libgnunetnamestore.la
 
-test_namestore_api_zone_iteration_specific_zone_flat_SOURCES = \
- test_namestore_api_zone_iteration_specific_zone.c
-test_namestore_api_zone_iteration_specific_zone_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  libgnunetnamestore.la
-
 test_namestore_api_zone_iteration_specific_zone_sqlite_SOURCES = \
  test_namestore_api_zone_iteration_specific_zone.c
 test_namestore_api_zone_iteration_specific_zone_sqlite_LDADD = \
@@ -677,15 +516,6 @@ 
test_namestore_api_zone_iteration_specific_zone_postgres_LDADD = \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   libgnunetnamestore.la
 
-test_namestore_api_zone_iteration_stop_flat_SOURCES = \
- test_namestore_api_zone_iteration_stop.c
-test_namestore_api_zone_iteration_stop_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
-  libgnunetnamestore.la
-
 test_namestore_api_zone_iteration_stop_sqlite_SOURCES = \
  test_namestore_api_zone_iteration_stop.c
 test_namestore_api_zone_iteration_stop_sqlite_LDADD = \
@@ -704,13 +534,6 @@ test_namestore_api_zone_iteration_stop_postgres_LDADD = \
   $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   libgnunetnamestore.la
 
-test_plugin_namestore_flat_SOURCES = \
- test_plugin_namestore.c
-test_plugin_namestore_flat_LDADD = \
-  $(top_builddir)/src/testing/libgnunettesting.la \
-  $(top_builddir)/src/identity/libgnunetidentity.la \
-  $(top_builddir)/src/util/libgnunetutil.la
-
 test_plugin_namestore_sqlite_SOURCES = \
  test_plugin_namestore.c
 test_plugin_namestore_sqlite_LDADD = \
@@ -738,12 +561,9 @@ EXTRA_DIST = \
   test_namestore_api.conf \
   test_namestore_api_postgres.conf \
   test_namestore_api_sqlite.conf \
-  test_namestore_api_flat.conf \
   perf_namestore_api_postgres.conf \
   perf_namestore_api_sqlite.conf \
-  perf_namestore_api_flat.conf \
   test_plugin_namestore_sqlite.conf \
   test_plugin_namestore_postgres.conf \
-  test_plugin_namestore_flat.conf \
   test_hostkey \
   $(check_SCRIPTS)
diff --git a/src/namestore/gnunet-service-namestore.c 
b/src/namestore/gnunet-service-namestore.c
index 6d3cc45ec..1f621c5f0 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -131,6 +131,11 @@ struct NamestoreClient
    */
   struct GNUNET_SERVICE_Client *client;
 
+  /**
+   * Database handle
+   */
+  struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
+
   /**
    * Message queue for transmission to @e client
    */
@@ -352,11 +357,6 @@ static struct GNUNET_STATISTICS_Handle *statistics;
  */
 static struct GNUNET_NAMECACHE_Handle *namecache;
 
-/**
- * Database handle
- */
-static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
-
 /**
  * Name of the database plugin
  */
@@ -436,7 +436,6 @@ cleanup_task (void *cls)
     GNUNET_NAMECACHE_disconnect (namecache);
     namecache = NULL;
   }
-  GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
   GNUNET_free (db_lib_name);
   db_lib_name = NULL;
   if (NULL != monitor_nc)
@@ -560,11 +559,13 @@ cache_nick (const struct GNUNET_IDENTITY_PrivateKey *zone,
 /**
  * Return the NICK record for the zone (if it exists).
  *
+ * @param nc the namestore client
  * @param zone private key for the zone to look for nick
  * @return NULL if no NICK record was found
  */
 static struct GNUNET_GNSRECORD_Data *
-get_nick_record (const struct GNUNET_IDENTITY_PrivateKey *zone)
+get_nick_record (const struct NamestoreClient *nc,
+                 const struct GNUNET_IDENTITY_PrivateKey *zone)
 {
   struct GNUNET_IDENTITY_PublicKey pub;
   struct GNUNET_GNSRECORD_Data *nick;
@@ -588,11 +589,11 @@ get_nick_record (const struct GNUNET_IDENTITY_PrivateKey 
*zone)
   }
 
   nick = NULL;
-  res = GSN_database->lookup_records (GSN_database->cls,
-                                      zone,
-                                      GNUNET_GNS_EMPTY_LABEL_AT,
-                                      &lookup_nick_it,
-                                      &nick);
+  res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
+                                          zone,
+                                          GNUNET_GNS_EMPTY_LABEL_AT,
+                                          &lookup_nick_it,
+                                          &nick);
   if ((GNUNET_OK != res) || (NULL == nick))
   {
 #if ! defined(GNUNET_CULL_LOGGING)
@@ -735,7 +736,7 @@ send_lookup_response (struct NamestoreClient *nc,
   char *name_tmp;
   char *rd_ser;
 
-  nick = get_nick_record (zone_key);
+  nick = get_nick_record (nc, zone_key);
   GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (rd_count, rd));
 
   if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
@@ -936,7 +937,7 @@ refresh_block (struct NamestoreClient *nc,
     rd_clean[rd_count_clean++] = rd[i];
   }
 
-  nick = get_nick_record (zone_key);
+  nick = get_nick_record (nc, zone_key);
   res_count = rd_count_clean;
   res = (struct GNUNET_GNSRECORD_Data *) rd_clean;  /* fixme: a bit unclean... 
*/
   if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
@@ -1168,6 +1169,7 @@ client_disconnect_cb (void *cls,
   for (cop = cop_head; NULL != cop; cop = cop->next)
     if (nc == cop->nc)
       cop->nc = NULL;
+  GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, nc->GSN_database));
   GNUNET_free (nc);
 }
 
@@ -1186,12 +1188,35 @@ client_connect_cb (void *cls,
                    struct GNUNET_MQ_Handle *mq)
 {
   struct NamestoreClient *nc;
+  char *database;
+  char *db_lib_name;
 
   (void) cls;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
   nc = GNUNET_new (struct NamestoreClient);
   nc->client = client;
   nc->mq = mq;
+  /* Loading database plugin */
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (GSN_cfg,
+                                                          "namestore",
+                                                          "database",
+                                                          &database))
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
+  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Loading %s\n", db_lib_name);
+  nc->GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
+  GNUNET_free (database);
+  if (NULL == nc->GSN_database)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Could not load database backend `%s'\n",
+                db_lib_name);
+    GNUNET_free (db_lib_name);
+    GNUNET_free (nc);
+    return NULL;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Loaded %s\n", db_lib_name);
+  GNUNET_free (db_lib_name);
   return nc;
 }
 
@@ -1402,12 +1427,12 @@ handle_record_lookup (void *cls, const struct 
LabelLookupMessage *ll_msg)
   rlc.res_rd_count = 0;
   rlc.res_rd = NULL;
   rlc.rd_ser_len = 0;
-  rlc.nick = get_nick_record (&ll_msg->zone);
-  res = GSN_database->lookup_records (GSN_database->cls,
-                                      &ll_msg->zone,
-                                      conv_name,
-                                      &lookup_it,
-                                      &rlc);
+  rlc.nick = get_nick_record (nc, &ll_msg->zone);
+  res = nc->GSN_database->lookup_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,
@@ -1591,11 +1616,11 @@ handle_record_store (void *cls, const struct 
RecordStoreMessage *rp_msg)
                 "Creating %u records for name `%s'\n",
                 (unsigned int) rd_count,
                 conv_name);
-    if ((GNUNET_NO == GSN_database->lookup_records (GSN_database->cls,
-                                                    &rp_msg->private_key,
-                                                    conv_name,
-                                                    &get_block_exp_existing,
-                                                    &existing_block_exp)) &&
+    if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls,
+                                                        &rp_msg->private_key,
+                                                        conv_name,
+                                                        
&get_block_exp_existing,
+                                                        &existing_block_exp)) 
&&
         (rd_count == 0))
     {
       /* This name does not exist, so cannot be removed */
@@ -1676,11 +1701,11 @@ handle_record_store (void *cls, const struct 
RecordStoreMessage *rp_msg)
         /* remove nick record from cache, in case we have one there */
         cache_nick (&rp_msg->private_key, NULL);
       }
-      res = GSN_database->store_records (GSN_database->cls,
-                                         &rp_msg->private_key,
-                                         conv_name,
-                                         rd_nf_count,
-                                         rd_nf);
+      res = nc->GSN_database->store_records (nc->GSN_database->cls,
+                                             &rp_msg->private_key,
+                                             conv_name,
+                                             rd_nf_count,
+                                             rd_nf);
     }
 
     if (GNUNET_OK != res)
@@ -1703,6 +1728,57 @@ handle_record_store (void *cls, const struct 
RecordStoreMessage *rp_msg)
   }
 }
 
+/**
+ * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL message
+ *
+ * @param cls client sending the message
+ * @param tx_msg message of type `struct TxControlMessage`
+ */
+static void
+handle_tx_control (void *cls, const struct TxControlMessage *tx_msg)
+{
+  struct NamestoreClient *nc = cls;
+  struct TxControlResultMessage *txr_msg;
+  struct GNUNET_MQ_Envelope *env;
+  enum GNUNET_GenericReturnValue ret;
+  char *emsg;
+  char *err_tmp;
+  size_t err_len;
+
+  switch (ntohs (tx_msg->control))
+  {
+  case GNUNET_NAMESTORE_TX_BEGIN:
+    ret = nc->GSN_database->transaction_begin (nc->GSN_database->cls,
+                                               &emsg);
+    break;
+  case GNUNET_NAMESTORE_TX_COMMIT:
+    ret = nc->GSN_database->transaction_commit (nc->GSN_database->cls,
+                                                &emsg);
+    break;
+  case GNUNET_NAMESTORE_TX_ROLLBACK:
+    ret = nc->GSN_database->transaction_rollback (nc->GSN_database->cls,
+                                                  &emsg);
+    break;
+  default:
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Unknown control type %u\n", ntohs (tx_msg->control));
+    GNUNET_break (0);
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "TX status is %u\n", ret);
+  err_len = (GNUNET_YES == ret) ? 0 : strlen (emsg) + 1;
+  env =
+    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.r_id = tx_msg->gns_header.r_id;
+  txr_msg->success = htons (ret);
+  err_tmp = (char *) &txr_msg[1];
+  GNUNET_memcpy (err_tmp, emsg, err_len);
+  GNUNET_MQ_send (nc->mq, env);
+  GNUNET_SERVICE_client_continue (nc->client);
+}
 
 /**
  * Context for record remove operations passed from #handle_zone_to_name to
@@ -1817,11 +1893,11 @@ handle_zone_to_name (void *cls, const struct 
ZoneToNameMessage *ztn_msg)
   ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
   ztn_ctx.nc = nc;
   ztn_ctx.success = GNUNET_NO;
-  if (GNUNET_SYSERR == GSN_database->zone_to_name (GSN_database->cls,
-                                                   &ztn_msg->zone,
-                                                   &ztn_msg->value_zone,
-                                                   &handle_zone_to_name_it,
-                                                   &ztn_ctx))
+  if (GNUNET_SYSERR == nc->GSN_database->zone_to_name (nc->GSN_database->cls,
+                                                       &ztn_msg->zone,
+                                                       &ztn_msg->value_zone,
+                                                       &handle_zone_to_name_it,
+                                                       &ztn_ctx))
   {
     /* internal error, hang up instead of signalling something
        that might be wrong */
@@ -1935,6 +2011,7 @@ run_zone_iteration_round (struct ZoneIteration *zi, 
uint64_t limit)
   struct ZoneIterationProcResult proc;
   struct GNUNET_TIME_Absolute start;
   struct GNUNET_TIME_Relative duration;
+  struct NamestoreClient *nc = zi->nc;
 
   memset (&proc, 0, sizeof(proc));
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1945,15 +2022,16 @@ run_zone_iteration_round (struct ZoneIteration *zi, 
uint64_t limit)
   proc.limit = limit;
   start = GNUNET_TIME_absolute_get ();
   GNUNET_break (GNUNET_SYSERR !=
-                GSN_database->iterate_records (GSN_database->cls,
-                                               (GNUNET_YES == GNUNET_is_zero (
-                                                  &zi->zone))
+                nc->GSN_database->iterate_records (nc->GSN_database->cls,
+                                                   (GNUNET_YES ==
+                                                    GNUNET_is_zero (
+                                                      &zi->zone))
                                                ? NULL
                                                : &zi->zone,
-                                               zi->seq,
-                                               limit,
-                                               &zone_iterate_proc,
-                                               &proc));
+                                                   zi->seq,
+                                                   limit,
+                                                   &zone_iterate_proc,
+                                                   &proc));
   duration = GNUNET_TIME_absolute_get_duration (start);
   duration = GNUNET_TIME_relative_divide (duration, limit - proc.limit);
   GNUNET_STATISTICS_set (statistics,
@@ -2212,6 +2290,7 @@ static void
 monitor_iteration_next (void *cls)
 {
   struct ZoneMonitor *zm = cls;
+  struct NamestoreClient *nc = zm->nc;
   int ret;
 
   zm->task = NULL;
@@ -2220,15 +2299,13 @@ monitor_iteration_next (void *cls)
     zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
   else
     zm->iteration_cnt = zm->limit; /* use it all */
-  ret = GSN_database->iterate_records (GSN_database->cls,
-                                       (GNUNET_YES == GNUNET_is_zero (
-                                          &zm->zone))
-                                       ? NULL
-                                       : &zm->zone,
-                                       zm->seq,
-                                       zm->iteration_cnt,
-                                       &monitor_iterate_cb,
-                                       zm);
+  ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
+                                           (GNUNET_YES == GNUNET_is_zero (
+                                              &zm->zone)) ? NULL : &zm->zone,
+                                           zm->seq,
+                                           zm->iteration_cnt,
+                                           &monitor_iterate_cb,
+                                           zm);
   if (GNUNET_SYSERR == ret)
   {
     GNUNET_SERVICE_client_drop (zm->nc->client);
@@ -2330,26 +2407,8 @@ run (void *cls,
     namecache = GNUNET_NAMECACHE_connect (cfg);
     GNUNET_assert (NULL != namecache);
   }
-  /* Loading database plugin */
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
-                                                          "namestore",
-                                                          "database",
-                                                          &database))
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
-
-  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
-  GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
-  GNUNET_free (database);
   statistics = GNUNET_STATISTICS_create ("namestore", cfg);
   GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL);
-  if (NULL == GSN_database)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Could not load database backend `%s'\n",
-                db_lib_name);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
 }
 
 
@@ -2363,6 +2422,10 @@ GNUNET_SERVICE_MAIN (
   &client_connect_cb,
   &client_disconnect_cb,
   NULL,
+  GNUNET_MQ_hd_fixed_size (tx_control,
+                           GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL,
+                           struct TxControlMessage,
+                           NULL),
   GNUNET_MQ_hd_var_size (record_store,
                          GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE,
                          struct RecordStoreMessage,
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index 583ec1e68..06feee13a 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -305,6 +305,54 @@ struct RecordResultMessage
    */
 };
 
+/**
+ * Send a transaction control message.
+ */
+struct TxControlMessage
+{
+  /**
+   * Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL
+   */
+  struct GNUNET_NAMESTORE_Header gns_header;
+
+  /**
+   * The type of control message to send
+   */
+  uint16_t control GNUNET_PACKED;
+
+  /**
+   * always zero (for alignment)
+   */
+  uint16_t reserved GNUNET_PACKED;
+
+};
+
+/**
+ * Result of a transaction control message.
+ */
+struct TxControlResultMessage
+{
+  /**
+   * Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT
+   */
+  struct GNUNET_NAMESTORE_Header gns_header;
+
+  /**
+   * The type of control message to send
+   */
+  uint16_t control GNUNET_PACKED;
+
+  /**
+   * Of type GNUNET_GenericReturnValue
+   */
+  uint16_t success GNUNET_PACKED;
+
+  /* followed by:
+   * an error message if status != ntohs(GNUNET_OK)
+   */
+};
+
+
 
 /**
  * Start monitoring a zone.
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index 73f985803..26e1477f4 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -674,6 +674,60 @@ handle_record_result_end (void *cls, const struct 
GNUNET_NAMESTORE_Header *msg)
   free_ze (ze);
 }
 
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT.
+ *
+ * @param qe the respective entry in the message queue
+ * @param msg the message we received
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if message malformed
+ */
+static int
+check_tx_control_result (void *cls,
+                         const struct TxControlResultMessage *msg)
+{
+  const char *err_tmp;
+  size_t err_len;
+
+  (void) cls;
+  err_len = ntohs (msg->gns_header.header.size)
+            - sizeof (struct TxControlResultMessage);
+  if ((GNUNET_YES == ntohs (msg->success)) && (err_len > 0))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  err_tmp = (const char *) &msg[1];
+  if ((err_len > 0) && ('\0' != err_tmp[err_len - 1]))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+static void
+handle_tx_control_result (void *cls,
+                          const struct TxControlResultMessage *msg)
+{
+  struct GNUNET_NAMESTORE_Handle *h = cls;
+  struct GNUNET_NAMESTORE_QueueEntry *qe;
+  int res;
+  const char *emsg;
+
+  qe = find_qe (h, ntohl (msg->gns_header.r_id));
+  emsg = (const char *) &msg[1];
+  res = ntohs (msg->success);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Received TX_CONTROL_RESULT with result %d\n",
+       res);
+  if (NULL == qe)
+    return;
+  if (NULL != qe->cont)
+    qe->cont (qe->cont_cls, res,
+              (GNUNET_YES == res) ? NULL : emsg);
+  free_qe (qe);
+}
 
 /**
  * Handle an incoming message of type
@@ -839,6 +893,10 @@ reconnect (struct GNUNET_NAMESTORE_Handle *h)
                            
GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE,
                            struct LabelLookupResponseMessage,
                            h),
+    GNUNET_MQ_hd_var_size (tx_control_result,
+                           GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT,
+                           struct TxControlResultMessage,
+                           h),
     GNUNET_MQ_handler_end () };
   struct GNUNET_NAMESTORE_ZoneIterator *it;
   struct GNUNET_NAMESTORE_QueueEntry *qe;
@@ -1344,43 +1402,65 @@ GNUNET_NAMESTORE_cancel (struct 
GNUNET_NAMESTORE_QueueEntry *qe)
  * New API draft. Experimental
  */
 
-struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h,
-                                    GNUNET_SCHEDULER_TaskCallback error_cb,
-                                    void *error_cb_cls)
+static struct GNUNET_NAMESTORE_QueueEntry *
+send_transaction_control_msg (struct GNUNET_NAMESTORE_Handle *h,
+                              GNUNET_NAMESTORE_ContinuationWithStatus cont,
+                              void *cont_cls,
+                              enum GNUNET_NAMESTORE_TxControl ctrl)
 {
+  struct GNUNET_NAMESTORE_QueueEntry *qe;
+  struct GNUNET_MQ_Envelope *env;
+  struct TxControlMessage *msg;
+  uint32_t rid;
+
+  rid = get_op_id (h);
+  qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
+  qe->h = h;
+  qe->cont = cont;
+  qe->cont_cls = cont_cls;
+  qe->op_id = rid;
+  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
+
+  env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL);
+  msg->gns_header.r_id = htonl (rid);
+  msg->control = htons (ctrl);
+  if (NULL == h->mq)
+    qe->env = env;
+  else
+    GNUNET_MQ_send (h->mq, env);
+  return qe;
   GNUNET_break (0);
   return NULL;
 }
 
+struct GNUNET_NAMESTORE_QueueEntry *
+GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h,
+                                    GNUNET_NAMESTORE_ContinuationWithStatus 
cont,
+                                    void *cont_cls)
+{
+  return send_transaction_control_msg (h, cont, cont_cls,
+                                       GNUNET_NAMESTORE_TX_BEGIN);
+}
 
 struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_transaction_abort (struct GNUNET_NAMESTORE_Handle *h,
-                                    GNUNET_SCHEDULER_TaskCallback error_cb,
-                                    void *error_cb_cls)
+GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h,
+                                     GNUNET_NAMESTORE_ContinuationWithStatus
+                                     cont,
+                                     void *cont_cls)
 {
-  GNUNET_break (0);
-  return NULL;
+  return send_transaction_control_msg (h, cont, cont_cls,
+                                       GNUNET_NAMESTORE_TX_COMMIT);
 }
 
 
-/**
- * Commit a namestore transaction.
- * Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin
- *
- * @param h handle to the namestore
- * @param error_cb function to call on error (i.e. disconnect or unable to get 
lock)
- *        the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
- * @return handle to abort the request
- */
 struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h,
-                                     GNUNET_SCHEDULER_TaskCallback error_cb,
-                                     void *error_cb_cls)
+GNUNET_NAMESTORE_transaction_rollback (struct GNUNET_NAMESTORE_Handle *h,
+                                       GNUNET_NAMESTORE_ContinuationWithStatus
+                                       cont,
+                                       void *cont_cls)
 {
-  GNUNET_break (0);
-  return NULL;
+  return send_transaction_control_msg (h, cont, cont_cls,
+                                       GNUNET_NAMESTORE_TX_ROLLBACK);
 }
 
 
diff --git a/src/namestore/perf_namestore_api_flat.conf 
b/src/namestore/perf_namestore_api_flat.conf
deleted file mode 100644
index 30759ce7a..000000000
--- a/src/namestore/perf_namestore_api_flat.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-@INLINE@ test_namestore_api.conf
-
-[namestore]
-DATABASE = flat
-
-[namecache]
-DISABLE = YES
-
-[namestore-heap]
-FILENAME = $GNUNET_TEST_HOME/namestore/heap.db
diff --git a/src/namestore/plugin_namestore_flat.c 
b/src/namestore/plugin_namestore_flat.c
deleted file mode 100644
index 3576b14e0..000000000
--- a/src/namestore/plugin_namestore_flat.c
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * This file is part of GNUnet
- * Copyright (C) 2009-2015, 2018, 2019 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/plugin_namestore_flat.c
- * @brief file-based namestore backend
- * @author Martin Schanzenbach
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include "gnunet_namestore_plugin.h"
-#include "gnunet_namestore_service.h"
-#include "gnunet_gnsrecord_lib.h"
-#include "namestore.h"
-
-/**
- * Context for all functions in this plugin.
- */
-struct Plugin
-{
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Database filename.
-   */
-  char *fn;
-
-  /**
-   * HashMap
-   */
-  struct GNUNET_CONTAINER_MultiHashMap *hm;
-};
-
-
-struct FlatFileEntry
-{
-  /**
-   * Entry zone
-   */
-  struct GNUNET_IDENTITY_PrivateKey private_key;
-
-  /**
-   * Record count.
-   */
-  uint32_t record_count;
-
-  /**
-   * Rvalue
-   */
-  uint64_t rvalue;
-
-  /**
-   * Record data
-   */
-  struct GNUNET_GNSRECORD_Data *record_data;
-
-  /**
-   * Label
-   */
-  char *label;
-};
-
-
-/**
- * Hash contactenation of @a pkey and @a label into @a h
- *
- * @param pkey a key
- * @param label a label
- * @param h[out] initialized hash
- */
-static void
-hash_pkey_and_label (const struct GNUNET_IDENTITY_PrivateKey *pkey,
-                     const char *label,
-                     struct GNUNET_HashCode *h)
-{
-  char *key;
-  size_t label_len;
-  size_t key_len;
-
-  label_len = strlen (label);
-  key_len = label_len + sizeof(struct GNUNET_IDENTITY_PrivateKey);
-  key = GNUNET_malloc (key_len);
-  GNUNET_memcpy (key,
-                 label,
-                 label_len);
-  GNUNET_memcpy (key + label_len,
-                 pkey,
-                 sizeof(struct GNUNET_IDENTITY_PrivateKey));
-  GNUNET_CRYPTO_hash (key,
-                      key_len,
-                      h);
-  GNUNET_free (key);
-}
-
-
-/**
- * Initialize the database connections and associated
- * data structures (create tables and indices
- * as needed as well).
- *
- * @param plugin the plugin context (state for this module)
- * @return #GNUNET_OK on success
- */
-static int
-database_setup (struct Plugin *plugin)
-{
-  char *flatdbfile;
-  char *record_data;
-  char *zone_private_key;
-  char *record_data_b64;
-  char *buffer;
-  char *line;
-  char *label;
-  char *rvalue;
-  char *record_count;
-  size_t record_data_size;
-  uint64_t size;
-  struct GNUNET_HashCode hkey;
-  struct GNUNET_DISK_FileHandle *fh;
-  struct FlatFileEntry *entry;
-  struct GNUNET_DISK_MapHandle *mh;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg,
-                                               "namestore-flat",
-                                               "FILENAME",
-                                               &flatdbfile))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "namestore-flat",
-                               "FILENAME");
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_OK !=
-      GNUNET_DISK_file_test (flatdbfile))
-  {
-    if (GNUNET_OK !=
-        GNUNET_DISK_directory_create_for_file (flatdbfile))
-    {
-      GNUNET_break (0);
-      GNUNET_free (flatdbfile);
-      return GNUNET_SYSERR;
-    }
-  }
-  /* flatdbfile should be UTF-8-encoded. If it isn't, it's a bug */
-  plugin->fn = flatdbfile;
-
-  /* Load data from file into hashmap */
-  plugin->hm = GNUNET_CONTAINER_multihashmap_create (10,
-                                                     GNUNET_NO);
-  fh = GNUNET_DISK_file_open (flatdbfile,
-                              GNUNET_DISK_OPEN_CREATE
-                              | GNUNET_DISK_OPEN_READWRITE,
-                              GNUNET_DISK_PERM_USER_WRITE
-                              | GNUNET_DISK_PERM_USER_READ);
-  if (NULL == fh)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Unable to initialize file: %s.\n"),
-                flatdbfile);
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_SYSERR ==
-      GNUNET_DISK_file_size (flatdbfile,
-                             &size,
-                             GNUNET_YES,
-                             GNUNET_YES))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Unable to get filesize: %s.\n"),
-                flatdbfile);
-    GNUNET_DISK_file_close (fh);
-    return GNUNET_SYSERR;
-  }
-  if (size > SIZE_MAX)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("File too big to map: %llu bytes.\n"),
-                (unsigned long long) size);
-    GNUNET_DISK_file_close (fh);
-    return GNUNET_SYSERR;
-  }
-  if (0 == size)
-  {
-    GNUNET_DISK_file_close (fh);
-    return GNUNET_OK;
-  }
-  buffer = GNUNET_DISK_file_map (fh,
-                                 &mh,
-                                 GNUNET_DISK_MAP_TYPE_READ,
-                                 size);
-  if (NULL == buffer)
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                         "mmap");
-    GNUNET_DISK_file_close (fh);
-    return GNUNET_SYSERR;
-  }
-  if ('\0' != buffer[size - 1])
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Namestore database file `%s' malformed\n"),
-                flatdbfile);
-    GNUNET_DISK_file_unmap (mh);
-    GNUNET_DISK_file_close (fh);
-    return GNUNET_SYSERR;
-  }
-
-  line = strtok (buffer, "\n");
-  while (NULL != line)
-  {
-    zone_private_key = strtok (line, ",");
-    if (NULL == zone_private_key)
-      break;
-    rvalue = strtok (NULL, ",");
-    if (NULL == rvalue)
-      break;
-    record_count = strtok (NULL, ",");
-    if (NULL == record_count)
-      break;
-    record_data_b64 = strtok (NULL, ",");
-    if (NULL == record_data_b64)
-      break;
-    label = strtok (NULL, ",");
-    if (NULL == label)
-      break;
-    line = strtok (NULL, "\n");
-    entry = GNUNET_new (struct FlatFileEntry);
-    {
-      unsigned long long ll;
-
-      if (1 != sscanf (rvalue,
-                       "%llu",
-                       &ll))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "Error parsing entry\n");
-        GNUNET_free (entry);
-        break;
-      }
-      entry->rvalue = (uint64_t) ll;
-    }
-    {
-      unsigned int ui;
-
-      if (1 != sscanf (record_count,
-                       "%u",
-                       &ui))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "Error parsing entry\n");
-        GNUNET_free (entry);
-        break;
-      }
-      entry->record_count = (uint32_t) ui;
-    }
-    entry->label = GNUNET_strdup (label);
-    record_data_size
-      = GNUNET_STRINGS_base64_decode (record_data_b64,
-                                      strlen (record_data_b64),
-                                      (void **) &record_data);
-    entry->record_data =
-      GNUNET_new_array (entry->record_count,
-                        struct GNUNET_GNSRECORD_Data);
-    if (GNUNET_OK !=
-        GNUNET_GNSRECORD_records_deserialize (record_data_size,
-                                              record_data,
-                                              entry->record_count,
-                                              entry->record_data))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Unable to deserialize record %s\n",
-                  label);
-      GNUNET_free (entry->label);
-      GNUNET_free (entry);
-      GNUNET_free (record_data);
-      break;
-    }
-    GNUNET_free (record_data);
-
-    {
-      struct GNUNET_IDENTITY_PrivateKey *private_key;
-
-      GNUNET_STRINGS_base64_decode (zone_private_key,
-                                    strlen (zone_private_key),
-                                    (void **) &private_key);
-      entry->private_key = *private_key;
-      GNUNET_free (private_key);
-    }
-
-    hash_pkey_and_label (&entry->private_key,
-                         label,
-                         &hkey);
-    if (GNUNET_OK !=
-        GNUNET_CONTAINER_multihashmap_put (plugin->hm,
-                                           &hkey,
-                                           entry,
-                                           
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
-    {
-      GNUNET_free (entry);
-      GNUNET_break (0);
-    }
-  }
-  GNUNET_DISK_file_unmap (mh);
-  GNUNET_DISK_file_close (fh);
-  return GNUNET_OK;
-}
-
-
-/**
- * Store values in hashmap in file and free data
- *
- * @param plugin the plugin context
- * @param key key in the map
- * @param value a `struct FlatFileEntry`
- */
-static int
-store_and_free_entries (void *cls,
-                        const struct GNUNET_HashCode *key,
-                        void *value)
-{
-  struct GNUNET_DISK_FileHandle *fh = cls;
-  struct FlatFileEntry *entry = value;
-  char *line;
-  char *zone_private_key;
-  char *record_data_b64;
-  ssize_t data_size;
-
-  (void) key;
-  GNUNET_STRINGS_base64_encode (&entry->private_key,
-                                sizeof(struct GNUNET_IDENTITY_PrivateKey),
-                                &zone_private_key);
-  data_size = GNUNET_GNSRECORD_records_get_size (entry->record_count,
-                                                 entry->record_data);
-  if (data_size < 0)
-  {
-    GNUNET_break (0);
-    GNUNET_free (zone_private_key);
-    return GNUNET_SYSERR;
-  }
-  if (data_size >= UINT16_MAX)
-  {
-    GNUNET_break (0);
-    GNUNET_free (zone_private_key);
-    return GNUNET_SYSERR;
-  }
-  {
-    char data[data_size];
-    ssize_t ret;
-
-    ret = GNUNET_GNSRECORD_records_serialize (entry->record_count,
-                                              entry->record_data,
-                                              data_size,
-                                              data);
-    if ((ret < 0) ||
-        (data_size != ret))
-    {
-      GNUNET_break (0);
-      GNUNET_free (zone_private_key);
-      return GNUNET_SYSERR;
-    }
-    GNUNET_STRINGS_base64_encode (data,
-                                  data_size,
-                                  &record_data_b64);
-  }
-  GNUNET_asprintf (&line,
-                   "%s,%llu,%u,%s,%s\n",
-                   zone_private_key,
-                   (unsigned long long) entry->rvalue,
-                   (unsigned int) entry->record_count,
-                   record_data_b64,
-                   entry->label);
-  GNUNET_free (record_data_b64);
-  GNUNET_free (zone_private_key);
-
-  GNUNET_DISK_file_write (fh,
-                          line,
-                          strlen (line));
-
-  GNUNET_free (line);
-  GNUNET_free (entry->label);
-  GNUNET_free (entry->record_data);
-  GNUNET_free (entry);
-  return GNUNET_YES;
-}
-
-
-/**
- * Shutdown database connection and associate data
- * structures.
- * @param plugin the plugin context (state for this module)
- */
-static void
-database_shutdown (struct Plugin *plugin)
-{
-  struct GNUNET_DISK_FileHandle *fh;
-
-  fh = GNUNET_DISK_file_open (plugin->fn,
-                              GNUNET_DISK_OPEN_CREATE
-                              | GNUNET_DISK_OPEN_TRUNCATE
-                              | GNUNET_DISK_OPEN_READWRITE,
-                              GNUNET_DISK_PERM_USER_WRITE
-                              | GNUNET_DISK_PERM_USER_READ);
-  if (NULL == fh)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _ ("Unable to initialize file: %s.\n"),
-                plugin->fn);
-    return;
-  }
-
-  GNUNET_CONTAINER_multihashmap_iterate (plugin->hm,
-                                         &store_and_free_entries,
-                                         fh);
-  GNUNET_CONTAINER_multihashmap_destroy (plugin->hm);
-  /* append 0-terminator */
-  GNUNET_DISK_file_write (fh,
-                          "",
-                          1);
-  GNUNET_DISK_file_close (fh);
-}
-
-
-/**
- * Store a record in the datastore.  Removes any existing record in the
- * same zone with the same name.
- *
- * @param cls closure (internal context for the plugin)
- * @param zone_key private key of the zone
- * @param label name that is being mapped (at most 255 characters long)
- * @param rd_count number of entries in @a rd array
- * @param rd array of records with data to store
- * @return #GNUNET_OK on success, else #GNUNET_SYSERR
- */
-static int
-namestore_flat_store_records (void *cls,
-                              const struct
-                              GNUNET_IDENTITY_PrivateKey *zone_key,
-                              const char *label,
-                              unsigned int rd_count,
-                              const struct GNUNET_GNSRECORD_Data *rd)
-{
-  struct Plugin *plugin = cls;
-  uint64_t rvalue;
-  struct GNUNET_HashCode hkey;
-  struct FlatFileEntry *entry;
-
-  rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
-                                     UINT64_MAX);
-  hash_pkey_and_label (zone_key,
-                       label,
-                       &hkey);
-  GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm,
-                                            &hkey);
-  if (0 == rd_count)
-  {
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
-                     "sqlite",
-                     "Record deleted\n");
-    return GNUNET_OK;
-  }
-  entry = GNUNET_new (struct FlatFileEntry);
-  GNUNET_asprintf (&entry->label,
-                   label,
-                   strlen (label));
-  GNUNET_memcpy (&entry->private_key,
-                 zone_key,
-                 sizeof(struct GNUNET_IDENTITY_PrivateKey));
-  entry->rvalue = rvalue;
-  entry->record_count = rd_count;
-  entry->record_data = GNUNET_new_array (rd_count,
-                                         struct GNUNET_GNSRECORD_Data);
-  for (unsigned int i = 0; i < rd_count; i++)
-  {
-    entry->record_data[i].expiration_time = rd[i].expiration_time;
-    entry->record_data[i].record_type = rd[i].record_type;
-    entry->record_data[i].flags = rd[i].flags;
-    entry->record_data[i].data_size = rd[i].data_size;
-    entry->record_data[i].data = GNUNET_malloc (rd[i].data_size);
-    GNUNET_memcpy ((char *) entry->record_data[i].data,
-                   rd[i].data,
-                   rd[i].data_size);
-  }
-  return GNUNET_CONTAINER_multihashmap_put (plugin->hm,
-                                            &hkey,
-                                            entry,
-                                            
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-}
-
-
-/**
- * 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_flat_lookup_records (void *cls,
-                               const struct GNUNET_IDENTITY_PrivateKey *zone,
-                               const char *label,
-                               GNUNET_NAMESTORE_RecordIterator iter,
-                               void *iter_cls)
-{
-  struct Plugin *plugin = cls;
-  struct FlatFileEntry *entry;
-  struct GNUNET_HashCode hkey;
-
-  if (NULL == zone)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  hash_pkey_and_label (zone,
-                       label,
-                       &hkey);
-  entry = GNUNET_CONTAINER_multihashmap_get (plugin->hm,
-                                             &hkey);
-
-  if (NULL == entry)
-    return GNUNET_NO;
-  if (NULL != iter)
-    iter (iter_cls,
-          1, /* zero is illegal */
-          &entry->private_key,
-          entry->label,
-          entry->record_count,
-          entry->record_data);
-  return GNUNET_YES;
-}
-
-
-/**
- * Closure for #iterate_zones.
- */
-struct IterateContext
-{
-  /**
-   * How many more records should we skip before returning results?
-   */
-  uint64_t offset;
-
-  /**
-   * How many more records should we return?
-   */
-  uint64_t limit;
-
-  /**
-   * What is the position of the current entry, counting
-   * starts from 1.
-   */
-  uint64_t pos;
-
-  /**
-   * Target zone.
-   */
-  const struct GNUNET_IDENTITY_PrivateKey *zone;
-
-  /**
-   * Function to call on each record.
-   */
-  GNUNET_NAMESTORE_RecordIterator iter;
-
-  /**
-   * Closure for @e iter.
-   */
-  void *iter_cls;
-};
-
-
-/**
- * Helper function for #namestore_flat_iterate_records().
- *
- * @param cls a `struct IterateContext`
- * @param key unused
- * @param value a `struct FlatFileEntry`
- * @return #GNUNET_YES to continue the iteration
- */
-static int
-iterate_zones (void *cls,
-               const struct GNUNET_HashCode *key,
-               void *value)
-{
-  struct IterateContext *ic = cls;
-  struct FlatFileEntry *entry = value;
-
-  (void) key;
-  if (0 == ic->limit)
-    return GNUNET_NO;
-  if ((NULL != ic->zone) &&
-      (0 != GNUNET_memcmp (&entry->private_key,
-                           ic->zone)))
-    return GNUNET_YES;
-  ic->pos++;
-  if (ic->offset > 0)
-  {
-    ic->offset--;
-    return GNUNET_YES;
-  }
-  ic->iter (ic->iter_cls,
-            ic->pos,
-            (NULL == ic->zone)
-            ? &entry->private_key
-            : ic->zone,
-            entry->label,
-            entry->record_count,
-            entry->record_data);
-  ic->limit--;
-  if (0 == ic->limit)
-    return GNUNET_NO;
-  return GNUNET_YES;
-}
-
-
-/**
- * Iterate over the results for a particular key and zone in the
- * datastore.  Will return at most one result to the iterator.
- *
- * @param cls closure (internal context for the plugin)
- * @param zone hash of public key of the zone, NULL to iterate over all zones
- * @param serial serial number to exclude in the list of all matching records
- * @param limit maximum number of results to return to @a iter
- * @param iter function to call with the result
- * @param iter_cls closure for @a iter
- * @return #GNUNET_OK on success, #GNUNET_NO if there were no more results, 
#GNUNET_SYSERR on error
- */
-static int
-namestore_flat_iterate_records (void *cls,
-                                const struct
-                                GNUNET_IDENTITY_PrivateKey *zone,
-                                uint64_t serial,
-                                uint64_t limit,
-                                GNUNET_NAMESTORE_RecordIterator iter,
-                                void *iter_cls)
-{
-  struct Plugin *plugin = cls;
-  struct IterateContext ic;
-
-  ic.offset = serial;
-  ic.pos = 0;
-  ic.limit = limit;
-  ic.iter = iter;
-  ic.iter_cls = iter_cls;
-  ic.zone = zone;
-  GNUNET_CONTAINER_multihashmap_iterate (plugin->hm,
-                                         &iterate_zones,
-                                         &ic);
-  return (0 == ic.limit) ? GNUNET_OK : GNUNET_NO;
-}
-
-
-/**
- * Closure for #zone_to_name.
- */
-struct ZoneToNameContext
-{
-  const struct GNUNET_IDENTITY_PrivateKey *zone;
-  const struct GNUNET_IDENTITY_PublicKey *value_zone;
-  GNUNET_NAMESTORE_RecordIterator iter;
-  void *iter_cls;
-
-  int result_found;
-};
-
-
-static int
-zone_to_name (void *cls,
-              const struct GNUNET_HashCode *key,
-              void *value)
-{
-  struct ZoneToNameContext *ztn = cls;
-  struct FlatFileEntry *entry = value;
-
-  (void) key;
-  if (0 != GNUNET_memcmp (&entry->private_key,
-                          ztn->zone))
-    return GNUNET_YES;
-
-  for (unsigned int i = 0; i < entry->record_count; i++)
-  {
-    if (GNUNET_NO ==
-        GNUNET_GNSRECORD_is_zonekey_type (entry->record_data[i].record_type))
-      continue;
-    if (ztn->value_zone->type != entry->record_data[i].record_type)
-      continue;
-    if (0 == memcmp (ztn->value_zone,
-                     entry->record_data[i].data,
-                     entry->record_data[i].data_size))
-    {
-      ztn->iter (ztn->iter_cls,
-                 i + 1,    /* zero is illegal! */
-                 &entry->private_key,
-                 entry->label,
-                 entry->record_count,
-                 entry->record_data);
-      ztn->result_found = GNUNET_YES;
-    }
-  }
-  return GNUNET_YES;
-}
-
-
-/**
- * Look for an existing PKEY delegation record for a given public key.
- * Returns at most one result to the iterator.
- *
- * @param cls closure (internal context for the plugin)
- * @param zone private key of the zone to look up in, never NULL
- * @param value_zone public key of the target zone (value), never NULL
- * @param iter function to call with the result
- * @param iter_cls closure for @a iter
- * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, 
#GNUNET_SYSERR on error
- */
-static int
-namestore_flat_zone_to_name (void *cls,
-                             const struct GNUNET_IDENTITY_PrivateKey *zone,
-                             const struct
-                             GNUNET_IDENTITY_PublicKey *value_zone,
-                             GNUNET_NAMESTORE_RecordIterator iter,
-                             void *iter_cls)
-{
-  struct Plugin *plugin = cls;
-  struct ZoneToNameContext ztn = {
-    .iter = iter,
-    .iter_cls = iter_cls,
-    .zone = zone,
-    .value_zone = value_zone,
-    .result_found = GNUNET_NO
-  };
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Performing reverse lookup for `%s'\n",
-              GNUNET_GNSRECORD_z2s (value_zone));
-  GNUNET_CONTAINER_multihashmap_iterate (plugin->hm,
-                                         &zone_to_name,
-                                         &ztn);
-  return ztn.result_found;
-}
-
-
-/**
- * Entry point for the plugin.
- *
- * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
- * @return NULL on error, otherwise the plugin context
- */
-void *
-libgnunet_plugin_namestore_flat_init (void *cls)
-{
-  static struct Plugin plugin;
-  const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
-  struct GNUNET_NAMESTORE_PluginFunctions *api;
-
-  if (NULL != plugin.cfg)
-    return NULL;                /* can only initialize once! */
-  memset (&plugin,
-          0,
-          sizeof(struct Plugin));
-  plugin.cfg = cfg;
-  if (GNUNET_OK != database_setup (&plugin))
-  {
-    database_shutdown (&plugin);
-    return NULL;
-  }
-  api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
-  api->cls = &plugin;
-  api->store_records = &namestore_flat_store_records;
-  api->iterate_records = &namestore_flat_iterate_records;
-  api->zone_to_name = &namestore_flat_zone_to_name;
-  api->lookup_records = &namestore_flat_lookup_records;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _ ("Flat file database running\n"));
-  return api;
-}
-
-
-/**
- * Exit point from the plugin.
- *
- * @param cls the plugin context (as returned by "init")
- * @return always NULL
- */
-void *
-libgnunet_plugin_namestore_flat_done (void *cls)
-{
-  struct GNUNET_NAMESTORE_PluginFunctions *api = cls;
-  struct Plugin *plugin = api->cls;
-
-  database_shutdown (plugin);
-  plugin->cfg = NULL;
-  GNUNET_free (api);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Flat file plugin is finished\n");
-  return NULL;
-}
-
-
-/* end of plugin_namestore_flat.c */
diff --git a/src/namestore/plugin_namestore_postgres.c 
b/src/namestore/plugin_namestore_postgres.c
index bdbaf96b3..3b1b7ac21 100644
--- a/src/namestore/plugin_namestore_postgres.c
+++ b/src/namestore/plugin_namestore_postgres.c
@@ -553,6 +553,68 @@ namestore_postgres_zone_to_name (void *cls,
   return GNUNET_OK;
 }
 
+/**
+ * Begin a transaction for a client.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param emsg error message set of return code is #GNUNET_SYSERR
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be 
started.
+ */
+static enum GNUNET_GenericReturnValue
+namestore_postgres_transaction_begin (void *cls,
+                                      char **emsg)
+{
+  struct Plugin *plugin = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("BEGIN;"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  return GNUNET_PQ_exec_statements (plugin->dbh, es);
+}
+
+/**
+ * Commit a transaction for a client.
+ * This releases the lock on the database.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param emsg error message set of return code is #GNUNET_SYSERR
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be 
started.
+ */
+static enum GNUNET_GenericReturnValue
+namestore_postgres_transaction_rollback (void *cls,
+                                         char **emsg)
+{
+  struct Plugin *plugin = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("ROLLBACK;"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  return GNUNET_PQ_exec_statements (plugin->dbh, es);
+}
+
+/**
+ * Roll back a transaction for a client.
+ * This releases the lock on the database.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param emsg error message set of return code is #GNUNET_SYSERR
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be 
started.
+ */
+static enum GNUNET_GenericReturnValue
+namestore_postgres_transaction_commit (void *cls,
+                                       char **emsg)
+{
+  struct Plugin *plugin = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("COMMIT;"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  return GNUNET_PQ_exec_statements (plugin->dbh, es);
+}
+
 
 /**
  * Shutdown database connection and associate data
@@ -577,25 +639,27 @@ database_shutdown (struct Plugin *plugin)
 void *
 libgnunet_plugin_namestore_postgres_init (void *cls)
 {
-  static struct Plugin plugin;
+  struct Plugin *plugin;
   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
   struct GNUNET_NAMESTORE_PluginFunctions *api;
 
-  if (NULL != plugin.cfg)
-    return NULL;                /* can only initialize once! */
-  memset (&plugin, 0, sizeof(struct Plugin));
-  plugin.cfg = cfg;
-  if (GNUNET_OK != database_setup (&plugin))
+  plugin = GNUNET_new (struct Plugin);
+  plugin->cfg = cfg;
+  if (GNUNET_OK != database_setup (plugin))
   {
-    database_shutdown (&plugin);
+    database_shutdown (plugin);
+    GNUNET_free (plugin);
     return NULL;
   }
   api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
-  api->cls = &plugin;
+  api->cls = plugin;
   api->store_records = &namestore_postgres_store_records;
   api->iterate_records = &namestore_postgres_iterate_records;
   api->zone_to_name = &namestore_postgres_zone_to_name;
   api->lookup_records = &namestore_postgres_lookup_records;
+  api->transaction_begin = &namestore_postgres_transaction_begin;
+  api->transaction_commit = &namestore_postgres_transaction_commit;
+  api->transaction_rollback = &namestore_postgres_transaction_rollback;
   LOG (GNUNET_ERROR_TYPE_INFO,
        "Postgres namestore plugin running\n");
   return api;
@@ -616,6 +680,7 @@ libgnunet_plugin_namestore_postgres_done (void *cls)
 
   database_shutdown (plugin);
   plugin->cfg = NULL;
+  GNUNET_free (plugin);
   GNUNET_free (api);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Postgres namestore plugin is finished\n");
diff --git a/src/namestore/plugin_namestore_sqlite.c 
b/src/namestore/plugin_namestore_sqlite.c
index 0b3aac84f..d434abd94 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -129,7 +129,7 @@ database_setup (struct Plugin *plugin)
     GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
     GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
     GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
-    GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"),
+    GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=NORMAL"),
     GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
     GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
     GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
@@ -201,17 +201,16 @@ database_setup (struct Plugin *plugin)
       return GNUNET_SYSERR;
     }
   }
-  /* sqlite_filename should be UTF-8-encoded. If it isn't, it's a bug */
-  plugin->fn = sqlite_filename;
 
   /* Open database and precompile statements */
   if (SQLITE_OK !=
-      sqlite3_open (plugin->fn,
+      sqlite3_open (sqlite_filename,
                     &plugin->dbh))
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
          _ ("Unable to initialize SQLite: %s.\n"),
          sqlite3_errmsg (plugin->dbh));
+    GNUNET_free (sqlite_filename);
     return GNUNET_SYSERR;
   }
   GNUNET_break (SQLITE_OK ==
@@ -224,7 +223,8 @@ database_setup (struct Plugin *plugin)
     GNUNET_break (0);
     LOG (GNUNET_ERROR_TYPE_ERROR,
          _ ("Failed to setup database at `%s'\n"),
-         plugin->fn);
+         sqlite_filename);
+    GNUNET_free (sqlite_filename);
     return GNUNET_SYSERR;
   }
 
@@ -235,7 +235,8 @@ database_setup (struct Plugin *plugin)
     GNUNET_break (0);
     LOG (GNUNET_ERROR_TYPE_ERROR,
          _ ("Failed to setup database at `%s'\n"),
-         plugin->fn);
+         sqlite_filename);
+    GNUNET_free (sqlite_filename);
     return GNUNET_SYSERR;
   }
   return GNUNET_OK;
@@ -296,7 +297,6 @@ database_shutdown (struct Plugin *plugin)
                 GNUNET_ERROR_TYPE_ERROR,
                 "sqlite3_close");
 
-  GNUNET_free (plugin->fn);
 }
 
 
@@ -331,8 +331,8 @@ namestore_sqlite_store_records (void *cls,
   for (unsigned int i = 0; i < rd_count; i++)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Checking if `%d' is zonekey type\n",
-       rd[i].record_type);
+         "Checking if `%d' is zonekey type\n",
+         rd[i].record_type);
 
     if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type))
     {
@@ -342,8 +342,8 @@ namestore_sqlite_store_records (void *cls,
                                                          rd[i].record_type,
                                                          &pkey));
       LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Storing delegation zone record value `%s'\n",
-       GNUNET_GNSRECORD_z2s (&pkey));
+           "Storing delegation zone record value `%s'\n",
+           GNUNET_GNSRECORD_z2s (&pkey));
 
       break;
     }
@@ -740,6 +740,58 @@ namestore_sqlite_zone_to_name (void *cls,
                                         iter_cls);
 }
 
+/**
+ * Begin a transaction for a client.
+ * This locks the database. SQLite is unable to discern between different
+ * rows with a specific zone key but the API looks like this anyway.
+ * https://www.sqlite.org/lang_transaction.html
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param emsg error message set of return code is #GNUNET_SYSERR
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be 
started.
+ */
+static enum GNUNET_GenericReturnValue
+namestore_sqlite_transaction_begin (void *cls,
+                                    char **emsg)
+{
+  struct Plugin *plugin = cls;
+  return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "BEGIN TRANSACTION;", NULL,
+                                       NULL, emsg)) ? GNUNET_SYSERR : 
GNUNET_YES;
+}
+
+/**
+ * Commit a transaction for a client.
+ * This releases the lock on the database.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param emsg error message set of return code is #GNUNET_SYSERR
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be 
started.
+ */
+static enum GNUNET_GenericReturnValue
+namestore_sqlite_transaction_rollback (void *cls,
+                                       char **emsg)
+{
+  struct Plugin *plugin = cls;
+  return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "ROLLBACK;", NULL,
+                                       NULL, emsg)) ? GNUNET_SYSERR : 
GNUNET_YES;
+}
+
+/**
+ * Roll back a transaction for a client.
+ * This releases the lock on the database.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param emsg error message set of return code is #GNUNET_SYSERR
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be 
started.
+ */
+static enum GNUNET_GenericReturnValue
+namestore_sqlite_transaction_commit (void *cls,
+                                     char **emsg)
+{
+  struct Plugin *plugin = cls;
+  return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "END TRANSACTION;", NULL,
+                                       NULL, emsg)) ? GNUNET_SYSERR : 
GNUNET_YES;
+}
 
 /**
  * Entry point for the plugin.
@@ -750,27 +802,27 @@ namestore_sqlite_zone_to_name (void *cls,
 void *
 libgnunet_plugin_namestore_sqlite_init (void *cls)
 {
-  static struct Plugin plugin;
+  struct Plugin *plugin;
   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
   struct GNUNET_NAMESTORE_PluginFunctions *api;
 
-  if (NULL != plugin.cfg)
-    return NULL;                /* can only initialize once! */
-  memset (&plugin,
-          0,
-          sizeof(struct Plugin));
-  plugin.cfg = cfg;
-  if (GNUNET_OK != database_setup (&plugin))
+  plugin = GNUNET_new (struct Plugin);
+  plugin->cfg = cfg;
+  if (GNUNET_OK != database_setup (plugin))
   {
-    database_shutdown (&plugin);
+    database_shutdown (plugin);
+    GNUNET_free (plugin);
     return NULL;
   }
   api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
-  api->cls = &plugin;
+  api->cls = plugin;
   api->store_records = &namestore_sqlite_store_records;
   api->iterate_records = &namestore_sqlite_iterate_records;
   api->zone_to_name = &namestore_sqlite_zone_to_name;
   api->lookup_records = &namestore_sqlite_lookup_records;
+  api->transaction_begin = &namestore_sqlite_transaction_begin;
+  api->transaction_commit = &namestore_sqlite_transaction_commit;
+  api->transaction_rollback = &namestore_sqlite_transaction_rollback;
   LOG (GNUNET_ERROR_TYPE_INFO,
        _ ("Sqlite database running\n"));
   return api;
@@ -791,6 +843,7 @@ libgnunet_plugin_namestore_sqlite_done (void *cls)
 
   database_shutdown (plugin);
   plugin->cfg = NULL;
+  GNUNET_free (plugin);
   GNUNET_free (api);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "sqlite plugin is finished\n");
diff --git a/src/namestore/test_namestore_api_flat.conf 
b/src/namestore/test_namestore_api_flat.conf
deleted file mode 100644
index 8460d143c..000000000
--- a/src/namestore/test_namestore_api_flat.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-@INLINE@ test_namestore_api.conf
-
-[namestore]
-DATABASE = flat
-
-[namestore-heap]
-FILENAME = $GNUNET_TEST_HOME/namestore/flat.db
diff --git a/src/namestore/test_namestore_api_monitoring_existing.c 
b/src/namestore/test_namestore_api_monitoring_existing.c
index 366f5739f..95907f34a 100644
--- a/src/namestore/test_namestore_api_monitoring_existing.c
+++ b/src/namestore/test_namestore_api_monitoring_existing.c
@@ -250,25 +250,6 @@ put_cont (void *cls,
 
   if (3 == c)
   {
-    /* Start monitoring */
-    zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
-                                              &privkey,
-                                              GNUNET_YES,
-                                              &fail_cb,
-                                              NULL,
-                                              &zone_proc,
-                                              NULL,
-                                              &sync_cb,
-                                              NULL);
-    if (NULL == zm)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Failed to create zone monitor\n");
-      GNUNET_break (0);
-      res = 1;
-      GNUNET_SCHEDULER_shutdown ();
-      return;
-    }
   }
 }
 
@@ -324,6 +305,25 @@ run (void *cls,
                                               NULL);
     return;
   }
+  /* Start monitoring */
+  zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
+                                            &privkey,
+                                            GNUNET_YES,
+                                            &fail_cb,
+                                            NULL,
+                                            &zone_proc,
+                                            NULL,
+                                            &sync_cb,
+                                            NULL);
+  if (NULL == zm)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to create zone monitor\n");
+    GNUNET_break (0);
+    res = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Created record 3\n");
diff --git a/src/namestore/test_plugin_namestore_flat.conf 
b/src/namestore/test_plugin_namestore_flat.conf
deleted file mode 100644
index 5c632f0d1..000000000
--- a/src/namestore/test_plugin_namestore_flat.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[namestore-flat]
-FILENAME = $GNUNET_TMP/gnunet-test-plugin-namestore-flat/flatdb

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