gnunet-svn
[Top][All Lists]
Advanced

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

[taler-sync] branch master updated (c804772 -> d9ce406)


From: gnunet
Subject: [taler-sync] branch master updated (c804772 -> d9ce406)
Date: Thu, 14 Nov 2019 19:34:05 +0100

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

grothoff pushed a change to branch master
in repository sync.

    from c804772  skeleton
     new 0ccb604  wip
     new d9ce406  first cut at syncdb plugin

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/Makefile.am                       |   2 +-
 src/include/sync_database_plugin.h    | 173 +++++--
 src/syncdb/Makefile.am                |   6 +-
 src/syncdb/plugin_sync_postgres.c     | 284 ------------
 src/syncdb/plugin_syncdb_postgres.c   | 817 ++++++++++++++++++++++++++++++++++
 src/syncdb/sync_db_plugin.c           |  22 +-
 src/syncdb/test_sync_db.c             |  71 +--
 src/syncdb/test_sync_db_postgres.conf |   6 +-
 src/util/Makefile.am                  |  28 ++
 src/util/os_installation.c            |  71 +++
 src/util/sync-config                  |  17 +
 11 files changed, 1095 insertions(+), 402 deletions(-)
 delete mode 100644 src/syncdb/plugin_sync_postgres.c
 create mode 100644 src/syncdb/plugin_syncdb_postgres.c
 create mode 100644 src/util/Makefile.am
 create mode 100644 src/util/os_installation.c
 create mode 100644 src/util/sync-config

diff --git a/src/Makefile.am b/src/Makefile.am
index 0746ad4..cd274f1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,3 @@
 # This Makefile is in the public domain
 AM_CPPFLAGS = -I$(top_srcdir)/src/include
-SUBDIRS = include syncdb sync lib
+SUBDIRS = include util syncdb sync lib
diff --git a/src/include/sync_database_plugin.h 
b/src/include/sync_database_plugin.h
index 5563cf3..b847888 100644
--- a/src/include/sync_database_plugin.h
+++ b/src/include/sync_database_plugin.h
@@ -1,25 +1,25 @@
 /*
-  This file is part of Sync
+  This file is part of GNU Taler
   Copyright (C) 2019 Taler Systems SA
 
-  Sync is free software; you can redistribute it and/or modify it under the
+  Taler is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
   Foundation; either version 3, or (at your option) any later version.
 
-  Sync is distributed in the hope that it will be useful, but WITHOUT ANY
+  Taler is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License along with
-  Sync; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
+  Taler; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
 */
 /**
  * @file include/sync_database_plugin.h
  * @brief database access for Sync
  * @author Christian Grothoff
  */
-#ifndef TALER_SYNC_DATABASE_PLUGIN_H
-#define TALER_SYNC_DATABASE_PLUGIN_H
+#ifndef SYNC_DATABASE_PLUGIN_H
+#define SYNC_DATABASE_PLUGIN_H
 
 #include <gnunet/gnunet_util_lib.h>
 #include <sync_error_codes.h>
@@ -27,6 +27,79 @@
 #include <jansson.h>
 #include <taler/taler_util.h>
 
+/**
+ * Private key identifying an account.
+ */
+struct SYNC_AccountPrivateKey
+{
+  /**
+   * We use EdDSA.
+   */
+  struct GNUNET_EdDSAPrivateKey eddsa_priv;
+};
+
+
+/**
+ * Public key identifying an account.
+ */
+struct SYNC_AccountPublicKey
+{
+  /**
+   * We use EdDSA.
+   */
+  struct GNUNET_EdDSAPrivateKey eddsa_priv;
+};
+
+
+/**
+ * Signature made with an account's public key.
+ */
+struct SYNC_AccountSignature
+{
+  /**
+   * We use EdDSA.
+   */
+  struct GNUNET_EdDSASignature eddsa_sig;
+};
+
+
+/**
+ * Possible status codes returned from the SYNC database.
+ */
+enum SYNC_DB_QueryStatus
+{
+  /**
+   * Update failed because the old backup hash does not match what we 
previously had in the DB.
+   */
+  SYNC_DB_OLD_BACKUP_MISSMATCH = -4,
+
+  /**
+   * Account is unpaid.
+   */
+  SYNC_DB_QS_PAYMENT_REQUIRED = -3,
+
+  /**
+   * Hard database issue, retries futile.
+   */
+  SYNC_DB_HARD_ERROR = -2,
+
+  /**
+   * Soft database error, retrying may help.
+   */
+  SYNC_DB_SOFT_ERROR = -1,
+
+  /**
+   * Database succeeded, but no results.
+   */
+  SYNC_DB_NO_RESULTS = 0,
+
+  /**
+   * Database succeeded, one change or result.
+   */
+  SYNC_DB_ONE_RESULT = 1
+};
+
+
 /**
  * Handle to interact with the database.
  *
@@ -67,51 +140,85 @@ struct SYNC_DatabasePlugin
    * truth and financial records older than @a fin_expire.
    *
    * @param cls closure
-   * @param fin_expire financial records older than the given
-   *        time stamp should be garbage collected (usual
-   *        values might be something like 6-10 years in the past)
+   * @param expire backups older than the given time stamp should be garbage 
collected
    * @return transaction status
    */
   enum SYNC_DB_QueryStatus
   (*gc)(void *cls,
-        struct GNUNET_TIME_Absolute fin_expire);
+        struct GNUNET_TIME_Absolute expire);
 
   /**
-  * Do a pre-flight check that we are not in an uncommitted transaction.
-  * If we are, try to commit the previous transaction and output a warning.
-  * Does not return anything, as we will continue regardless of the outcome.
-  *
-  * @param cls the `struct PostgresClosure` with the plugin-specific state
-  */
-  void
-  (*preflight) (void *cls);
-
-  /**
-  * Check that the database connection is still up.
-  *
-  * @param pg connection to check
-  */
-  void
-  (*check_connection) (void *cls);
+   * Store backup. Only applicable for the FIRST backup under
+   * an @a account_pub. Use @e update_backup_TR to update an
+   * existing backup.
+   *
+   * @param cls closure
+   * @param account_pub account to store @a backup under
+   * @param account_sig signature affirming storage request
+   * @param backup_hash hash of @a backup
+   * @param backup_size number of bytes in @a backup
+   * @param backup raw data to backup
+   * @return transaction status
+   */
+  enum SYNC_DB_QueryStatus
+  (*store_backup_TR)(void *cls,
+                     const struct SYNC_AccountPublicKey *account_pub,
+                     const struct SYNC_AccountSignature *account_sig,
+                     const struct GNUNET_HashCode *backup_hash,
+                     size_t backup_size,
+                     const void *backup);
 
   /**
-   * Store backup.
+   * Update backup.
    *
    * @param cls closure
+   * @param account_pub account to store @a backup under
+   * @param account_sig signature affirming storage request
+   * @param old_backup_hash hash of the previous backup (must match)
+   * @param backup_hash hash of @a backup
+   * @param backup_size number of bytes in @a backup
+   * @param backup raw data to backup
    * @return transaction status
    */
-  enum GNUNET_DB_QueryStatus
-  (*store_backup)(void *cls,
-                  ...);
+  enum SYNC_DB_QueryStatus
+  (*update_backup_TR)(void *cls,
+                      const struct SYNC_AccountPublicKey *account_pub,
+                      const struct GNUNET_HashCode *old_backup_hash,
+                      const struct SYNC_AccountSignature *account_sig,
+                      const struct GNUNET_HashCode *backup_hash,
+                      size_t backup_size,
+                      const void *backup);
 
   /**
    * Obtain backup.
    *
    * @param cls closure
+   * @param account_pub account to store @a backup under
+   * @param account_sig[OUT] set to signature affirming storage request
+   * @param backup_hash[OUT] set to hash of @a backup
+   * @param backup_size[OUT] set to number of bytes in @a backup
+   * @param backup[OUT] set to raw data to backup, caller MUST FREE
    */
-  enum GNUNET_DB_QueryStatus
-  (*lookup_backup)(void *cls,
-                   ...);
+  enum SYNC_DB_QueryStatus
+  (*lookup_backup_TR)(void *cls,
+                      const struct SYNC_AccountPublicKey *account_pub,
+                      struct SYNC_AccountSignature *account_sig,
+                      struct GNUNET_HashCode *backup_hash,
+                      size_t *backup_size,
+                      void **backup);
+
+  /**
+   * Increment account lifetime.
+   *
+   * @param cls closure
+   * @param account_pub which account received a payment
+   * @param lifetime for how long is the account now paid (increment)
+   * @return transaction status
+   */
+  enum SYNC_DB_QueryStatus
+  (*increment_lifetime_TR)(void *cls,
+                           const struct SYNC_AccountPublicKey *account_pub,
+                           struct GNUNET_TIME_Relative lifetime);
 
 };
 #endif
diff --git a/src/syncdb/Makefile.am b/src/syncdb/Makefile.am
index 56db964..9b3d4b0 100644
--- a/src/syncdb/Makefile.am
+++ b/src/syncdb/Makefile.am
@@ -1,7 +1,7 @@
 # This Makefile.am is in the public domain
 AM_CPPFLAGS = -I$(top_srcdir)/src/include
 
-plugindir = $(libdir)/taler
+plugindir = $(libdir)/sync
 
 if HAVE_POSTGRESQL
 if HAVE_GNUNETPQ
@@ -27,11 +27,11 @@ libsyncdb_la_LIBADD = \
   -lgnunetutil
 libsyncdb_la_LDFLAGS = \
    $(POSTGRESQL_LDFLAGS) \
-   -version-info 2:0:0 \
+   -version-info 0:0:0 \
    -no-undefined
 
 libsync_plugin_db_postgres_la_SOURCES = \
-  plugin_sync_postgres.c
+  plugin_syncdb_postgres.c
 libsync_plugin_db_postgres_la_LIBADD = \
   $(LTLIBINTL)
 libsync_plugin_db_postgres_la_LDFLAGS = \
diff --git a/src/syncdb/plugin_sync_postgres.c 
b/src/syncdb/plugin_sync_postgres.c
deleted file mode 100644
index 4e63198..0000000
--- a/src/syncdb/plugin_sync_postgres.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
-  This file is part of TALER
-  (C) 2014--2019 Taler Systems SA
-
-  TALER is free software; you can redistribute it and/or modify it under the
-  terms of the GNU Lesser General Public License as published by the Free 
Software
-  Foundation; either version 3, or (at your option) any later version.
-
-  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of ANASTASISABILITY or FITNESS 
FOR
-  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License along with
-  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file sync/plugin_syncdb_postgres.c
- * @brief database helper functions for postgres used by the sync
- * @author Sree Harsha Totakura <address@hidden>
- * @author Christian Grothoff
- * @author Marcello Stanisci
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_pq_lib.h>
-#include <taler/taler_pq_lib.h>
-#include "sync_database_plugin.h"
-#include "sync_database_lib.h"
-
-/**
- * How often do we re-try if we run into a DB serialization error?
- */
-#define MAX_RETRIES 3
-
-
-/**
- * Type of the "cls" argument given to each of the functions in
- * our API.
- */
-struct PostgresClosure
-{
-
-  /**
-   * Postgres connection handle.
-   */
-  struct GNUNET_PQ_Context *conn;
-
-  /**
-   * Underlying configuration.
-   */
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Name of the currently active transaction, NULL if none is active.
-   */
-  const char *transaction_name;
-
-};
-
-
-/**
- * Drop sync tables
- *
- * @param cls closure our `struct Plugin`
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-static int
-postgres_drop_tables (void *cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS backups;"),
-    GNUNET_PQ_EXECUTE_STATEMENT_END
-  };
-  return GNUNET_PQ_exec_statements (pg->conn,
-                                    es);
-}
-
-
-/**
- * Check that the database connection is still up.
- *
- * @param pg connection to check
- */
-static void
-check_connection (void *cls)
-{
-  struct PostgresClosure *pg = cls;
-  GNUNET_PQ_reconnect_if_down (pg->conn);
-}
-
-
-/**
- * Do a pre-flight check that we are not in an uncommitted transaction.
- * If we are, try to commit the previous transaction and output a warning.
- * Does not return anything, as we will continue regardless of the outcome.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- */
-static void
-postgres_preflight (void *cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("COMMIT"),
-    GNUNET_PQ_EXECUTE_STATEMENT_END
-  };
-
-  if (NULL == pg->transaction_name)
-    return; /* all good */
-  if (GNUNET_OK ==
-      GNUNET_PQ_exec_statements (pg->conn,
-                                 es))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "BUG: Preflight check committed transaction `%s'!\n",
-                pg->transaction_name);
-  }
-  else
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "BUG: Preflight check failed to commit transaction `%s'!\n",
-                pg->transaction_name);
-  }
-  pg->transaction_name = NULL;
-}
-
-/**
- * Start a transaction.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param name unique name identifying the transaction (for debugging),
- *             must point to a constant
- * @return #GNUNET_OK on success
- */
-static int
-begin_transaction (void *cls,
-                   const char *name)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
-    GNUNET_PQ_EXECUTE_STATEMENT_END
-  };
-
-  check_connection (pg);
-  postgres_preflight (pg);
-  pg->transaction_name = name;
-  if (GNUNET_OK !=
-      GNUNET_PQ_exec_statements (pg->conn,
-                                 es))
-  {
-    TALER_LOG_ERROR ("Failed to start transaction\n");
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-/**
-* Roll back the current transaction of a database connection.
-*
-* @param cls the `struct PostgresClosure` with the plugin-specific state
-* @return #GNUNET_OK on success
-*/
-static void
-rollback (void *cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("ROLLBACK"),
-    GNUNET_PQ_EXECUTE_STATEMENT_END
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_PQ_exec_statements (pg->conn,
-                                 es))
-  {
-    TALER_LOG_ERROR ("Failed to rollback transaction\n");
-    GNUNET_break (0);
-  }
-  pg->transaction_name = NULL;
-}
-
-/**
- * Commit the current transaction of a database connection.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @return transaction status code
- */
-
-static enum SYNC_DB_QueryStatus
-commit_transaction (void *cls)
-{
-  struct PostgresClosure *pg = cls;
-  enum SYNC_DB_QueryStatus qs;
-  struct GNUNET_PQ_QueryParam no_params[] = {
-    GNUNET_PQ_query_param_end
-  };
-
-  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                           "do_commit",
-                                           no_params);
-  pg->transaction_name = NULL;
-  return qs;
-}
-
-
-
-/**
- * Initialize Postgres database subsystem.
- *
- * @param cls a configuration instance
- * @return NULL on error, otherwise a `struct TALER_SYNCDB_Plugin`
- */
-void *
-libsync_plugin_db_postgres_init (void *cls)
-{
-  struct GNUNET_CONFIGURATION_Handle *cfg = cls;
-  struct PostgresClosure *pg;
-  struct SYNC_DatabasePlugin *plugin;
-  struct GNUNET_PQ_ExecuteStatement es[] = {
-    /* Orders created by the frontend, not signed or given a nonce yet.
-       The contract terms will change (nonce will be added) when moved to the
-       contract terms table */
-    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS backups"
-                            "("                            
-                            "data BYTEA NOT NULL,"
-                            ");"),
-    GNUNET_PQ_EXECUTE_STATEMENT_END
-  };
-  struct GNUNET_PQ_PreparedStatement ps[] = {
-    GNUNET_PQ_make_prepare ("backup_insert",
-                            "INSERT INTO backups "
-                            "(data"
-                            ") VALUES "
-                            "($1);",
-                            1),
-    GNUNET_PQ_make_prepare ("do_commit",
-                            "COMMIT",
-                            0),
-    GNUNET_PQ_PREPARED_STATEMENT_END
-  };
-
-  pg = GNUNET_new (struct PostgresClosure);
-  pg->cfg = cfg;
-  pg->conn = GNUNET_PQ_connect_with_cfg (cfg,
-                                         "syncdb-postgres",
-                                         es,
-                                         ps);
-  if (NULL == pg->conn)
-  {
-    GNUNET_free (pg);
-    return NULL;
-  }
-  plugin = GNUNET_new (struct SYNC_DatabasePlugin);
-  plugin->cls = pg;
-  plugin->drop_tables = &postgres_drop_tables;
-  plugin->preflight = &postgres_preflight;
-  plugin->rollback = &rollback;
-  plugin->commit = &commit_transaction;
-  return plugin;
-}
-
-
-/**
- * Shutdown Postgres database subsystem.
- *
- * @param cls a `struct SYNC_DB_Plugin`
- * @return NULL (always)
- */
-void *
-libsync_plugin_db_postgres_done (void *cls)
-{
-  struct SYNC_DatabasePlugin *plugin = cls;
-  struct PostgresClosure *pg = plugin->cls;
-
-  GNUNET_PQ_disconnect (pg->conn);
-  GNUNET_free (pg);
-  GNUNET_free (plugin);
-  return NULL;
-}
-
-/* end of plugin_syncdb_postgres.c */
diff --git a/src/syncdb/plugin_syncdb_postgres.c 
b/src/syncdb/plugin_syncdb_postgres.c
new file mode 100644
index 0000000..d1c3e3e
--- /dev/null
+++ b/src/syncdb/plugin_syncdb_postgres.c
@@ -0,0 +1,817 @@
+/*
+  This file is part of TALER
+  (C) 2014--2019 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Lesser General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of ANASTASISABILITY or FITNESS 
FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync/plugin_syncdb_postgres.c
+ * @brief database helper functions for postgres used by sync
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_pq_lib.h>
+#include <taler/taler_pq_lib.h>
+#include "sync_database_plugin.h"
+#include "sync_database_lib.h"
+
+/**
+ * Type of the "cls" argument given to each of the functions in
+ * our API.
+ */
+struct PostgresClosure
+{
+
+  /**
+   * Postgres connection handle.
+   */
+  struct GNUNET_PQ_Context *conn;
+
+  /**
+   * Underlying configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Name of the currently active transaction, NULL if none is active.
+   */
+  const char *transaction_name;
+
+};
+
+
+/**
+ * Drop sync tables
+ *
+ * @param cls closure our `struct Plugin`
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
+ */
+static int
+postgres_drop_tables (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS accounts CASCADE;"),
+    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS backups;"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  return GNUNET_PQ_exec_statements (pg->conn,
+                                    es);
+}
+
+
+/**
+ * Check that the database connection is still up.
+ *
+ * @param pg connection to check
+ */
+static void
+check_connection (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+
+  GNUNET_PQ_reconnect_if_down (pg->conn);
+}
+
+
+/**
+ * Do a pre-flight check that we are not in an uncommitted transaction.
+ * If we are, try to commit the previous transaction and output a warning.
+ * Does not return anything, as we will continue regardless of the outcome.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ */
+static void
+postgres_preflight (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("COMMIT"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  if (NULL == pg->transaction_name)
+    return; /* all good */
+  if (GNUNET_OK ==
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check committed transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check failed to commit transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  pg->transaction_name = NULL;
+}
+
+
+/**
+ * Start a transaction.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param name unique name identifying the transaction (for debugging),
+ *             must point to a constant
+ * @return #GNUNET_OK on success
+ */
+static int
+begin_transaction (void *cls,
+                   const char *name)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  check_connection (pg);
+  postgres_preflight (pg);
+  pg->transaction_name = name;
+  if (GNUNET_OK !=
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    TALER_LOG_ERROR ("Failed to start transaction\n");
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Roll back the current transaction of a database connection.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @return #GNUNET_OK on success
+ */
+static void
+rollback (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("ROLLBACK"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  if (GNUNET_OK !=
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    TALER_LOG_ERROR ("Failed to rollback transaction\n");
+    GNUNET_break (0);
+  }
+  pg->transaction_name = NULL;
+}
+
+
+/**
+ * Commit the current transaction of a database connection.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @return transaction status code
+ */
+static enum GNUNET_DB_QueryStatus
+commit_transaction (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  enum SYNC_DB_QueryStatus qs;
+  struct GNUNET_PQ_QueryParam no_params[] = {
+    GNUNET_PQ_query_param_end
+  };
+
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                           "do_commit",
+                                           no_params);
+  pg->transaction_name = NULL;
+  return qs;
+}
+
+
+/**
+ * Function called to perform "garbage collection" on the
+ * database, expiring records we no longer require.  Deletes
+ * all user records that are not paid up (and by cascade deletes
+ * the associated recovery documents). Also deletes expired
+ * truth and financial records older than @a fin_expire.
+ *
+ * @param cls closure
+ * @param expire backups older than the given time stamp should be garbage 
collected
+ * @return transaction status
+ */
+static enum SYNC_DB_QueryStatus
+postgres_gc (void *cls,
+             struct GNUNET_TIME_Absolute expire)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    TALER_PQ_query_param_absolute_time (&expire),
+    GNUNET_PQ_query_param_end
+  };
+
+  check_connection (pg);
+  postgres_preflight (pg);
+  return (enum SYNC_DB_QueryStatus)
+         GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "gc",
+                                             params);
+}
+
+
+/**
+ * Store backup. Only applicable for the FIRST backup under
+ * an @a account_pub. Use @e update_backup_TR to update an
+ * existing backup.
+ *
+ * @param cls closure
+ * @param account_pub account to store @a backup under
+ * @param account_sig signature affirming storage request
+ * @param backup_hash hash of @a backup
+ * @param backup_size number of bytes in @a backup
+ * @param backup raw data to backup
+ * @return transaction status
+ */
+static enum SYNC_DB_QueryStatus
+postgres_store_backup (void *cls,
+                       const struct SYNC_AccountPublicKey *account_pub,
+                       const struct SYNC_AccountSignature *account_sig,
+                       const struct GNUNET_HashCode *backup_hash,
+                       size_t backup_size,
+                       const void *backup)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryStatus qs;
+  struct GNUNET_HashCode bh;
+
+  check_connection (pg);
+  postgres_preflight (pg);
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (account_pub),
+      GNUNET_PQ_query_param_auto_from_type (account_sig),
+      GNUNET_PQ_query_param_auto_from_type (backup_hash),
+      GNUNET_PQ_query_param_fixed_size (backup,
+                                        backup_size),
+      GNUNET_PQ_query_param_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "backup_insert",
+                                             params);
+  }
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    GNUNET_break (0);
+    return SYNC_DB_NO_RESULTS;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    return SYNC_DB_ONE_RESULT;
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    /* handle interesting case below */
+    break;
+  }
+
+  /* First, check if account exists */
+  {
+    struct GNUNET_TIME_Absolute ed;
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (account_pub),
+      GNUNET_PQ_query_param_end
+    };
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_auto_from_type ("expiration_date",
+                                            &ed),
+      GNUNET_PQ_result_spec_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "account_select",
+                                                   params,
+                                                   rs);
+  }
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    return SYNC_DB_PAYMENT_REQUIRED;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    /* handle interesting case below */
+    break;
+  }
+
+  /* account exists, check if existing backup conflicts */
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (account_pub),
+      GNUNET_PQ_query_param_end
+    };
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_auto_from_type ("backup_hash",
+                                            &bh),
+      GNUNET_PQ_result_spec_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "backup_select_hash",
+                                                   params,
+                                                   rs);
+  }
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    /* original error must have been a hard error, oddly enough */
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    /* handle interesting case below */
+    break;
+  }
+
+  /* had an existing backup, is it identical? */
+  if (0 != GNUNET_memcmp (&bh,
+                          backup_hash))
+    /* previous conflicting backup exists */
+    return SYNC_DB_OLD_BACKUP_MISSMATCH;
+  /* backup identical to what was provided, no change */
+  return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+}
+
+
+/**
+ * Update backup.
+ *
+ * @param cls closure
+ * @param account_pub account to store @a backup under
+ * @param account_sig signature affirming storage request
+ * @param old_backup_hash hash of the previous backup (must match)
+ * @param backup_hash hash of @a backup
+ * @param backup_size number of bytes in @a backup
+ * @param backup raw data to backup
+ * @return transaction status
+ */
+static enum SYNC_DB_QueryStatus
+postgres_update_backup (void *cls,
+                        const struct SYNC_AccountPublicKey *account_pub,
+                        const struct GNUNET_HashCode *old_backup_hash,
+                        const struct SYNC_AccountSignature *account_sig,
+                        const struct GNUNET_HashCode *backup_hash,
+                        size_t backup_size,
+                        const void *backup)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryStatus qs;
+  struct GNUNET_HashCode bh;
+
+  check_connection (pg);
+  postgres_preflight (pg);
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (backup_hash),
+      GNUNET_PQ_query_param_auto_from_type (account_sig),
+      GNUNET_PQ_query_param_fixed_size (backup,
+                                        backup_size),
+      GNUNET_PQ_query_param_auto_from_type (account_pub),
+      GNUNET_PQ_query_param_auto_from_type (old_backup_hash),
+      GNUNET_PQ_query_param_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "backup_update",
+                                             params);
+  }
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    GNUNET_break (0);
+    return SYNC_DB_NO_RESULTS;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    return SYNC_DB_ONE_RESULT;
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    /* handle interesting case below */
+    break;
+  }
+
+  /* First, check if account exists */
+  {
+    struct GNUNET_TIME_Absolute ed;
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (account_pub),
+      GNUNET_PQ_query_param_end
+    };
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_auto_from_type ("expiration_date",
+                                            &ed),
+      GNUNET_PQ_result_spec_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "account_select",
+                                                   params,
+                                                   rs);
+  }
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    return SYNC_DB_PAYMENT_REQUIRED;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    /* handle interesting case below */
+    break;
+  }
+
+  /* account exists, check if existing backup conflicts */
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (account_pub),
+      GNUNET_PQ_query_param_end
+    };
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_auto_from_type ("backup_hash",
+                                            &bh),
+      GNUNET_PQ_result_spec_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "backup_select_hash",
+                                                   params,
+                                                   rs);
+  }
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    /* Well, trying to update where there is no original
+       is a hard erorr, even though an odd one */
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    /* handle interesting case below */
+    break;
+  }
+
+  /* had an existing backup, is it identical? */
+  if (0 == GNUNET_memcmp (&bh,
+                          backup_hash))
+    /* backup identical to what was provided, no change */
+    return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+  if (0 == GNUNET_memcmp (&bh,
+                          old_backup_hash))
+    /* all constraints seem satisified, original error must
+       have been a hard error */
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  /* previous backup does not match old_backup_hash */
+  return SYNC_DB_OLD_BACKUP_MISSMATCH;
+}
+
+
+/**
+ * Obtain backup.
+ *
+ * @param cls closure
+ * @param account_pub account to store @a backup under
+ * @param account_sig[OUT] set to signature affirming storage request
+ * @param backup_hash[OUT] set to hash of @a backup
+ * @param backup_size[OUT] set to number of bytes in @a backup
+ * @param backup[OUT] set to raw data to backup, caller MUST FREE
+ */
+static enum SYNC_DB_QueryStatus
+postgres_lookup_backup (void *cls,
+                        const struct SYNC_AccountPublicKey *account_pub,
+                        struct SYNC_AccountSignature *account_sig,
+                        struct GNUNET_HashCode *backup_hash,
+                        size_t *backup_size,
+                        void **backup)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (account_pub),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_auto_from_type ("account_sig",
+                                          account_sig),
+    GNUNET_PQ_result_spec_auto_from_type ("backup_hash",
+                                          backup_hash),
+    GNUNET_PQ_result_spec_variable_size ("data",
+                                         &backup,
+                                         &backup_size),
+    GNUNET_PQ_result_spec_end
+  };
+
+  check_connection (pg);
+  postgres_preflight (pg);
+  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                 "backup_select",
+                                                 params,
+                                                 rs);
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    return SYNC_DB_NO_RESULTS;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    return SYNC_DB_ONE_RESULT;
+  }
+}
+
+
+/**
+ * Increment account lifetime.
+ *
+ * @param cls closure
+ * @param account_pub which account received a payment
+ * @param lifetime for how long is the account now paid (increment)
+ * @return transaction status
+ */
+static enum SYNC_DB_QueryStatus
+postgres_increment_lifetime (void *cls,
+                             const struct SYNC_AccountPublicKey *account_pub,
+                             struct GNUNET_TIME_Relative lifetime)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_TIME_Absolute expiration;
+  struct GNUNET_PQ_QueryStatus qs;
+
+  check_connection (pg);
+  if (GNUNET_OK !=
+      begin_transaction (pg,
+                         "increment lifetime"))
+  {
+    GNUNET_break (0);
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  }
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (account_pub),
+      GNUNET_PQ_query_param_end
+    };
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      TALER_PQ_result_spec_absolute_time ("wire_deadline",
+                                          &wire_deadline),
+      GNUNET_PQ_result_spec_end
+    };
+
+    qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+                                                   "account_select",
+                                                   params,
+                                                   rs);
+  }
+
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    rollback (pg);
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    rollback (pg);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    {
+      struct GNUNET_PQ_QueryParam params[] = {
+        GNUNET_PQ_query_param_auto_from_type (account_pub),
+        GNUNET_PQ_query_param_absolute_time (&expiration),
+        GNUNET_PQ_query_param_end
+      };
+
+      qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                               "account_insert",
+                                               params);
+    }
+    break;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    {
+      struct GNUNET_PQ_QueryParam params[] = {
+        GNUNET_PQ_query_param_absolute_time (&expiration),
+        GNUNET_PQ_query_param_auto_from_type (account_pub),
+        GNUNET_PQ_query_param_end
+      };
+
+      qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                               "account_update",
+                                               params);
+    }
+    break;
+  }
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    rollback (pg);
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    rollback (pg);
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    GNUNET_break (0);
+    rollback (pg);
+    return SYNC_DB_NO_RESULTS;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    break;
+  }
+  qs = commit_transaction (pg);
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    return SYNC_DB_HARD_ERROR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    return SYNC_DB_SOFT_ERROR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    return SYNC_DB_ONE_RESULT;
+  case GNUNET_DB_STATUS_SUCCESS_RESULT_ONE:
+    return SYNC_DB_ONE_RESULT;
+  }
+}
+
+
+/**
+ * Initialize Postgres database subsystem.
+ *
+ * @param cls a configuration instance
+ * @return NULL on error, otherwise a `struct TALER_SYNCDB_Plugin`
+ */
+void *
+libsync_plugin_db_postgres_init (void *cls)
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+  struct PostgresClosure *pg;
+  struct SYNC_DatabasePlugin *plugin;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    /* Orders created by the frontend, not signed or given a nonce yet.
+       The contract terms will change (nonce will be added) when moved to the
+       contract terms table */
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS accounts"
+                            "("
+                            "account_pub BYTEA PRIMARY KEY CHECK 
(length(account_pub)=32),"
+                            "expiration_date INT8 NOT NULL"
+                            ");"),
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS backups"
+                            "("
+                            "account_pub BYTEA PRIMARY KEY REFERENCES accounts 
(account_pub),"
+                            "account_sig BYTEA NOT NULL CHECK 
(length(account_sig)=64),"
+                            "backup_hash BYTEA NOT NULL CHECK 
(length(backup_hash)=64),"
+                            "data BYTEA NOT NULL"
+                            ");"),
+    /* index for gc */
+    GNUNET_PQ_make_try_execute (
+      "CREATE INDEX accounts_expire ON "
+      "accounts (expiration_date);"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+  struct GNUNET_PQ_PreparedStatement ps[] = {
+    GNUNET_PQ_make_prepare ("account_insert",
+                            "INSERT INTO accounts "
+                            "("
+                            "account_pub,"
+                            "expiration_date"
+                            ") VALUES "
+                            "($1,$2);",
+                            2),
+    GNUNET_PQ_make_prepare ("account_update",
+                            "UPDATE accounts "
+                            "SET"
+                            " expiration_date=$1 "
+                            "WHERE"
+                            " account_pub=$2;",
+                            2),
+    GNUNET_PQ_make_prepare ("account_select",
+                            "SELECT"
+                            " expiration_date "
+                            "FROM"
+                            " account"
+                            "WHERE"
+                            " account_pub=$1;",
+                            1),
+    GNUNET_PQ_make_prepare ("gc",
+                            "DELETE FROM accounts "
+                            "WHERE"
+                            " expiration_data<$1;",
+                            1),
+    GNUNET_PQ_make_prepare ("backup_insert",
+                            "INSERT INTO backups "
+                            "(account_pub"
+                            ",account_sig"
+                            ",backup_hash"
+                            ",data"
+                            ") VALUES "
+                            "($1,$2,$3,$4);",
+                            4),
+    GNUNET_PQ_make_prepare ("backup_update",
+                            "UPDATE backups "
+                            " SET"
+                            " backup_hash=$1"
+                            ",account_sig=$2"
+                            ",data=$3"
+                            " WHERE"
+                            "   account_pub=$4"
+                            "  AND"
+                            "   backup_hash=$5"
+                            ") VALUES "
+                            "($1,$2,$3,$4,$5);",
+                            5),
+    GNUNET_PQ_make_prepare ("backup_select_hash",
+                            "SELECT "
+                            " backup_hash"
+                            "FROM"
+                            " backups"
+                            "WHERE"
+                            " account_pub=$1;",
+                            1),
+    GNUNET_PQ_make_prepare ("backup_select",
+                            "SELECT "
+                            " account_sig"
+                            ",backup_hash"
+                            ",data"
+                            "FROM"
+                            " backups"
+                            "WHERE"
+                            " account_pub=$1;",
+                            1),
+    GNUNET_PQ_make_prepare ("do_commit",
+                            "COMMIT",
+                            0),
+    GNUNET_PQ_PREPARED_STATEMENT_END
+  };
+
+  pg = GNUNET_new (struct PostgresClosure);
+  pg->cfg = cfg;
+  pg->conn = GNUNET_PQ_connect_with_cfg (cfg,
+                                         "syncdb-postgres",
+                                         es,
+                                         ps);
+  if (NULL == pg->conn)
+  {
+    GNUNET_free (pg);
+    return NULL;
+  }
+  plugin = GNUNET_new (struct SYNC_DatabasePlugin);
+  plugin->cls = pg;
+  plugin->drop_tables = &postgres_drop_tables;
+  plugin->gc = &postgres_gc;
+  plugin->store_backup_TR = &postgres_store_backup;
+  plugin->update_backup_TR = &postgres_update_backup;
+  plugin->increment_lifetime_TR = &postgres_increment_lifetime;
+  return plugin;
+}
+
+
+/**
+ * Shutdown Postgres database subsystem.
+ *
+ * @param cls a `struct SYNC_DB_Plugin`
+ * @return NULL (always)
+ */
+void *
+libsync_plugin_db_postgres_done (void *cls)
+{
+  struct SYNC_DatabasePlugin *plugin = cls;
+  struct PostgresClosure *pg = plugin->cls;
+
+  GNUNET_PQ_disconnect (pg->conn);
+  GNUNET_free (pg);
+  GNUNET_free (plugin);
+  return NULL;
+}
+
+
+/* end of plugin_syncdb_postgres.c */
diff --git a/src/syncdb/sync_db_plugin.c b/src/syncdb/sync_db_plugin.c
index 6b2c6e0..6c4f8d5 100644
--- a/src/syncdb/sync_db_plugin.c
+++ b/src/syncdb/sync_db_plugin.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2015, 2016 GNUnet e.V. and INRIA
+  Copyright (C) 2019 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -14,13 +14,13 @@
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 /**
- * @file merchantdb/merchantdb_plugin.c
+ * @file syncdb/sync_db_plugin.c
  * @brief Logic to load database plugin
  * @author Christian Grothoff
  * @author Sree Harsha Totakura <address@hidden>
  */
 #include "platform.h"
-#include "anastasis_database_plugin.h"
+#include "sync_database_plugin.h"
 #include <ltdl.h>
 
 
@@ -30,27 +30,27 @@
  * @param cfg configuration to use
  * @return #GNUNET_OK on success
  */
-struct ANASTASIS_DatabasePlugin *
-ANASTASIS_DB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg)
+struct SYNC_DatabasePlugin *
+SYNC_DB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   char *plugin_name;
   char *lib_name;
   struct GNUNET_CONFIGURATION_Handle *cfg_dup;
-  struct ANASTASIS_DatabasePlugin *plugin;
+  struct SYNC_DatabasePlugin *plugin;
 
   if (GNUNET_SYSERR ==
       GNUNET_CONFIGURATION_get_value_string (cfg,
-                                             "anastasis",
+                                             "sync",
                                              "db",
                                              &plugin_name))
   {
     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "anastasis",
+                               "sync",
                                "db");
     return NULL;
   }
   (void) GNUNET_asprintf (&lib_name,
-                          "libanastasis_plugin_db_%s",
+                          "libsync_plugin_db_%s",
                           plugin_name);
   GNUNET_free (plugin_name);
   cfg_dup = GNUNET_CONFIGURATION_dup (cfg);
@@ -70,7 +70,7 @@ ANASTASIS_DB_plugin_load (const struct 
GNUNET_CONFIGURATION_Handle *cfg)
  * @param plugin the plugin to unload
  */
 void
-ANASTASIS_DB_plugin_unload (struct ANASTASIS_DatabasePlugin *plugin)
+SYNC_DB_plugin_unload (struct SYNC_DatabasePlugin *plugin)
 {
   char *lib_name;
 
@@ -146,4 +146,4 @@ plugin_fini ()
 }
 
 
-/* end of anastasis_db_plugin.c */
+/* end of sync_db_plugin.c */
diff --git a/src/syncdb/test_sync_db.c b/src/syncdb/test_sync_db.c
index e57a548..55e5c98 100644
--- a/src/syncdb/test_sync_db.c
+++ b/src/syncdb/test_sync_db.c
@@ -1,6 +1,6 @@
 /*
   This file is part of
-  (C) 2014-2017 INRIA
+  (C) 2019 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -16,7 +16,6 @@
 /**
  * @file sync/test_sync_db.c
  * @brief testcase for sync postgres db plugin
- * @author Marcello Stanisci
  * @author Christian Grothoff
  */
 
@@ -50,76 +49,11 @@ static int result;
  */
 static struct SYNC_DatabasePlugin *plugin;
 
-/**
- * Payment Secret for the test, set to a random value
- */
-static struct SYNC_PaymentSecretP paymentSecretP;
-
 /**
  * User public key, set to a random value
  */
 static struct SYNC_AccountPubP accountPubP;
 
-/**
- * Amount which is deposited, set to random value
- */
-static struct TALER_Amount amount;
-
-/**
- * How many posts are paid by the payment
- */
-static unsigned int post_counter;
-
-/**
- * Recoverydata which is stored into the Database, set to a random value
- */
-static void *recovery_data;
-
-/**
- * Recovery_data for the select test
- */
-static void *res_recovery_data;
-
-/**
- * Truthdata which is stored into the Database, set to a random value
- */
-static void *truth_data;
-
-/**
- * Truth for the select test
- */
-static void *truth;
-
-/**
- * Keyshare which is stored into the Database, set to a random value
- */
-static void *key_share;
-
-/**
- * Keyshare for the select test
- */
-static void *res_key_share;
-
-/**
- * Mime-type of truth
- */
-static char *mime_type;
-
-/**
- * Mime-type of truth for the select test
- */
-static char *res_mime_type;
-
-/**
- * Version of a Recoverydocument
- */
-static uint32_t version;
-
-/**
- * Version of the latest Recoverydocument
- */
-static uint32_t res_version;
-
 
 /**
  * Main function that will be run by the scheduler.
@@ -150,6 +84,8 @@ run (void *cls)
     return;
   }
 
+  // FIXME: test logic here!
+
   GNUNET_break (GNUNET_OK ==
                 plugin->drop_tables (plugin->cls));
   SYNC_DB_plugin_unload (plugin);
@@ -197,4 +133,5 @@ main (int argc,
   return result;
 }
 
+
 /* end of test_sync_db.c */
diff --git a/src/syncdb/test_sync_db_postgres.conf 
b/src/syncdb/test_sync_db_postgres.conf
index f91dea1..c020cc7 100644
--- a/src/syncdb/test_sync_db_postgres.conf
+++ b/src/syncdb/test_sync_db_postgres.conf
@@ -1,7 +1,7 @@
-[anastasis]
+[sync]
 #The DB plugin to use
 DB = postgres
 
-[anastasisdb-postgres]
+[syncdb-postgres]
 #The connection string the plugin has to use for connecting to the database
-CONFIG = postgres:///anastasischeck
+CONFIG = postgres:///synccheck
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
new file mode 100644
index 0000000..bc1291c
--- /dev/null
+++ b/src/util/Makefile.am
@@ -0,0 +1,28 @@
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include $(LIBGCRYPT_CFLAGS)
+
+if USE_COVERAGE
+  AM_CFLAGS = --coverage -O0
+  XLIB = -lgcov
+endif
+
+
+pkgcfgdir = $(prefix)/share/sync/config.d/
+
+pkgcfg_DATA = \
+  paths.conf
+
+bin_SCRIPTS = \
+  sync-config
+
+lib_LTLIBRARIES = \
+  libsyncutil.la
+
+libsyncutil_la_SOURCES = \
+  os_installation.c
+libsyncutil_la_LIBADD = \
+  -lgnunetutil \
+  $(XLIB)
+libsyncutil_la_LDFLAGS = \
+  -version-info 0:0:0 \
+  -export-dynamic -no-undefined
diff --git a/src/util/os_installation.c b/src/util/os_installation.c
new file mode 100644
index 0000000..85092d1
--- /dev/null
+++ b/src/util/os_installation.c
@@ -0,0 +1,71 @@
+/*
+     This file is part of GNU Taler.
+     Copyright (C) 2019 Taler Systems SA
+
+     Sync is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     Sync is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with Sync; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file os_installation.c
+ * @brief initialize libgnunet OS subsystem for Sync.
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+
+
+/**
+ * Default project data used for installation path detection
+ * for GNU Sync.
+ */
+static const struct GNUNET_OS_ProjectData sync_pd = {
+  .libname = "libsyncutil",
+  .project_dirname = "sync",
+  .binary_name = "sync-httpd",
+  .env_varname = "SYNC_PREFIX",
+  .base_config_varname = "SYNC_BASE_CONFIG",
+  .bug_email = "address@hidden",
+  .homepage = "http://www.gnu.org/s/taler/";,
+  .config_file = "sync.conf",
+  .user_config_file = "~/.config/sync.conf",
+  .version = PACKAGE_VERSION,
+  .is_gnu = 1,
+  .gettext_domain = "sync",
+  .gettext_path = NULL,
+};
+
+
+/**
+ * Return default project data used by Sync.
+ */
+const struct GNUNET_OS_ProjectData *
+SYNC_project_data_default (void)
+{
+  return &sync_pd;
+}
+
+
+/**
+ * Initialize libsyncutil.
+ */
+void __attribute__ ((constructor))
+SYNC_OS_init ()
+{
+  GNUNET_OS_init (&sync_pd);
+}
+
+
+/* end of os_installation.c */
diff --git a/src/util/sync-config b/src/util/sync-config
new file mode 100644
index 0000000..6184167
--- /dev/null
+++ b/src/util/sync-config
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -eu
+
+if ! type gnunet-config >/dev/null; then
+  echo "$0 needs gnunet-config to be installed"
+  exit 1
+fi
+
+# FIXME: not very portable ...
+# FIXME: should use "libdir" instead of prefix/lib, but somehow
+# the recursive expansion does not work ;-(.
+GC=`which gnunet-config`
+ASAN=""
+A=`ldd $GC | grep libasan` && ASAN=`echo $A | awk '{print $3 ":"}'`
+export LD_PRELOAD=${ASAN}${LD_PRELOAD:-}:/home/grothoff/lib/libsyncutil.so
+exec gnunet-config "$@"

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]