gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28974 - in gnunet/src: include psycstore


From: gnunet
Subject: [GNUnet-SVN] r28974 - in gnunet/src: include psycstore
Date: Wed, 4 Sep 2013 00:33:21 +0200

Author: tg
Date: 2013-09-04 00:33:21 +0200 (Wed, 04 Sep 2013)
New Revision: 28974

Added:
   gnunet/src/psycstore/test_plugin_psycstore.c
   gnunet/src/psycstore/test_plugin_psycstore_sqlite.conf
Modified:
   gnunet/src/include/gnunet_multicast_service.h
   gnunet/src/include/gnunet_protocols.h
   gnunet/src/include/gnunet_psyc_service.h
   gnunet/src/include/gnunet_psycstore_plugin.h
   gnunet/src/include/gnunet_psycstore_service.h
   gnunet/src/include/gnunet_social_service.h
   gnunet/src/psycstore/Makefile.am
   gnunet/src/psycstore/gnunet-service-psycstore.c
   gnunet/src/psycstore/plugin_psycstore_sqlite.c
   gnunet/src/psycstore/psycstore.conf
   gnunet/src/psycstore/psycstore.h
   gnunet/src/psycstore/psycstore_api.c
   gnunet/src/psycstore/test_psycstore.c
   gnunet/src/psycstore/test_psycstore.conf
Log:
PSYCstore SQLite backend; API fixes/enhancements

Modified: gnunet/src/include/gnunet_multicast_service.h
===================================================================
--- gnunet/src/include/gnunet_multicast_service.h       2013-09-03 19:16:43 UTC 
(rev 28973)
+++ gnunet/src/include/gnunet_multicast_service.h       2013-09-03 22:33:21 UTC 
(rev 28974)
@@ -101,7 +101,7 @@
    * unicast requests from members.  Updated at each hop and thus not signed 
and
    * not secure.
    */
-  uint32_t hop_counter GNUNET_PACKED;
+  uint32_t hop_counter;
 
   /** 
    * ECC signature of the message fragment.
@@ -118,19 +118,19 @@
   /** 
    * Number of the message fragment, monotonically increasing.
    */
-  uint64_t fragment_id GNUNET_PACKED;
+  uint64_t fragment_id;
 
   /** 
    * Byte offset of this @e fragment of the @e message.
    */
-  uint64_t fragment_offset GNUNET_PACKED;
+  uint64_t fragment_offset;
 
   /** 
    * Number of the message this fragment belongs to.
    *
    * Set in GNUNET_MULTICAST_origin_to_all().
    */
-  uint64_t message_id GNUNET_PACKED;
+  uint64_t message_id;
 
   /** 
    * Counter that monotonically increases whenever a member parts the group.
@@ -142,15 +142,15 @@
    * is still the same before and after the missed messages, it means that no
    * @e join or @e part operations happened during the missed messages.
    */
-  uint64_t group_generation GNUNET_PACKED;
+  uint64_t group_generation;
 
   /**
    * Flags for this message fragment.
    */
-  enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED;
+  uint32_t flags;
 
   /* Followed by message body. */
-};
+} GNUNET_PACKED;
 
 GNUNET_NETWORK_STRUCT_END
 
@@ -309,7 +309,7 @@
 
 /** 
  * Functions with this signature are called whenever the multicast service 
needs
- * a message to be replayed.
+ * a message fragemnt to be replayed by fragment_id.
  *
  * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
  * (with a message or an error); however, if the origin is destroyed or the
@@ -331,7 +331,7 @@
 
 /** 
  * Functions with this signature are called whenever the multicast service 
needs
- * a message to be replayed.
+ * a message fragment to be replayed by message_id and fragment_offset.
  *
  * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
  * (with a message or an error); however, if the origin is destroyed or the
@@ -404,9 +404,9 @@
  * @param ec Error code.
  */
 void
-GNUNET_MULTICAST_replay (struct GNUNET_MULTICAST_ReplayHandle *rh,
-                         const struct GNUNET_MessageHeader *msg,
-                         enum GNUNET_MULTICAST_ReplayErrorCode ec);
+GNUNET_MULTICAST_replay_response (struct GNUNET_MULTICAST_ReplayHandle *rh,
+                                  const struct GNUNET_MessageHeader *msg,
+                                  enum GNUNET_MULTICAST_ReplayErrorCode ec);
 
 
 /** 
@@ -417,7 +417,7 @@
  * @param rh Replay session to end.
  */
 void
-GNUNET_MULTICAST_replay_end (struct GNUNET_MULTICAST_ReplayHandle *rh);
+GNUNET_MULTICAST_replay_response_end (struct GNUNET_MULTICAST_ReplayHandle 
*rh);
 
 
 /**
@@ -426,9 +426,9 @@
  * @see GNUNET_MULTICAST_replay2()
  */
 typedef int
-(*GNUNET_MULTICAST_ReplayTransmitNotify)(void *cls,
-                                         size_t *data_size,
-                                         void *data);
+(*GNUNET_MULTICAST_ReplayTransmitNotify) (void *cls,
+                                          size_t *data_size,
+                                          void *data);
 
 
 /** 
@@ -439,9 +439,9 @@
  * @param notify_cls Closure for @a notify.
  */
 void
-GNUNET_MULTICAST_replay2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
-                          GNUNET_MULTICAST_ReplayTransmitNotify notify,
-                          void *notify_cls);
+GNUNET_MULTICAST_replay_response2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
+                                   GNUNET_MULTICAST_ReplayTransmitNotify 
notify,
+                                   void *notify_cls);
 
 
 /** 
@@ -465,7 +465,8 @@
  *        when restarting the origin.  0 for a new group.
  * @param join_cb Function called to approve / disapprove joining of a peer.
  * @param test_cb Function multicast can use to test group membership.
- * @param replay_cb Function that can be called to replay a message.
+ * @param replay_frag_cb Function that can be called to replay a message 
fragment.
+ * @param replay_msg_cb Function that can be called to replay a message.
  * @param request_cb Function called with message fragments from group members.
  * @param message_cb Function called with the message fragments sent to the
  *        network by GNUNET_MULTICAST_origin_to_all().  These message fragments
@@ -486,12 +487,13 @@
                                void *cls);
 
 /**
- * Function called to provide data for a transmission from the origin to all 
members.
+ * Function called to provide data for a transmission from the origin to all
+ * members.
  */
 typedef int
-(*GNUNET_MULTICAST_OriginTransmitNotify)(void *cls,
-                                         size_t *data_size,
-                                         void *data);
+(*GNUNET_MULTICAST_OriginTransmitNotify) (void *cls,
+                                          size_t *data_size,
+                                          void *data);
 
 
 /** 
@@ -568,16 +570,14 @@
  *        @a relay (might, for example, contain a user, bind user
  *        identity/pseudonym to peer identity, application-level message to
  *        origin, etc.).
- * @param max_known_fragment_id Largest known message fragment ID to the replay
- *        service; all messages with IDs larger than this ID will be replayed 
if
- *        possible (lower IDs will be considered known and thus only
- *        be replayed upon explicit request).
- *        FIXME: needed? can be optional or moved to a separate function.
  * @param join_cb Function called to approve / disapprove joining of a peer.
  * @param test_cb Function multicast can use to test group membership.
- * @param replay_cb Function that can be called to replay messages
- *        this peer already knows from this group; NULL if this
+ * @param replay_frag_cb Function that can be called to replay message 
fragments
+ *        this peer already knows from this group. NULL if this
  *        client is unable to support replay.
+ * @param replay_msg_cb Function that can be called to replay message fragments
+ *        this peer already knows from this group. NULL if this
+ *        client is unable to support replay.
  * @param message_cb Function to be called for all message fragments we
  *        receive from the group, excluding those our @a replay_cb
  *        already has.
@@ -597,9 +597,9 @@
                               GNUNET_MULTICAST_ReplayFragmentCallback 
replay_frag_cb,
                               GNUNET_MULTICAST_ReplayMessageCallback 
replay_msg_cb,
                               GNUNET_MULTICAST_MessageCallback message_cb,
-                              void *cls);
+                              void *cls)
+;
 
-
 /** 
  * Handle for a replay request.
  */
@@ -633,16 +633,10 @@
  * needed and not known to the client.
  *
  * @param member Membership handle.
- * @param fragment_id ID of a message fragment that this client would like to
-          see replayed.
- * @param message_id ID of a message that this client would like to see
- *        replayed.  Typically only one of the @a fragment_id and @a message_id
- *        is given.  Specifying a @a message_id would return the last fragment
- *        of the message, which allows requesting the preceding fragments of 
the
- *        message by looking at the @e fragment_delta header field.
+ * @param message_id ID of the message this client would like to see replayed.
+ * @param fragment_offset Offset of the fragment within the message to replay.
  * @param flags Additional flags for the replay request.  It is used & defined
- *        by the replay callback.  E.g. the PSYC service would use this to
- *        implement state synchronization.
+ *        by the replay callback.
  * @param result_cb Function to be called for the replayed message.
  * @param result_cb_cls Closure for @a message_cb.
  * @return Replay request handle, NULL on error.
@@ -679,7 +673,7 @@
 GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member);
 
 
-/**
+/** 
  * Function called to provide data for a transmission from a member to the 
origin.
  *
  * @param cls closure
@@ -688,9 +682,9 @@
  * @return number of bytes copied to data
  */
 typedef int
-(*GNUNET_MULTICAST_MemberTransmitNotify)(void *cls,
-                                         size_t *data_size,
-                                         void *data);
+(*GNUNET_MULTICAST_MemberTransmitNotify) (void *cls,
+                                          size_t *data_size,
+                                          void *data);
 
 
 /** 

Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2013-09-03 19:16:43 UTC (rev 
28973)
+++ gnunet/src/include/gnunet_protocols.h       2013-09-03 22:33:21 UTC (rev 
28974)
@@ -1997,7 +1997,7 @@
 /**
  * Multicast message from the origin to all members.
  */
-#define GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE
+#define GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE 700
 
 /**
  * A unicast message from a group member to the origin.

Modified: gnunet/src/include/gnunet_psyc_service.h
===================================================================
--- gnunet/src/include/gnunet_psyc_service.h    2013-09-03 19:16:43 UTC (rev 
28973)
+++ gnunet/src/include/gnunet_psyc_service.h    2013-09-03 22:33:21 UTC (rev 
28974)
@@ -208,9 +208,9 @@
  * @param modifier_count Number of elements in the @a modifiers array.
  * @param modifiers State modifiers and transient variables for the message.
  * @param data_offset Byte offset of @a data in the overall data of the method.
- * @param data_size Number of bytes in @a data.
  * @param data Data stream given to the method (might not be zero-terminated
  *             if data is binary).
+ * @param data_size Number of bytes in @a data.
  * @param frag Fragmentation status for the data.
  */
 typedef int
@@ -221,8 +221,8 @@
                        size_t modifier_count,
                        const struct GNUNET_ENV_Modifier *modifiers,
                        uint64_t data_offset,
+                       const void *data,
                        size_t data_size,
-                       const void *data,
                        enum GNUNET_PSYC_MessageFlags flags);
 
 
@@ -234,9 +234,10 @@
  * @param method_name Method name in the join request.
  * @param variable_count Number of elements in the @a variables array.
  * @param variables Transient variables for the join request.
- * @param data_size Number of bytes in @a data.
  * @param data Data stream given to the method (might not be zero-terminated
  *             if data is binary).
+ * @param data_size Number of bytes in @a data.
+ * @param jh Join handle to use with GNUNET_PSYC_join_decision()
  */
 typedef int
 (*GNUNET_PSYC_JoinCallback) (void *cls,
@@ -244,8 +245,8 @@
                              const char *method_name,
                              size_t variable_count,
                              const struct GNUNET_ENV_Modifier *variables,
+                             const void *data,
                              size_t data_size,
-                             const void *data,
                              struct GNUNET_PSYC_JoinHandle *jh);
 
 
@@ -268,8 +269,8 @@
  *        peer identity in this array.
  * @param method_name Method name for the message transmitted with the 
response.
  * @param env Environment containing transient variables for the message, or 
NULL.
+ * @param data Data of the message.
  * @param data_size Size of @a data.
- * @param data Data of the message.
  */
 void
 GNUNET_PSYC_join_decision (struct GNUNET_PSYC_JoinHandle *jh,
@@ -278,8 +279,8 @@
                            const struct GNUNET_PeerIdentity *relays,
                            const char *method_name,
                            const struct GNUNET_ENV_Environment *env,
-                           size_t data_size,
-                           const void *data);
+                           const void *data,
+                           size_t data_size);
 
 
 /** 
@@ -333,23 +334,22 @@
  * @param cls Closure.
  * @param message_id Set to the unique message ID that was generated for
  *        this message.
- * @param[in,out] data_size Initially set to the number of bytes available in 
@a data,
- *        should be set to the number of bytes written to data (IN/OUT).
- * @param[out] data Where to write the body of the message to give to the 
method;
- *        function must copy at most @a *data_size bytes to @a data.
+ * @param[in,out] data_size Initially set to the number of bytes available in
+ *        @a data, should be set to the number of bytes written to data.
+ * @param[out] data Where to write the body of the message to give to the
+ *         method. The function must copy at most @a data_size bytes to @a 
data.
  * @return #GNUNET_SYSERR on error (fatal, aborts transmission)
  *         #GNUNET_NO on success, if more data is to be transmitted later
- *         (should be used if @a *data_size was not big enough to take all the 
data)
+ *         (should be used if @a data_size was not big enough to take all the 
data)
  *         #GNUNET_YES if this completes the transmission (all data supplied)
  */
 typedef int
-(*GNUNET_PSYC_MasterTransmitNotify)(void *cls,
-                                    uint64_t message_id,
-                                    size_t *data_size,
-                                    void *data);
+(*GNUNET_PSYC_MasterTransmitNotify) (void *cls,
+                                     uint64_t message_id,
+                                     size_t *data_size,
+                                     void *data);
 
 
-
 /**
  * Flags for transmitting messages to a channel by the master.
  */
@@ -450,8 +450,8 @@
  * @param cls Closure for @a method_cb and @a join_cb.
  * @param method_name Method name for the join request.
  * @param env Environment containing transient variables for the request, or 
NULL.
+ * @param data Payload for the join message.
  * @param data_size Number of bytes in @a data.
- * @param data Payload for the join message.
  * @return Handle for the slave, NULL on error.
  */
 struct GNUNET_PSYC_Slave *
@@ -466,8 +466,8 @@
                         void *cls,
                         const char *method_name,
                         const struct GNUNET_ENV_Environment *env,
-                        size_t data_size,
-                        const void *data);
+                        const void *data,
+                        size_t data_size);
 
 
 /** 
@@ -618,7 +618,6 @@
  * @param channel Channel handle.
  * @param slave_key Identity of channel slave to remove.
  * @param announced_at ID of the message that announced the membership change.
- * @param effective_since Removal of slave is in effect since this message ID.
  */
 void
 GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *channel,
@@ -632,14 +631,14 @@
  * @param cls Closure.
  * @param name Name of the state variable.  A NULL value indicates that there
  *        are no more state variables to be returned.
+ * @param value Value of the state variable.
  * @param value_size Number of bytes in @a value.
- * @param value Value of the state variable.
  */
 typedef void
 (*GNUNET_PSYC_StateCallback) (void *cls,
                               const char *name,
-                              size_t value_size,
-                              const void *value);
+                              const void *value,
+                              size_t value_size);
 
 
 /**

Modified: gnunet/src/include/gnunet_psycstore_plugin.h
===================================================================
--- gnunet/src/include/gnunet_psycstore_plugin.h        2013-09-03 19:16:43 UTC 
(rev 28973)
+++ gnunet/src/include/gnunet_psycstore_plugin.h        2013-09-03 22:33:21 UTC 
(rev 28974)
@@ -40,7 +40,7 @@
 
 
 /**
- * @brief struct returned by the initialization function of the plugin
+ * Struct returned by the initialization function of the plugin.
  */
 struct GNUNET_PSYCSTORE_PluginFunctions
 {
@@ -59,9 +59,9 @@
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
-  (*membership_store) (void *cls, 
-                       const struct GNUNET_HashCode *channel_key,
-                       const struct GNUNET_HashCode *slave_key,
+  (*membership_store) (void *cls,
+                       const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                       const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
                        int did_join,
                        uint64_t announced_at,
                        uint64_t effective_since,
@@ -71,7 +71,7 @@
    * Test if a member was admitted to the channel at the given message ID.
    *
    * @see GNUNET_PSYCSTORE_membership_test()
-   * 
+   *
    * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not,
    *         #GNUNET_SYSERR if there was en error.
    */
@@ -79,41 +79,42 @@
   (*membership_test) (void *cls,
                       const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
                       const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
-                      uint64_t message_id,
-                      uint64_t group_generation);
+                      uint64_t message_id);
 
   /** 
    * Store a message fragment sent to a channel.
    *
    * @see GNUNET_PSYCSTORE_fragment_store()
-   * 
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
   (*fragment_store) (void *cls,
                      const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-                     const struct GNUNET_MULTICAST_MessageHeader *message);
+                     const struct GNUNET_MULTICAST_MessageHeader *message,
+                     uint32_t psycstore_flags);
 
   /** 
    * Set additional flags for a given message.
    *
+   * They are OR'd with any existing flags set.
+   *
    * @param message_id ID of the message.
-   * @param flags Flags to add.
-   * 
+   * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags.
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
-  (*fragment_add_flags) (void *cls,
-                         const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-                         uint64_t message_id,
-                         uint64_t multicast_flags,
-                         uint64_t psyc_flags);
+  (*message_add_flags) (void *cls,
+                        const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                        uint64_t message_id,
+                        uint64_t psycstore_flags);
 
   /** 
    * Retrieve a message fragment by fragment ID.
    *
    * @see GNUNET_PSYCSTORE_fragment_get()
-   * 
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
@@ -127,7 +128,7 @@
    * Retrieve all fragments of a message.
    *
    * @see GNUNET_PSYCSTORE_message_get()
-   * 
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
@@ -142,7 +143,7 @@
    * offset.
    *
    * @see GNUNET_PSYCSTORE_message_get_fragment()
-   * 
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
@@ -157,7 +158,7 @@
    * Retrieve latest values of counters for a channel master.
    *
    * @see GNUNET_PSYCSTORE_counters_get_master()
-   * 
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
@@ -168,10 +169,10 @@
                           uint64_t *group_generation);
 
   /** 
-   * Retrieve latest values of counters for a channel slave. 
+   * Retrieve latest values of counters for a channel slave.
    *
    * @see GNUNET_PSYCSTORE_counters_get_slave()
-   * 
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
@@ -183,27 +184,66 @@
    * Set a state variable to the given value.
    *
    * @see GNUNET_PSYCSTORE_state_modify()
-   * 
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
-  (*state_set) (struct GNUNET_PSYCSTORE_Handle *h,
+  (*state_set) (void *cls,
                 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
                 const char *name,
-                size_t value_size,
-                const void *value);
+                const void *value,
+                size_t value_size);
 
+
   /** 
-   * Retrieve a state variable by name.
+   * Reset the state of a channel.
    *
-   * @param name Name of the variable to retrieve.
-   * @param[out] value_size Size of value.
-   * @param[out] value Returned value.
-   * 
+   * Delete all state variables stored for the given channel.
+   *
+   * @see GNUNET_PSYCSTORE_state_reset()
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
-  (*state_get) (struct GNUNET_PSYCSTORE_Handle *h,
+  (*state_reset) (void *cls,
+                  const struct GNUNET_CRYPTO_EccPublicKey *channel_key);
+
+  /**
+   * Update signed state values from the current ones.
+   *
+   * Sets value_signed = value_current for each variable for the given channel.
+   */
+  int
+  (*state_update_signed) (void *cls,
+                          const struct GNUNET_CRYPTO_EccPublicKey 
*channel_key);
+
+  /** 
+   * Update signed values of state variables in the state store.
+   *
+   * @param h Handle for the PSYCstore.
+   * @param channel_key The channel we are interested in.
+   * @param message_id Message ID that contained the state @a hash.
+   * @param hash Hash of the serialized full state.
+   * @param rcb Callback to call with the result of the operation.
+   * @param rcb_cls Closure for the callback.
+   *
+   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+   */
+  int
+  (*state_hash_update) (void *cls,
+                        const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                        uint64_t message_id,
+                        const struct GNUNET_HashCode *hash,
+                        GNUNET_PSYCSTORE_ResultCallback rcb,
+                        void *rcb_cls);
+
+  /** 
+   * Retrieve a state variable by name (exact match).
+   *
+   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+   */
+  int
+  (*state_get) (void *cls,
                 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
                 const char *name,
                 GNUNET_PSYCSTORE_StateCallback cb,
@@ -213,16 +253,28 @@
    * Retrieve all state variables for a channel with the given prefix.
    *
    * @see GNUNET_PSYCSTORE_state_get_all()
-   * 
+   *
    * @return #GNUNET_OK on success, else #GNUNET_SYSERR
    */
   int
-  (*state_get_all) (struct GNUNET_PSYCSTORE_Handle *h,
+  (*state_get_all) (void *cls,
                     const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
                     const char *name,
                     GNUNET_PSYCSTORE_StateCallback cb,
                     void *cb_cls);
 
+
+  /** 
+   * Retrieve all signed state variables for a channel.
+   *
+   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+   */
+  int
+  (*state_get_signed) (void *cls,
+                       const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                       GNUNET_PSYCSTORE_StateCallback cb,
+                       void *cb_cls);
+
 };
 
 

Modified: gnunet/src/include/gnunet_psycstore_service.h
===================================================================
--- gnunet/src/include/gnunet_psycstore_service.h       2013-09-03 19:16:43 UTC 
(rev 28973)
+++ gnunet/src/include/gnunet_psycstore_service.h       2013-09-03 22:33:21 UTC 
(rev 28974)
@@ -45,6 +45,28 @@
  */
 #define GNUNET_PSYCSTORE_VERSION 0x00000000
 
+/**
+ * Flags for stored messages.
+ */
+enum GNUNET_PSYCSTORE_MessageFlags
+{
+  /**
+   * The message contains state modifiers.
+   */
+  GNUNET_PSYCSTORE_MESSAGE_STATE = 1 << 0,
+
+  /**
+   * The state modifiers have been applied to the state store.
+   */
+  GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED = 1 << 1,
+
+  /**
+   * The message contains a state hash.
+   */
+  GNUNET_PSYCSTORE_MESSAGE_STATE_HASH = 1 << 2
+};
+
+
 /** 
  * Handle for a PSYCstore
  */
@@ -157,6 +179,8 @@
  * @param h Handle for the PSYCstore.
  * @param channel_key The channel the message belongs to.
  * @param message Message to store.
+ * @param psycstore_flags Flags indicating whether the PSYC message contains
+ *        state modifiers.
  * @param rcb Callback to call with the result of the operation.
  * @param rcb_cls Closure for the callback.
  * 
@@ -166,6 +190,7 @@
 GNUNET_PSYCSTORE_fragment_store (struct GNUNET_PSYCSTORE_Handle *h,
                                  const struct GNUNET_CRYPTO_EccPublicKey 
*channel_key,
                                  const struct GNUNET_MULTICAST_MessageHeader 
*message,
+                                 uint32_t psycstore_flags,
                                  GNUNET_PSYCSTORE_ResultCallback rcb,
                                  void *rcb_cls);
 
@@ -177,12 +202,15 @@
  * @param cls Closure.
  * @param message The retrieved message fragment.  A NULL value indicates that
  *        there are no more results to be returned.
- * @param flags Message flags indicating fragmentation status.
+ * @param flags Flags stored with the message.
+ *
+ * @return #GNUNET_NO to stop calling this callback with further fragments,
+ *         #GNUNET_YES to continue.
  */
-typedef void
+typedef int
 (*GNUNET_PSYCSTORE_FragmentCallback) (void *cls,
-                                      const struct 
GNUNET_MULTICAST_MessageHeader *message,
-                                      enum GNUNET_PSYC_MessageFlags flags);
+                                      struct GNUNET_MULTICAST_MessageHeader 
*message,
+                                      enum GNUNET_PSYCSTORE_MessageFlags 
flags);
 
 
 /** 
@@ -224,7 +252,8 @@
 
 
 /** 
- * Retrieve a fragment of message specified by its message ID and fragment 
offset.
+ * Retrieve a fragment of message specified by its message ID and fragment
+ * offset.
  *
  * @param h Handle for the PSYCstore.
  * @param channel_key The channel we are interested in.
@@ -267,7 +296,8 @@
  * @see GNUNET_PSYCSTORE_counters_get_slave()
  *
  * @param cls Closure.
- * @param max_state_msg_id Latest message ID containing state modifiers that 
was applied to the state store.  Used for the state sync process.
+ * @param max_state_msg_id Latest message ID containing state modifiers that 
was
+ *        applied to the state store.  Used for the state sync process.
  */
 typedef void
 (*GNUNET_PSYCSTORE_SlaveCountersCallback) (void *cls,
@@ -343,6 +373,26 @@
 
 
 /** 
+ * Reset the state of a channel.
+ *
+ * Delete all state variables stored for the given channel.
+ *
+ * @param h Handle for the PSYCstore.
+ * @param channel_key The channel we are interested in.
+ * @param rcb Callback to call with the result of the operation.
+ * @param rcb_cls Closure for the callback.
+ * 
+ * @return Handle that can be used to cancel the operation.
+ */
+struct GNUNET_PSYCSTORE_Handle *
+GNUNET_PSYCSTORE_state_reset (struct GNUNET_PSYCSTORE_Handle *h,
+                              const struct GNUNET_CRYPTO_EccPublicKey
+                              *channel_key,
+                              GNUNET_PSYCSTORE_ResultCallback rcb,
+                              void *rcb_cls);
+
+
+/** 
  * Update signed values of state variables in the state store.
  *
  * @param h Handle for the PSYCstore.
@@ -368,15 +418,17 @@
  * @param cls Closure.
  * @param name Name of the state variable.  A NULL value indicates that there 
are no more
  *        state variables to be returned.
+ * @param value Value of the state variable.
  * @param value_size Number of bytes in @a value.
- * @param value Value of the state variable.
-t * 
+ *
+ * @return #GNUNET_NO to stop calling this callback with further variables,
+ *         #GNUNET_YES to continue.
  */
-typedef void
+typedef int
 (*GNUNET_PSYCSTORE_StateCallback) (void *cls,
                                    const char *name,
-                                   size_t value_size,
-                                   const void *value);
+                                   const void *value,
+                                   size_t value_size);
 
 
 /** 
@@ -420,10 +472,10 @@
 /** 
  * Cancel an operation.
  *
- * @param oh Handle for the operation to cancel.
+ * @param op Handle for the operation to cancel.
  */
 void
-GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle 
*oh);
+GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle 
*op);
 
 
 

Modified: gnunet/src/include/gnunet_social_service.h
===================================================================
--- gnunet/src/include/gnunet_social_service.h  2013-09-03 19:16:43 UTC (rev 
28973)
+++ gnunet/src/include/gnunet_social_service.h  2013-09-03 22:33:21 UTC (rev 
28974)
@@ -83,21 +83,22 @@
  * @param modifier_count Number of elements in the @a modifiers array.
  * @param modifiers Modifiers present in the message. FIXME: use environment 
instead?
  * @param data_offset Byte offset of @a data in the overall data of the method.
- * @param data_size Number of bytes in @a data.
  * @param data Data stream given to the method (might not be zero-terminated
  *             if data is binary).
+ * @param data_size Number of bytes in @a data.
  * @param flags Message flags indicating fragmentation status.
  */
-typedef int (*GNUNET_SOCIAL_Method)(void *cls,
-                                    struct GNUNET_SOCIAL_Nym *nym,
-                                    const char *full_method_name,
-                                    uint64_t message_id,
-                                    size_t modifier_count,
-                                    GNUNET_PSYC_Modifier *modifiers,
-                                    uint64_t data_offset,
-                                    size_t data_size,
-                                    const void *data,
-                                    enum GNUNET_PSYC_MessageFlags flags);
+typedef int
+(*GNUNET_SOCIAL_Method) (void *cls,
+                         struct GNUNET_SOCIAL_Nym *nym,
+                         const char *full_method_name,
+                         uint64_t message_id,
+                         size_t modifier_count,
+                         GNUNET_PSYC_Modifier *modifiers,
+                         uint64_t data_offset,
+                         const void *data,
+                         size_t data_size,
+                         enum GNUNET_PSYC_MessageFlags flags);
 
 
 /** 
@@ -164,16 +165,17 @@
  * @param method_name Method name in the entry request.
  * @param variable_count Number of elements in the @a variables array.
  * @param variables Variables present in the message.
+ * @param data Payload given on enter (e.g. a password).
  * @param data_size Number of bytes in @a data.
- * @param data Payload given on enter (e.g. a password).
  */
-typedef void (*GNUNET_SOCIAL_AnswerDoorCallback)(void *cls,
-                                                 struct GNUNET_SOCIAL_Nym *nym,
-                                                 size_t variable_count,
-                                                 const char *method_name,
-                                                 GNUNET_PSYC_Modifier 
*variables,
-                                                 size_t data_size,
-                                                 const void *data);
+typedef void
+(*GNUNET_SOCIAL_AnswerDoorCallback) (void *cls,
+                                     struct GNUNET_SOCIAL_Nym *nym,
+                                     size_t variable_count,
+                                     const char *method_name,
+                                     GNUNET_PSYC_Modifier *variables,
+                                     const void *data,
+                                     size_t data_size);
 
 
 /** 
@@ -187,10 +189,11 @@
  * @param variable_count Number of elements in the @a variables array.
  * @param variables Variables present in the message.
  */
-typedef void (*GNUNET_SOCIAL_FarewellCallback)(void *cls,
-                                               struct GNUNET_SOCIAL_Nym *nym,
-                                               size_t variable_count,
-                                               GNUNET_PSYC_Modifier 
*variables);
+typedef void
+(*GNUNET_SOCIAL_FarewellCallback) (void *cls,
+                                   struct GNUNET_SOCIAL_Nym *nym,
+                                   size_t variable_count,
+                                   GNUNET_PSYC_Modifier *variables);
 
 
 /** 
@@ -258,16 +261,16 @@
  * @param nym Handle for the entity that wanted to enter.
  * @param method_name Method name for the rejection message.
  * @param env Environment containing variables for the message, or NULL.
+ * @param data Data for the rejection message to send back.
  * @param data_size Number of bytes in @a data for method.
- * @param data Data for the rejection message to send back.
  */
 void
 GNUNET_SOCIAL_home_reject_entry (struct GNUNET_SOCIAL_Home *home,
                                  struct GNUNET_SOCIAL_Nym *nym,
                                  const char *method_name,
                                  const struct GNUNET_ENV_Environment *env,
-                                 size_t data_size,
-                                 const void *data);
+                                 const void *data,
+                                 size_t data_size);
 
 
 /** 
@@ -403,8 +406,8 @@
  *        pseudonym's place directly.
  * @param method_name Method name for the message.
  * @param env Environment containing variables for the message, or NULL.
+ * @param data Payload for the message to give to the enter callback.
  * @param data_size Number of bytes in @a data.
- * @param data Payload for the message to give to the enter callback.
  * @param slicer Slicer to use for processing incoming requests from guests.
  * @return NULL on errors, otherwise handle to the place.
  */
@@ -414,8 +417,8 @@
                            char *address,
                            const char *method_name,
                            const struct GNUNET_ENV_Environment *env,
+                           const void *data,
                            size_t data_size,
-                           const void *data,
                            struct GNUNET_SOCIAL_Slicer *slicer);
 
 /** 
@@ -429,8 +432,8 @@
  * @param relays Relays for the underlying multicast group.
  * @param method_name Method name for the message.
  * @param env Environment containing variables for the message, or NULL.
+ * @param data Payload for the message to give to the enter callback.
  * @param data_size Number of bytes in @a data.
- * @param data Payload for the message to give to the enter callback.
  * @param slicer Slicer to use for processing incoming requests from guests.
  * @return NULL on errors, otherwise handle to the place.
  */
@@ -443,8 +446,8 @@
                             struct GNUNET_PeerIdentity *relays,
                             const char *method_name,
                             const struct GNUNET_ENV_Environment *env,
+                            const void *data,
                             size_t data_size,
-                            const void *data,
                             struct GNUNET_SOCIAL_Slicer *slicer);
 
 

Modified: gnunet/src/psycstore/Makefile.am
===================================================================
--- gnunet/src/psycstore/Makefile.am    2013-09-03 19:16:43 UTC (rev 28973)
+++ gnunet/src/psycstore/Makefile.am    2013-09-03 22:33:21 UTC (rev 28974)
@@ -22,7 +22,7 @@
 if HAVE_SQLITE
 SQLITE_PLUGIN = libgnunet_plugin_psycstore_sqlite.la
 if HAVE_TESTING
-#SQLITE_TESTS = test_plugin_psycstore_sqlite
+SQLITE_TESTS = test_plugin_psycstore_sqlite
 endif
 endif
 
@@ -99,3 +99,14 @@
   test_psycstore.conf
 
 
+test_plugin_psycstore_sqlite_SOURCES = \
+ test_plugin_psycstore.c
+test_plugin_psycstore_sqlite_LDADD = \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/util/libgnunetutil.la  
+
+test_plugin_psycstore_postgres_SOURCES = \
+ test_plugin_psycstore.c
+test_plugin_psycstore_postgres_LDADD = \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/util/libgnunetutil.la  

Modified: gnunet/src/psycstore/gnunet-service-psycstore.c
===================================================================
--- gnunet/src/psycstore/gnunet-service-psycstore.c     2013-09-03 19:16:43 UTC 
(rev 28973)
+++ gnunet/src/psycstore/gnunet-service-psycstore.c     2013-09-03 22:33:21 UTC 
(rev 28974)
@@ -101,27 +101,72 @@
                  uint32_t result_code,
                  const char *emsg)
 {
-  struct GNUNET_PSYCSTORE_ResultCodeMessage *rcm;
+  struct ResultCodeMessage *rcm;
   size_t elen;
 
   if (NULL == emsg)
     elen = 0;
   else
     elen = strlen (emsg) + 1;
-  rcm = GNUNET_malloc (sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) + 
elen);
+  rcm = GNUNET_malloc (sizeof (struct ResultCodeMessage) + elen);
   rcm->header.type = htons (GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE);
-  rcm->header.size = htons (sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) 
+ elen);
+  rcm->header.size = htons (sizeof (struct ResultCodeMessage) + elen);
   rcm->result_code = htonl (result_code);
   memcpy (&rcm[1], emsg, elen);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Sending result %d (%s) to client\n",
              (int) result_code,
              emsg);
-  GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header, 
GNUNET_NO);
+  GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header,
+                                              GNUNET_NO);
   GNUNET_free (rcm);
 }
 
 
+static void
+handle_membership_store (void *cls,
+                           struct GNUNET_SERVER_Client *client,
+                           const struct GNUNET_MessageHeader *message)
+{
+  const struct MembershipStoreMessage *msg =
+    (const struct MembershipStoreMessage *) message;
+
+  int res = db->membership_store (db->cls, msg->channel_key, msg->slave_key,
+                                  msg->did_join, msg->announced_at,
+                                  msg->effective_since, msg->group_generation);
+
+  if (res != GNUNET_OK)
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Failed to store membership information!\n"));
+
+  send_result_code (client, res, NULL);
+}
+
+
+static void
+handle_membership_test (void *cls,
+                        struct GNUNET_SERVER_Client *client,
+                        const struct GNUNET_MessageHeader *message)
+{
+  const struct MembershipTestMessage *msg =
+    (const struct MembershipTestMessage *) message;
+
+  int res = db->membership_test (db->cls, msg->channel_key, msg->slave_key,
+                                 msg->message_id);
+  switch (res)
+  {
+  case GNUNET_YES:
+  case GNUNET_NO:
+    break;
+  default:
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Failed to test membership!\n"));
+  }
+
+  send_result_code (client, res, NULL);
+}
+
+
 /**
  * Handle PSYCstore clients.
  *
@@ -135,6 +180,12 @@
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
+    {&handle_membership_store, NULL,
+     GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_STORE,
+     sizeof (struct MembershipStoreMessage)},
+    {&handle_membership_test, NULL,
+     GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_TEST,
+     sizeof (struct MembershipTestMessage)},
     {NULL, NULL, 0, 0}
   };
 

Modified: gnunet/src/psycstore/plugin_psycstore_sqlite.c
===================================================================
--- gnunet/src/psycstore/plugin_psycstore_sqlite.c      2013-09-03 19:16:43 UTC 
(rev 28973)
+++ gnunet/src/psycstore/plugin_psycstore_sqlite.c      2013-09-03 22:33:21 UTC 
(rev 28974)
@@ -25,9 +25,16 @@
  * @author Christian Grothoff
  */
 
+/*
+ * FIXME: SQLite3 only supports signed 64-bit integers natively,
+ *        thus it can only store 63 bits of the uint64_t's.
+ */
+
 #include "platform.h"
 #include "gnunet_psycstore_plugin.h"
 #include "gnunet_psycstore_service.h"
+#include "gnunet_multicast_service.h"
+#include "gnunet_crypto_lib.h"
 #include "psycstore.h"
 #include <sqlite3.h>
 
@@ -43,13 +50,14 @@
  */
 #define BUSY_TIMEOUT_MS 1000
 
+#define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING
 
 /**
  * Log an error message at log-level 'level' that indicates
  * a failure of the command 'cmd' on file 'filename'
  * with the message given by strerror(errno).
  */
-#define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, 
"psycstore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, 
__LINE__, sqlite3_errmsg(db->dbh)); } while(0)
+#define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, 
"psycstore-sqlite", _("`%s' failed at %s:%d with error: %s (%d)\n"), cmd, 
__FILE__, __LINE__, sqlite3_errmsg(db->dbh), sqlite3_errcode(db->dbh)); } 
while(0)
 
 #define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__)
 
@@ -100,9 +108,9 @@
   sqlite3_stmt *insert_fragment;
 
   /**
-   * Precompiled SQL for fragment_add_flags()
+   * Precompiled SQL for message_add_flags()
    */
-  sqlite3_stmt *update_fragment_flags;
+  sqlite3_stmt *update_message_flags;
 
   /**
    * Precompiled SQL for fragment_get()
@@ -122,12 +130,12 @@
   /**
    * Precompiled SQL for counters_get_master()
    */
-  sqlite3_stmt *select_master_counters;
+  sqlite3_stmt *select_counters_master;
 
   /**
    * Precompiled SQL for counters_get_slave()
    */
-  sqlite3_stmt *select_slave_counters;
+  sqlite3_stmt *select_counters_slave;
 
 
   /**
@@ -136,11 +144,6 @@
   sqlite3_stmt *insert_state_current;
 
   /**
-   * Precompiled SQL for state_set()
-   */
-  sqlite3_stmt *update_state_current;
-
-  /**
    * Precompiled SQL for state_set_signed()
    */
   sqlite3_stmt *update_state_signed;
@@ -166,6 +169,11 @@
   sqlite3_stmt *delete_state_sync;
 
   /**
+   * Precompiled SQL for state_get_signed()
+   */
+  sqlite3_stmt *select_state_signed;
+
+  /**
    * Precompiled SQL for state_get()
    */
   sqlite3_stmt *select_state_one;
@@ -177,7 +185,16 @@
 
 };
 
+#if DEBUG_PSYCSTORE
 
+static void
+sql_trace (void *cls, const char *sql)
+{
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "SQL query:\n%s\n", sql);
+}
+
+#endif
+
 /**
  * @brief Prepare a SQL statement
  *
@@ -208,8 +225,7 @@
  * @brief Prepare a SQL statement
  *
  * @param dbh handle to the database
- * @param zSql SQL statement, UTF-8 encoded
- * @param ppStmt set to the prepared statement
+ * @param sql SQL statement, UTF-8 encoded
  * @return 0 on success
  */
 static int
@@ -262,7 +278,7 @@
   plugin->fn = filename;
 
   /* Open database and precompile statements */
-  if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
+  if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh))
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
         _("Unable to initialize SQLite: %s.\n"),
@@ -270,6 +286,10 @@
     return GNUNET_SYSERR;
   }
 
+#if DEBUG_PSYCSTORE
+  sqlite3_trace (plugin->dbh, &sql_trace, NULL);
+#endif
+
   sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY");
   sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL");
   sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF");
@@ -284,62 +304,62 @@
   /* Create tables */
 
   sql_exec (plugin->dbh,
-            "CREATE TABLE IF NOT EXISTS channels ("
-            "  id INTEGER PRIMARY KEY,"
-            "  pub_key BLOB UNIQUE"
+            "CREATE TABLE IF NOT EXISTS channels (\n"
+            "  id INTEGER PRIMARY KEY,\n"
+            "  pub_key BLOB UNIQUE\n"
             ");");
 
   sql_exec (plugin->dbh,
-            "CREATE TABLE IF NOT EXISTS slaves ("
-            "  id INTEGER PRIMARY KEY,"
-            "  pub_key BLOB UNIQUE"
+            "CREATE TABLE IF NOT EXISTS slaves (\n"
+            "  id INTEGER PRIMARY KEY,\n"
+            "  pub_key BLOB UNIQUE\n"
             ");");
 
   sql_exec (plugin->dbh,
-            "CREATE TABLE IF NOT EXISTS membership ("
-            "  channel_id INTEGER NOT NULL REFERENCES channels(id),"
-            "  slave_id INTEGER NOT NULL REFERENCES slaves(id),"
-            "  did_join INTEGER NOT NULL,"
-            "  announced_at INTEGER NOT NULL,"
-            "  effective_since INTEGER NOT NULL,"
-            "  group_generation INTEGER NOT NULL"
+            "CREATE TABLE IF NOT EXISTS membership (\n"
+            "  channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
+            "  slave_id INTEGER NOT NULL REFERENCES slaves(id),\n"
+            "  did_join INTEGER NOT NULL,\n"
+            "  announced_at INTEGER NOT NULL,\n"
+            "  effective_since INTEGER NOT NULL,\n"
+            "  group_generation INTEGER NOT NULL\n"
             ");");
   sql_exec (plugin->dbh,
             "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id "
             "ON membership (channel_id, slave_id);");
 
   sql_exec (plugin->dbh,
-            "CREATE TABLE IF NOT EXISTS messages ("
-            "  channel_id INTEGER NOT NULL,"
-            "  hop_counter INTEGER NOT NULL,"
-            "  signature BLOB,"
-            "  purpose BLOB,"
-            "  fragment_id INTEGER NOT NULL,"
-            "  fragment_offset INTEGER NOT NULL,"
-            "  message_id INTEGER NOT NULL,"
-            "  group_generation INTEGER NOT NULL,"
-            "  multicast_flags INTEGER NOT NULL,"
-            "  psyc_flags INTEGER NOT NULL,"
-            "  data BLOB,"
-            "  PRIMARY KEY (channel_id, fragment_id),"
-            "  UNIQUE (channel_id, message_id, fragment_offset)"
+            "CREATE TABLE IF NOT EXISTS messages (\n"
+            "  channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
+            "  hop_counter INTEGER NOT NULL,\n"
+            "  signature BLOB,\n"
+            "  purpose BLOB,\n"
+            "  fragment_id INTEGER NOT NULL,\n"
+            "  fragment_offset INTEGER NOT NULL,\n"
+            "  message_id INTEGER NOT NULL,\n"
+            "  group_generation INTEGER NOT NULL,\n"
+            "  multicast_flags INTEGER NOT NULL,\n"
+            "  psycstore_flags INTEGER NOT NULL,\n"
+            "  data BLOB,\n"
+            "  PRIMARY KEY (channel_id, fragment_id),\n"
+            "  UNIQUE (channel_id, message_id, fragment_offset)\n"
             ");");
 
   sql_exec (plugin->dbh,
-            "CREATE TABLE IF NOT EXISTS state ("
-            "  channel_id INTEGER NOT NULL,"
-            "  name TEXT NOT NULL,"
-            "  value_current BLOB, "
-            "  value_signed BLOB, "
-            "  PRIMARY KEY (channel_id, name)"
+            "CREATE TABLE IF NOT EXISTS state (\n"
+            "  channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
+            "  name TEXT NOT NULL,\n"
+            "  value_current BLOB,\n"
+            "  value_signed BLOB,\n"
+            "  PRIMARY KEY (channel_id, name)\n"
             ");");
 
   sql_exec (plugin->dbh,
-            "CREATE TABLE IF NOT EXISTS state_sync ("
-            "  channel_id INTEGER NOT NULL,"
-            "  name TEXT NOT NULL,"
-            "  value BLOB, "
-            "  PRIMARY KEY (channel_id, name)"
+            "CREATE TABLE IF NOT EXISTS state_sync (\n"
+            "  channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
+            "  name TEXT NOT NULL,\n"
+            "  value BLOB,\n"
+            "  PRIMARY KEY (channel_id, name)\n"
             ");");
 
   /* Prepare statements */
@@ -353,132 +373,143 @@
                &plugin->insert_slave_key);
 
   sql_prepare (plugin->dbh,
-               "INSERT INTO membership "
-               " (channel_id, slave_id, did_join, announced_at, "
-               "  effective_since, group_generation) "
-               "VALUES ((SELECT id FROM channels WHERE pub_key = ?), "
-               "        (SELECT id FROM slaves WHERE pub_key = ?), "
+               "INSERT INTO membership\n"
+               " (channel_id, slave_id, did_join, announced_at,\n"
+               "  effective_since, group_generation)\n"
+               "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n"
+               "        (SELECT id FROM slaves WHERE pub_key = ?),\n"
                "        ?, ?, ?, ?);",
                &plugin->insert_membership);
 
   sql_prepare (plugin->dbh,
-               "SELECT did_join FROM membership "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
"
-               "      AND slave_id = ? AND effective_since <= ? "
+               "SELECT did_join FROM membership\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
+               "      AND slave_id = (SELECT id FROM slaves WHERE pub_key = 
?)\n"
+               "      AND effective_since <= ? AND did_join = 1\n"
                "ORDER BY announced_at DESC LIMIT 1;",
                &plugin->select_membership);
 
   sql_prepare (plugin->dbh,
-               "INSERT INTO messages "
-               " (channel_id, hop_counter, signature, purpose, "
-               "  fragment_id, fragment_offset, message_id, "
-               "  group_generation, multicast_flags, psyc_flags, data) "
-               "VALUES ((SELECT id FROM channels WHERE pub_key = ?), "
+               "INSERT INTO messages\n"
+               " (channel_id, hop_counter, signature, purpose,\n"
+               "  fragment_id, fragment_offset, message_id,\n"
+               "  group_generation, multicast_flags, psycstore_flags, data)\n"
+               "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n"
                "        ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
                &plugin->insert_fragment);
 
   sql_prepare (plugin->dbh,
-               "UPDATE messages "
-               "SET multicast_flags = multicast_flags | ?, "
-               "    psyc_flags = psyc_flags | ? "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
"
-               "      AND message_id = ?;",
-               &plugin->update_fragment_flags);
+               "UPDATE messages\n"
+               "SET psycstore_flags = psycstore_flags | ?\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
+               "      AND message_id = ? AND fragment_offset = 0;",
+               &plugin->update_message_flags);
 
   sql_prepare (plugin->dbh,
-               "SELECT hop_counter, signature, purpose, "
-               "       fragment_offset, message_id, group_generation, "
-               "       multicast_flags, psyc_flags, data "
-               "FROM messages "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
"
+               "SELECT hop_counter, signature, purpose, fragment_id,\n"
+               "       fragment_offset, message_id, group_generation,\n"
+               "       multicast_flags, psycstore_flags, data\n"
+               "FROM messages\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
                "      AND fragment_id = ?;",
                &plugin->select_fragment);
 
   sql_prepare (plugin->dbh,
-               "SELECT hop_counter, signature, purpose, "
-               "       fragment_id, fragment_offset, group_generation, "
-               "       multicast_flags, psyc_flags, data "
-               "FROM messages "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
"
+               "SELECT hop_counter, signature, purpose, fragment_id,\n"
+               "       fragment_offset, message_id, group_generation,\n"
+               "       multicast_flags, psycstore_flags, data\n"
+               "FROM messages\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
                "      AND message_id = ?;",
                &plugin->select_message);
 
   sql_prepare (plugin->dbh,
-               "SELECT hop_counter, signature, purpose, "
-               "       fragment_id, message_id, group_generation, "
-               "       multicast_flags, psyc_flags, data "
-               "FROM messages "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
"
+               "SELECT hop_counter, signature, purpose, fragment_id,\n"
+               "       fragment_offset, message_id, group_generation,\n"
+               "       multicast_flags, psycstore_flags, data\n"
+               "FROM messages\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
                "      AND message_id = ? AND fragment_offset = ?;",
                &plugin->select_message_fragment);
 
   sql_prepare (plugin->dbh,
-               "SELECT max(fragment_id), max(message_id), 
max(group_generation) "
-               "FROM messages "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?);",
-               &plugin->select_master_counters);
+               "SELECT fragment_id, message_id, group_generation\n"
+               "FROM messages\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
+               "ORDER BY fragment_id DESC LIMIT 1;",
+               &plugin->select_counters_master);
 
   sql_prepare (plugin->dbh,
-               "SELECT max(message_id) "
-               "FROM messages "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
"
-               "      AND psyc_flags & ?;",
-               &plugin->select_slave_counters);
+               "SELECT message_id\n"
+               "FROM messages\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
+               "      AND psycstore_flags & ?\n"
+               "ORDER BY message_id DESC LIMIT 1",
+               &plugin->select_counters_slave);
 
   sql_prepare (plugin->dbh,
-               "INSERT OR REPLACE INTO state (channel_id, name, value_current) 
"
-               "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);",
+               "INSERT OR REPLACE INTO state\n"
+               "  (channel_id, name, value_current, value_signed)\n"
+               "SELECT new.channel_id, new.name,\n"
+               "       new.value_current, old.value_signed\n"
+               "FROM (SELECT (SELECT id FROM channels WHERE pub_key = ?)\n"
+               "             AS channel_id,\n"
+               "             ? AS name, ? AS value_current) AS new\n"
+               "LEFT JOIN (SELECT channel_id, name, value_signed\n"
+               "           FROM state) AS old\n"
+               "ON new.channel_id = old.channel_id AND new.name = old.name;",
                &plugin->insert_state_current);
 
   sql_prepare (plugin->dbh,
-               "UPDATE state "
-               "SET value_current = ? "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
"
-               "      AND name = ?;",
-               &plugin->update_state_current);
-
-  sql_prepare (plugin->dbh,
-               "UPDATE state "
-               "SET value_signed = value_current "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
",
+               "UPDATE state\n"
+               "SET value_signed = value_current\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?);",
                &plugin->update_state_signed);
 
   sql_prepare (plugin->dbh,
-               "INSERT INTO state_sync (channel_id, name, value) "
+               "INSERT INTO state_sync (channel_id, name, value)\n"
                "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);",
                &plugin->insert_state_sync);
 
   sql_prepare (plugin->dbh,
-               "DELETE FROM state "
+               "DELETE FROM state\n"
                "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?);",
                &plugin->delete_state);
 
   sql_prepare (plugin->dbh,
-               "INSERT INTO state "
-               " (channel_id, name, value_current, value_signed) "
-               "SELECT channel_id, name, value, value "
-               "FROM state_sync "
+               "INSERT INTO state\n"
+               " (channel_id, name, value_current, value_signed)\n"
+               "SELECT channel_id, name, value, value\n"
+               "FROM state_sync\n"
                "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?);",
                &plugin->insert_state_from_sync);
 
   sql_prepare (plugin->dbh,
-               "DELETE FROM state_sync "
+               "DELETE FROM state_sync\n"
                "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?);",
                &plugin->delete_state_sync);
 
   sql_prepare (plugin->dbh,
-               "SELECT value_current "
-               "FROM state "
-               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) 
"
+               "SELECT value_current\n"
+               "FROM state\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
                "      AND name = ?;",
                &plugin->select_state_one);
 
   sql_prepare (plugin->dbh,
-               "SELECT value_current "
-               "FROM state "
-               "WHERE name LIKE ? OR name LIKE ?;",
+               "SELECT name, value_current\n"
+               "FROM state\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = 
?)\n"
+               "      AND name = ? OR name LIKE ?;",
                &plugin->select_state_prefix);
 
+  sql_prepare (plugin->dbh,
+               "SELECT name, value_signed\n"
+               "FROM state\n"
+               "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)"
+               "      AND value_signed IS NOT NULL;",
+               &plugin->select_state_signed);
+
   return GNUNET_OK;
 }
 
@@ -509,8 +540,8 @@
   if (NULL != plugin->insert_fragment)
     sqlite3_finalize (plugin->insert_fragment);
 
-  if (NULL != plugin->update_fragment_flags)
-    sqlite3_finalize (plugin->update_fragment_flags);
+  if (NULL != plugin->update_message_flags)
+    sqlite3_finalize (plugin->update_message_flags);
 
   if (NULL != plugin->select_fragment)
     sqlite3_finalize (plugin->select_fragment);
@@ -521,18 +552,15 @@
   if (NULL != plugin->select_message_fragment)
     sqlite3_finalize (plugin->select_message_fragment);
 
-  if (NULL != plugin->select_master_counters)
-    sqlite3_finalize (plugin->select_master_counters);
+  if (NULL != plugin->select_counters_master)
+    sqlite3_finalize (plugin->select_counters_master);
 
-  if (NULL != plugin->select_slave_counters)
-    sqlite3_finalize (plugin->select_slave_counters);
+  if (NULL != plugin->select_counters_slave)
+    sqlite3_finalize (plugin->select_counters_slave);
 
   if (NULL != plugin->insert_state_current)
     sqlite3_finalize (plugin->insert_state_current);
 
-  if (NULL != plugin->update_state_current)
-    sqlite3_finalize (plugin->update_state_current);
-
   if (NULL != plugin->update_state_signed)
     sqlite3_finalize (plugin->update_state_signed);
 
@@ -579,6 +607,65 @@
 }
 
 
+static int
+channel_key_store (struct Plugin *plugin,
+                   const struct GNUNET_CRYPTO_EccPublicKey *channel_key)
+{
+  sqlite3_stmt *stmt = plugin->insert_channel_key;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_channel_key (bind)");
+  }
+  else if (SQLITE_DONE != sqlite3_step (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_channel_key (step)");
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_channel_key (reset)");
+    return GNUNET_SYSERR;
+  }
+
+  return GNUNET_OK;
+}
+
+
+static int
+slave_key_store (struct Plugin *plugin,
+                 const struct GNUNET_CRYPTO_EccPublicKey *slave_key)
+{
+  sqlite3_stmt *stmt = plugin->insert_slave_key;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, slave_key,
+                                      sizeof (*slave_key), SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_slave_key (bind)");
+  }
+  else if (SQLITE_DONE != sqlite3_step (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_slave_key (step)");
+  }
+
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_slave_key (reset)");
+    return GNUNET_SYSERR;
+  }
+
+  return GNUNET_OK;
+}
+
+
 /** 
  * Store join/leave events for a PSYC channel in order to be able to answer
  * membership test queries later.
@@ -587,17 +674,56 @@
  *
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_membership_store
- (void *cls, 
-  const struct GNUNET_HashCode *channel_key,
-  const struct GNUNET_HashCode *slave_key,
-  int did_join,
-  uint64_t announced_at,
-  uint64_t effective_since,
-  uint64_t group_generation) {
+static int
+membership_store (void *cls,
+                  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                  const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
+                  int did_join,
+                  uint64_t announced_at,
+                  uint64_t effective_since,
+                  uint64_t group_generation)
+{
+  if (announced_at > INT64_MAX ||
+      effective_since > INT64_MAX ||
+      group_generation > INT64_MAX)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
 
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->insert_membership;
 
+  if (GNUNET_OK != channel_key_store (plugin, channel_key) ||
+      GNUNET_OK != slave_key_store (plugin, slave_key))
+    return GNUNET_SYSERR;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key,
+                                      sizeof (*slave_key), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int (stmt, 3, did_join) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 4, announced_at) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 5, effective_since) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 6, group_generation))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_membership (bind)");
+  }
+  else if (SQLITE_DONE != sqlite3_step (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_membership (step)");
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_membership (reset)");
+    return GNUNET_SYSERR;
+  }
+
+  return GNUNET_OK;
 }
 
 /** 
@@ -608,14 +734,44 @@
  * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not,
  *         #GNUNET_SYSERR if there was en error.
  */
-int
-libgnunet_plugin_psycstore_sqlite_membership_test
- (void *cls,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
-  uint64_t message_id,
-  uint64_t group_generation) {
+static int
+membership_test (void *cls,
+                 const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                 const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
+                 uint64_t message_id)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->select_membership;
+  int ret = GNUNET_SYSERR;
 
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key,
+                                      sizeof (*slave_key), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_membership (bind)");
+  }
+  else
+  {
+    switch (sqlite3_step (stmt))
+    {
+    case SQLITE_DONE:
+      ret = GNUNET_NO;
+      break;
+    case SQLITE_ROW:
+      ret = GNUNET_YES;
+    }
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_membership (reset)");
+  }
+
+  return ret;
 }
 
 /** 
@@ -625,32 +781,143 @@
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_fragment_store
- (void *cls,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  const struct GNUNET_MULTICAST_MessageHeader *message) {
+static int
+fragment_store (void *cls,
+                const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                const struct GNUNET_MULTICAST_MessageHeader *msg,
+                uint32_t psycstore_flags)
+{
+  if (msg->fragment_id > INT64_MAX ||
+      msg->fragment_offset > INT64_MAX ||
+      msg->message_id > INT64_MAX ||
+      msg->group_generation > INT64_MAX)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
 
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->insert_fragment;
+
+  if (GNUNET_OK != channel_key_store (plugin, channel_key))
+    return GNUNET_SYSERR;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 2, msg->hop_counter ) ||
+      SQLITE_OK != sqlite3_bind_blob (stmt, 3, (const void *) &msg->signature,
+                                      sizeof (msg->signature), SQLITE_STATIC) 
||
+      SQLITE_OK != sqlite3_bind_blob (stmt, 4, (const void *) &msg->purpose,
+                                      sizeof (msg->purpose), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 5, msg->fragment_id) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 6, msg->fragment_offset) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 7, msg->message_id) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 8, msg->group_generation) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 9, msg->flags) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 10, psycstore_flags) ||
+      SQLITE_OK != sqlite3_bind_blob (stmt, 11, (const void *) &msg[1],
+                                      ntohs (msg->header.size) - sizeof (*msg),
+                                      SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_fragment (bind)");
+  }
+  else if (SQLITE_DONE != sqlite3_step (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_fragment (step)");
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_fragment (reset)");
+    return GNUNET_SYSERR;
+  }
+
+  return GNUNET_OK;
 }
 
 /** 
  * Set additional flags for a given message.
  *
+ * They are OR'd with any existing flags set.
+ *
+ * @param plugin Plugin handle. 
+ * @param channel_key Public key of the channel.
  * @param message_id ID of the message.
- * @param flags Flags to add.
+ * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags.
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_fragment_add_flags
- (void *cls,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  uint64_t message_id,
-  uint64_t multicast_flags,
-  uint64_t psyc_flags) {
+static int
+message_add_flags (void *cls,
+                   const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                   uint64_t message_id,
+                   uint64_t psycstore_flags)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->update_message_flags;
+  int ret = GNUNET_SYSERR;
 
+  if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, psycstore_flags) ||
+      SQLITE_OK != sqlite3_bind_blob (stmt, 2, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "update_message_flags (bind)");
+  }
+  else
+  {
+    switch (sqlite3_step (stmt))
+    {
+    case SQLITE_DONE:
+      ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO;
+      break;
+    default:
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                  "update_message_flags (step)");
+    }
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "update_message_flags (reset)");
+    return GNUNET_SYSERR;
+  }
+
+  return ret;
 }
 
+static int
+fragment_row (sqlite3_stmt *stmt, GNUNET_PSYCSTORE_FragmentCallback cb,
+              void *cb_cls)
+{
+  int data_size = sqlite3_column_bytes (stmt, 9);
+  struct GNUNET_MULTICAST_MessageHeader *msg
+    = GNUNET_malloc (sizeof (*msg) + data_size);
+
+  msg->header.size = htons (sizeof (*msg) + data_size);
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE);
+  msg->hop_counter = (uint32_t) sqlite3_column_int64 (stmt, 0);
+  memcpy (&msg->signature,
+          sqlite3_column_blob (stmt, 1),
+          sqlite3_column_bytes (stmt, 1));
+  memcpy (&msg->purpose,
+          sqlite3_column_blob (stmt, 2),
+          sqlite3_column_bytes (stmt, 2));
+  msg->fragment_id = sqlite3_column_int64 (stmt, 3);
+  msg->fragment_offset = sqlite3_column_int64 (stmt, 4);
+  msg->message_id = sqlite3_column_int64 (stmt, 5);
+  msg->group_generation = sqlite3_column_int64 (stmt, 6);
+  msg->flags = sqlite3_column_int64 (stmt, 7);
+  memcpy (&msg[1], sqlite3_column_blob (stmt, 9), data_size);
+
+  return cb (cb_cls, (void *) msg, sqlite3_column_int64 (stmt, 8));
+}
+
 /** 
  * Retrieve a message fragment by fragment ID.
  *
@@ -658,14 +925,49 @@
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_fragment_get
- (void *cls,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  uint64_t fragment_id,
-  GNUNET_PSYCSTORE_FragmentCallback cb,
-  void *cb_cls) {
+static int
+fragment_get (void *cls,
+              const struct
+              GNUNET_CRYPTO_EccPublicKey *channel_key,
+              uint64_t fragment_id,
+              GNUNET_PSYCSTORE_FragmentCallback cb,
+              void *cb_cls)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->select_fragment;
+  int ret = GNUNET_SYSERR;
 
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key),
+                                      SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 2, fragment_id))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_fragment (bind)");
+  }
+  else
+  {
+    switch (sqlite3_step (stmt))
+    {
+    case SQLITE_DONE:
+      ret = GNUNET_NO;
+      break;
+    case SQLITE_ROW:
+      ret = fragment_row (stmt, cb, cb_cls);
+      break;
+    default:
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                  "select_fragment (step)");
+    }
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_fragment (reset)");
+  }
+
+  return ret;
 }
 
 /** 
@@ -675,14 +977,57 @@
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_message_get
- (void *cls,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  uint64_t message_id,
-  GNUNET_PSYCSTORE_FragmentCallback cb,
-  void *cb_cls) {
+static int
+message_get (void *cls,
+             const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+             uint64_t message_id,
+             GNUNET_PSYCSTORE_FragmentCallback cb,
+             void *cb_cls)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->select_message;
+  int ret = GNUNET_SYSERR;
 
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key),
+                                      SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_message (bind)");
+  }
+  else
+  {
+    int sql_ret;
+    do
+    {
+      sql_ret = sqlite3_step (stmt);
+      switch (sql_ret)
+      {
+      case SQLITE_DONE:
+        if (ret != GNUNET_OK)
+          ret = GNUNET_NO;
+        break;
+      case SQLITE_ROW:
+        ret = fragment_row (stmt, cb, cb_cls);
+        if (ret != GNUNET_YES)
+          sql_ret = SQLITE_DONE;
+        break;
+      default:
+        LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                    "select_message (step)");
+      }
+    }
+    while (sql_ret == SQLITE_ROW);
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_message (reset)");
+  }
+
+  return ret;
 }
 
 /** 
@@ -693,16 +1038,51 @@
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_message_get_fragment
- (void *cls,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  uint64_t message_id,
-  uint64_t fragment_offset,
-  GNUNET_PSYCSTORE_FragmentCallback cb,
-  void *cb_cls)
+static int
+message_get_fragment (void *cls,
+                      const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                      uint64_t message_id,
+                      uint64_t fragment_offset,
+                      GNUNET_PSYCSTORE_FragmentCallback cb,
+                      void *cb_cls)
 {
+  struct Plugin *plugin = cls;
+  int ret = GNUNET_SYSERR;
 
+  sqlite3_stmt *stmt = plugin->select_message_fragment;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key),
+                                      SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 3, fragment_offset))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_message_fragment (bind)");
+  }
+  else
+  {
+    switch (sqlite3_step (stmt))
+    {
+    case SQLITE_DONE:
+      ret = GNUNET_NO;
+      break;
+    case SQLITE_ROW:
+      ret = fragment_row (stmt, cb, cb_cls);
+      break;
+    default:
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                  "select_message_fragment (step)");
+    }
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_message_fragment (reset)");
+  }
+
+  return ret;
 }
 
 /** 
@@ -712,15 +1092,50 @@
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_counters_get_master
- (void *cls,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  uint64_t *fragment_id,
-  uint64_t *message_id,
-  uint64_t *group_generation)
+static int
+counters_get_master (void *cls,
+                     const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                     uint64_t *fragment_id,
+                     uint64_t *message_id,
+                     uint64_t *group_generation)
 {
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->select_counters_master;
+  int ret = GNUNET_SYSERR;
 
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key),
+                                      SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_counters_master (bind)");
+  }
+  else
+  {
+    switch (sqlite3_step (stmt))
+    {
+    case SQLITE_DONE:
+      ret = GNUNET_NO;
+      break;
+    case SQLITE_ROW:
+      *fragment_id = sqlite3_column_int64 (stmt, 0);
+      *message_id = sqlite3_column_int64 (stmt, 1);
+      *group_generation = sqlite3_column_int64 (stmt, 2);
+      ret = GNUNET_OK;
+      break;
+    default:
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                  "select_counters_master (step)");
+    }
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_counters_master (reset)");
+  }
+
+  return ret;
 }
 
 /** 
@@ -730,12 +1145,48 @@
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_counters_get_slave
- (void *cls,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  uint64_t *max_state_msg_id) {
+static int
+counters_get_slave (void *cls,
+                    const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                    uint64_t *max_state_msg_id)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->select_counters_slave;
+  int ret = GNUNET_SYSERR;
 
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key),
+                                      SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_int64 (stmt, 2,
+                                       GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_counters_slave (bind)");
+  }
+  else
+  {
+    switch (sqlite3_step (stmt))
+    {
+    case SQLITE_DONE:
+      ret = GNUNET_NO;
+      break;
+    case SQLITE_ROW:
+      *max_state_msg_id = sqlite3_column_int64 (stmt, 0);
+      ret = GNUNET_OK;
+      break;
+    default:
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                  "select_counters_slave (step)");
+    }
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_counters_slave (reset)");
+  }
+
+  return ret;
 }
 
 /** 
@@ -745,35 +1196,174 @@
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_state_set
- (struct GNUNET_PSYCSTORE_Handle *h,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  const char *name,
-  size_t value_size,
-  const void *value) {
+static int
+state_set (void *cls,
+           const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+           const char *name, const void *value, size_t value_size)
+{
+  struct Plugin *plugin = cls;
+  int ret = GNUNET_SYSERR;
 
+  sqlite3_stmt *stmt = plugin->insert_state_current;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_blob (stmt, 3, value, value_size,
+                                      SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_state_current (bind)");
+  }
+  else
+  {
+    switch (sqlite3_step (stmt))
+    {
+    case SQLITE_DONE:
+      ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO;
+      break;
+    default:
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                  "insert_state_current (step)");
+    }
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "insert_state_current (reset)");
+    return GNUNET_SYSERR;
+  }
+
+  return ret;
 }
 
+
 /** 
+ * Reset the state of a channel.
+ *
+ * @see GNUNET_PSYCSTORE_state_reset()
+ * 
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+static int
+state_reset (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->delete_state;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "delete_state (bind)");
+  }
+  else if (SQLITE_DONE != sqlite3_step (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "delete_state (step)");
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "delete_state (reset)");
+    return GNUNET_SYSERR;
+  }
+
+  return GNUNET_OK;
+}
+
+
+/** 
+ * Update signed values of state variables in the state store.
+ *
+ * @see GNUNET_PSYCSTORE_state_hash_update()
+ * 
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+static int
+state_update_signed (void *cls,
+                     const struct GNUNET_CRYPTO_EccPublicKey *channel_key)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt = plugin->update_state_signed;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "update_state_signed (bind)");
+  }
+  else if (SQLITE_DONE != sqlite3_step (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "update_state_signed (step)");
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "update_state_signed (reset)");
+    return GNUNET_SYSERR;
+  }
+
+  return GNUNET_OK;
+}
+
+
+/** 
  * Retrieve a state variable by name.
  *
- * @param name Name of the variable to retrieve.
- * @param[out] value_size Size of value.
- * @param[out] value Returned value.
+ * @see GNUNET_PSYCSTORE_state_get()
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_state_get
- (struct GNUNET_PSYCSTORE_Handle *h,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  const char *name,
-  GNUNET_PSYCSTORE_StateCallback cb,
-  void *cb_cls) {
+static int
+state_get (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+           const char *name, GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls)
+{
+  struct Plugin *plugin = cls;
+  int ret = GNUNET_SYSERR;
 
+  sqlite3_stmt *stmt = plugin->select_state_one;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key),
+                                      SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_state_one (bind)");
+  }
+  else
+  {
+    switch (sqlite3_step (stmt))
+    {
+    case SQLITE_DONE:
+      ret = GNUNET_NO;
+      break;
+    case SQLITE_ROW:
+      ret = cb (cb_cls, name, sqlite3_column_blob (stmt, 0),
+                sqlite3_column_bytes (stmt, 0));
+      break;
+    default:
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                  "select_state_one (step)");
+    }
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_state_one (reset)");
+  }
+  
+
+  return ret;
 }
 
+
 /** 
  * Retrieve all state variables for a channel with the given prefix.
  *
@@ -781,21 +1371,130 @@
  * 
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
-int
-libgnunet_plugin_psycstore_sqlite_state_get_all
- (struct GNUNET_PSYCSTORE_Handle *h,
-  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
-  const char *name,
-  GNUNET_PSYCSTORE_StateCallback cb,
-  void *cb_cls) {
+static int
+state_get_all (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+               const char *name, GNUNET_PSYCSTORE_StateCallback cb,
+               void *cb_cls)
+{
+  struct Plugin *plugin = cls;
+  int ret = GNUNET_SYSERR;
 
+  sqlite3_stmt *stmt = plugin->select_state_prefix;
+  size_t name_len = strlen (name);
+  char *name_prefix = GNUNET_malloc (name_len + 2);
+  memcpy (name_prefix, name, name_len);
+  memcpy (name_prefix + name_len, "_%", 2);
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC) ||
+      SQLITE_OK != sqlite3_bind_text (stmt, 2, name, name_len, SQLITE_STATIC) 
||
+      SQLITE_OK != sqlite3_bind_text (stmt, 3, name_prefix, name_len + 2,
+                                      SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_state_prefix (bind)");
+  }
+  else
+  {
+    int sql_ret;
+    do
+    {
+      sql_ret = sqlite3_step (stmt);
+      switch (sql_ret)
+      {
+      case SQLITE_DONE:
+        if (ret != GNUNET_OK)
+          ret = GNUNET_NO;
+        break;
+      case SQLITE_ROW:
+        ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0),
+                  sqlite3_column_blob (stmt, 1),
+                  sqlite3_column_bytes (stmt, 1));
+        if (ret != GNUNET_YES)
+          sql_ret = SQLITE_DONE;
+        break;
+      default:
+        LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                    "select_state_prefix (step)");
+      }
+    }
+    while (sql_ret == SQLITE_ROW);
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_state_prefix (reset)");
+  }
+
+  return ret;
 }
 
 
-/**
+/** 
+ * Retrieve all signed state variables for a channel.
+ *
+ * @see GNUNET_PSYCSTORE_state_get_signed()
+ * 
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ */
+static int
+state_get_signed (void *cls,
+                  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+                  GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls)
+{
+  struct Plugin *plugin = cls;
+  int ret = GNUNET_SYSERR;
+
+  sqlite3_stmt *stmt = plugin->select_state_signed;
+
+  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
+                                      sizeof (*channel_key), SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_state_signed (bind)");
+  }
+  else
+  {
+    int sql_ret;
+    do
+    {
+      sql_ret = sqlite3_step (stmt);
+      switch (sql_ret)
+      {
+      case SQLITE_DONE:
+        if (ret != GNUNET_OK)
+          ret = GNUNET_NO;
+        break;
+      case SQLITE_ROW:
+        ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0),
+                  sqlite3_column_blob (stmt, 1),
+                  sqlite3_column_bytes (stmt, 1));
+        if (ret != GNUNET_YES)
+          sql_ret = SQLITE_DONE;
+        break;
+      default:
+        LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                    "select_state_signed (step)");
+      }
+    }
+    while (sql_ret == SQLITE_ROW);
+  }
+
+  if (SQLITE_OK != sqlite3_reset (stmt))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                "select_state_signed (reset)");
+  }
+
+  return ret;
+}
+
+
+/** 
  * Entry point for the plugin.
  *
- * @param cls the "struct GNUNET_PSYCSTORE_PluginEnvironment*"
+ * @param cls The struct GNUNET_CONFIGURATION_Handle.
  * @return NULL on error, otherwise the plugin context
  */
 void *
@@ -816,21 +1515,23 @@
   }
   api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions);
   api->cls = &plugin;
-  api->membership_store = &libgnunet_plugin_psycstore_sqlite_membership_store;
-  api->membership_test = &libgnunet_plugin_psycstore_sqlite_membership_test;
-  api->fragment_store = &libgnunet_plugin_psycstore_sqlite_fragment_store;
-  api->fragment_add_flags = 
&libgnunet_plugin_psycstore_sqlite_fragment_add_flags;
-  api->fragment_get = &libgnunet_plugin_psycstore_sqlite_fragment_get;
-  api->message_get = &libgnunet_plugin_psycstore_sqlite_message_get;
-  api->message_get_fragment = 
&libgnunet_plugin_psycstore_sqlite_message_get_fragment;
-  api->counters_get_master = 
&libgnunet_plugin_psycstore_sqlite_counters_get_master;
-  api->counters_get_slave = 
&libgnunet_plugin_psycstore_sqlite_counters_get_slave;
-  api->state_set = &libgnunet_plugin_psycstore_sqlite_state_set;
-  api->state_get = &libgnunet_plugin_psycstore_sqlite_state_get;
-  api->state_get_all = &libgnunet_plugin_psycstore_sqlite_state_get_all;
+  api->membership_store = &membership_store;
+  api->membership_test = &membership_test;
+  api->fragment_store = &fragment_store;
+  api->message_add_flags = &message_add_flags;
+  api->fragment_get = &fragment_get;
+  api->message_get = &message_get;
+  api->message_get_fragment = &message_get_fragment;
+  api->counters_get_master = &counters_get_master;
+  api->counters_get_slave = &counters_get_slave;
+  api->state_set = &state_set;
+  api->state_reset = &state_reset;
+  api->state_update_signed = &state_update_signed;
+  api->state_get = &state_get;
+  api->state_get_all = &state_get_all;
+  api->state_get_signed = &state_get_signed;
 
-  LOG (GNUNET_ERROR_TYPE_INFO, 
-       _("Sqlite database running\n"));
+  LOG (GNUNET_ERROR_TYPE_INFO, _("SQLite database running\n"));
   return api;
 }
 
@@ -838,8 +1539,8 @@
 /**
  * Exit point from the plugin.
  *
- * @param cls the plugin context (as returned by "init")
- * @return always NULL
+ * @param cls The plugin context (as returned by "init")
+ * @return Always NULL
  */
 void *
 libgnunet_plugin_psycstore_sqlite_done (void *cls)
@@ -850,8 +1551,7 @@
   database_shutdown (plugin);
   plugin->cfg = NULL;
   GNUNET_free (api);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, 
-       "sqlite plugin is finished\n");
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "SQLite plugin is finished\n");
   return NULL;
 }
 

Modified: gnunet/src/psycstore/psycstore.conf
===================================================================
--- gnunet/src/psycstore/psycstore.conf 2013-09-03 19:16:43 UTC (rev 28973)
+++ gnunet/src/psycstore/psycstore.conf 2013-09-03 22:33:21 UTC (rev 28974)
@@ -2,7 +2,7 @@
 AUTOSTART = YES
 HOME = $SERVICEHOME
 BINARY = gnunet-service-psycstore
-UNIXPATH = /tmp/gnunet-service-psycstore.unix
+UNIXPATH = /tmp/gnunet-service-psycstore.sock
 UNIX_MATCH_UID = NO
 UNIX_MATCH_GID = YES
 DATABASE = sqlite

Modified: gnunet/src/psycstore/psycstore.h
===================================================================
--- gnunet/src/psycstore/psycstore.h    2013-09-03 19:16:43 UTC (rev 28973)
+++ gnunet/src/psycstore/psycstore.h    2013-09-03 22:33:21 UTC (rev 28974)
@@ -35,7 +35,7 @@
 /**
  * Answer from service to client about last operation.
  */
-struct GNUNET_PSYCSTORE_ResultCodeMessage
+struct ResultCodeMessage
 {
   /**
    * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE
@@ -52,6 +52,32 @@
 
 };
 
+
+/**
+ * @see GNUNET_PSYCSTORE_membership_store()
+ */
+struct MembershipStoreMessage
+{
+  const struct GNUNET_CRYPTO_EccPublicKey *channel_key;
+  const struct GNUNET_CRYPTO_EccPublicKey *slave_key;
+  int did_join;
+  uint64_t announced_at;
+  uint64_t effective_since;
+  uint64_t group_generation;
+};
+
+
+/**
+ * @see GNUNET_PSYCSTORE_membership_test()
+ */
+struct MembershipTestMessage
+{
+  const struct GNUNET_CRYPTO_EccPublicKey *channel_key;
+  const struct GNUNET_CRYPTO_EccPublicKey *slave_key;
+  uint64_t message_id;
+  uint64_t group_generation;
+};
+
 GNUNET_NETWORK_STRUCT_END
 
 #endif

Modified: gnunet/src/psycstore/psycstore_api.c
===================================================================
--- gnunet/src/psycstore/psycstore_api.c        2013-09-03 19:16:43 UTC (rev 
28973)
+++ gnunet/src/psycstore/psycstore_api.c        2013-09-03 22:33:21 UTC (rev 
28974)
@@ -187,7 +187,7 @@
 {
   struct GNUNET_PSYCSTORE_Handle *h = cls;
   struct GNUNET_PSYCSTORE_OperationHandle *op;
-  const struct GNUNET_PSYCSTORE_ResultCodeMessage *rcm;
+  const struct ResultCodeMessage *rcm;
   const char *str;
   uint16_t size;
 
@@ -203,22 +203,22 @@
   switch (ntohs (msg->type))
   {
   case GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE:
-    if (size < sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage))
+    if (size < sizeof (struct ResultCodeMessage))
     {
       GNUNET_break (0);
       reschedule_connect (h);
       return;
     }
-    rcm = (const struct GNUNET_PSYCSTORE_ResultCodeMessage *) msg;
+    rcm = (const struct ResultCodeMessage *) msg;
     str = (const char *) &rcm[1];
-    if ( (size > sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)) &&
-        ('\0' != str[size - sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) 
- 1]) )
+    if ( (size > sizeof (struct ResultCodeMessage)) &&
+        ('\0' != str[size - sizeof (struct ResultCodeMessage) - 1]) )
     {
       GNUNET_break (0);
       reschedule_connect (h);
       return;
     }
-    if (size == sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage))
+    if (size == sizeof (struct ResultCodeMessage))
       str = NULL;
 
     op = h->op_head;
@@ -341,7 +341,6 @@
   h->client = GNUNET_CLIENT_connect ("psycstore", h->cfg);
   GNUNET_assert (NULL != h->client);
   transmit_next (h);
-  GNUNET_assert (NULL != h->th);
 }
 
 
@@ -399,7 +398,7 @@
  * was already transmitted, the service may still choose to complete
  * the operation.
  *
- * @param op operation to cancel
+ * @param op Operation to cancel.
  */
 void
 GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op)
@@ -435,4 +434,33 @@
 }
 
 
+struct GNUNET_PSYCSTORE_OperationHandle *
+GNUNET_PSYCSTORE_membership_store (
+  struct GNUNET_PSYCSTORE_Handle *h,
+  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+  const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
+  int did_join,
+  uint64_t announced_at,
+  uint64_t effective_since,
+  uint64_t group_generation,
+  GNUNET_PSYCSTORE_ResultCallback rcb,
+  void *rcb_cls)
+{
+  
+}
+
+
+struct GNUNET_PSYCSTORE_OperationHandle *
+GNUNET_PSYCSTORE_membership_test (
+  struct GNUNET_PSYCSTORE_Handle *h,
+  const struct GNUNET_CRYPTO_EccPublicKey *channel_key,
+  const struct GNUNET_CRYPTO_EccPublicKey *slave_key,
+  uint64_t message_id,
+  uint64_t group_generation,
+  GNUNET_PSYCSTORE_ResultCallback rcb,
+  void *rcb_cls)
+{
+
+}
+
 /* end of psycstore_api.c */

Added: gnunet/src/psycstore/test_plugin_psycstore.c
===================================================================
--- gnunet/src/psycstore/test_plugin_psycstore.c                                
(rev 0)
+++ gnunet/src/psycstore/test_plugin_psycstore.c        2013-09-03 22:33:21 UTC 
(rev 28974)
@@ -0,0 +1,375 @@
+/*
+     This file is part of GNUnet.
+     (C) 2012 Christian Grothoff (and other contributing authors)
+
+     GNUnet 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.
+
+     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
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/*
+ * @file psycstore/test_plugin_psycstore.c
+ * @brief Test for the psycstore plugins
+ * @author Gabor X Toth
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_lib.h"
+#include "gnunet_psycstore_plugin.h"
+#include "gnunet_psycstore_service.h"
+#include "gnunet_multicast_service.h"
+
+#define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING
+#if DEBUG_PSYCSTORE
+# define LOG_LEVEL "DEBUG"
+#else
+# define LOG_LEVEL "WARNING"
+#endif
+
+#define C2ARG(str) str, (sizeof (str) - 1)
+
+#define LOG(kind,...) GNUNET_log_from (kind, "test-plugin-psycstore", 
__VA_ARGS__)
+
+#define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, 
__LINE__); goto FAILURE;} } while (0)
+
+static int ok;
+
+/**
+ * Name of plugin under test.
+ */
+static const char *plugin_name;
+
+static struct GNUNET_CRYPTO_EccPrivateKey *channel_key;
+static struct GNUNET_CRYPTO_EccPrivateKey *slave_key;
+
+static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key;
+static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key;
+
+/**
+ * Function called when the service shuts down.  Unloads our psycstore
+ * plugin.
+ *
+ * @param api api to unload
+ */
+static void
+unload_plugin (struct GNUNET_PSYCSTORE_PluginFunctions *api)
+{
+  char *libname;
+
+  GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name);
+  GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api));
+  GNUNET_free (libname);
+}
+
+
+/**
+ * Load the psycstore plugin.
+ *
+ * @param cfg configuration to pass
+ * @return NULL on error
+ */
+static struct GNUNET_PSYCSTORE_PluginFunctions *
+load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  struct GNUNET_PSYCSTORE_PluginFunctions *ret;
+  char *libname;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' psycstore plugin\n"),
+              plugin_name);
+  GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name);
+  if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg)))
+  {
+    FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name);
+    return NULL;
+  }
+  GNUNET_free (libname);
+  return ret;
+}
+
+
+struct FragmentClosure
+{
+  uint8_t n;
+  uint64_t flags[16];
+  struct GNUNET_MULTICAST_MessageHeader *msg[16];
+};
+
+static int
+fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2,
+             enum GNUNET_PSYCSTORE_MessageFlags flags)
+{
+  struct FragmentClosure *fcls = cls;
+  struct GNUNET_MULTICAST_MessageHeader *msg1 = fcls->msg[fcls->n];
+  uint64_t flags1 = fcls->flags[fcls->n++];
+  int ret;
+
+  if (flags1 == flags && msg1->header.size == msg2->header.size
+      && 0 == memcmp (msg1, msg2, ntohs (msg1->header.size)))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "Fragment %llu matches\n",
+         msg1->fragment_id);
+    ret = GNUNET_YES;
+  }
+  else
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR, "Fragment %llu differs\n",
+         msg1->fragment_id);
+    ret = GNUNET_SYSERR;
+  }
+
+  GNUNET_free (msg2);
+  return ret;
+}
+
+
+struct StateClosure {
+  size_t n;
+  void *value[16];
+  size_t value_size[16];
+};
+
+static int
+state_cb (void *cls, const char *name, const void *value, size_t value_size)
+{
+  struct StateClosure *scls = cls;
+  const void *val = scls->value[scls->n];
+  size_t val_size = scls->value_size[scls->n++];
+
+  return value_size == val_size && 0 == memcmp (value, val, val_size)
+    ? GNUNET_YES
+    : GNUNET_SYSERR;
+}
+
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  struct GNUNET_PSYCSTORE_PluginFunctions *db;
+  
+  ok = 1;
+  db = load_plugin (cfg);
+  if (NULL == db)
+  {
+    FPRINTF (stderr,
+             "%s", 
+            "Failed to initialize PSYCstore.  "
+             "Database likely not setup, skipping test.\n");
+    return;
+  }
+
+  /* Membership */
+
+  channel_key = GNUNET_CRYPTO_ecc_key_create ();
+  slave_key = GNUNET_CRYPTO_ecc_key_create ();
+
+  GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key);
+  GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key);
+
+  ASSERT (GNUNET_OK == db->membership_store(db->cls, &channel_pub_key,
+                                            &slave_pub_key, GNUNET_YES,
+                                            4, 2, 1));
+
+  ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key,
+                                            &slave_pub_key, 4));
+
+  ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key,
+                                            &slave_pub_key, 2));
+
+  ASSERT (GNUNET_NO == db->membership_test(db->cls, &channel_pub_key,
+                                           &slave_pub_key, 1));
+
+
+  /* Messages */
+
+  struct GNUNET_MULTICAST_MessageHeader *msg
+    = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key));
+  ASSERT (msg != NULL);
+
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE);
+  msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key));
+
+  msg->hop_counter = 9;
+  msg->fragment_id = INT64_MAX - 1;
+  msg->fragment_offset = 0;
+  msg->message_id = INT64_MAX - 2;
+  msg->group_generation = INT64_MAX - 3;
+  msg->flags = GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT;
+
+  memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key));
+
+  msg->purpose.size = htonl (ntohs (msg->header.size)
+                             - sizeof (msg->header)
+                             - sizeof (msg->hop_counter)
+                             - sizeof (msg->signature));
+  msg->purpose.purpose = htonl (234);
+  GNUNET_CRYPTO_ecc_sign (slave_key, &msg->purpose, &msg->signature);
+
+  struct FragmentClosure fcls = { 0 };
+  fcls.n = 0;
+  fcls.msg[0] = msg;
+  fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE;
+
+  ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg,
+                                           fcls.flags[0]));
+
+  ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
+                                         msg->fragment_id,
+                                         fragment_cb, &fcls));
+  ASSERT (fcls.n == 1);
+
+  fcls.n = 0;
+
+  ASSERT (GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key,
+                                                 msg->message_id,
+                                                 msg->fragment_offset,
+                                                 fragment_cb, &fcls));
+  ASSERT (fcls.n == 1);
+
+  ASSERT (GNUNET_OK == db->message_add_flags (
+            db->cls, &channel_pub_key, msg->message_id,
+            GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED));
+
+  fcls.n = 0;
+  fcls.flags[0] |= GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED;
+
+  ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
+                                         msg->fragment_id,
+                                         fragment_cb, &fcls));
+  ASSERT (fcls.n == 1);
+
+  struct GNUNET_MULTICAST_MessageHeader *msg1
+    = GNUNET_malloc (sizeof (*msg1) + sizeof (channel_pub_key));
+
+  memcpy (msg1, msg, sizeof (*msg1) + sizeof (channel_pub_key));
+
+  msg1->fragment_id++;
+  msg1->fragment_offset += 32768;
+
+  fcls.n = 0;
+  fcls.msg[1] = msg1;
+  fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH;
+
+  ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1,
+                                           fcls.flags[1]));
+
+  ASSERT (GNUNET_OK == db->message_get (db->cls, &channel_pub_key,
+                                        msg->message_id,
+                                        fragment_cb, &fcls));
+  ASSERT (fcls.n == 2);
+
+  uint64_t max_state_msg_id = 0;
+  ASSERT (GNUNET_OK == db->counters_get_slave (db->cls, &channel_pub_key,
+                                               &max_state_msg_id)
+          && max_state_msg_id == msg->message_id);
+
+  uint64_t fragment_id = 0, message_id = 0, group_generation = 0;
+  ASSERT (GNUNET_OK == db->counters_get_master (db->cls, &channel_pub_key,
+                                                &fragment_id, &message_id,
+                                                &group_generation)
+          && fragment_id == msg1->fragment_id
+          && message_id == msg1->message_id
+          && group_generation == msg1->group_generation);
+
+
+  /* State */
+
+  ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo",
+                                      C2ARG("one two three")));
+
+  ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo_bar",
+                                      slave_key,
+                                      sizeof (*slave_key)));
+
+  struct StateClosure scls = { 0 };
+  scls.n = 0;
+  scls.value[0] = "one two three";
+  scls.value_size[0] = strlen ("one two three");
+
+  ASSERT (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo",
+                                      state_cb, &scls));
+  ASSERT (scls.n == 1);
+
+  scls.n = 0;
+  scls.value[1] = slave_key;
+  scls.value_size[1] = sizeof (*slave_key);
+
+  ASSERT (GNUNET_OK == db->state_get_all (db->cls, &channel_pub_key, "_foo",
+                                          state_cb, &scls));
+  ASSERT (scls.n == 2);
+
+  scls.n = 0;
+  ASSERT (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key,
+                                             state_cb, &scls));
+  ASSERT (scls.n == 0);
+
+  ASSERT (GNUNET_OK == db->state_update_signed (db->cls, &channel_pub_key));
+
+  scls.n = 0;
+  ASSERT (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key,
+                                              state_cb, &scls));
+  ASSERT (scls.n == 2);
+
+  ok = 0;
+  
+FAILURE:
+
+  if (NULL != channel_key)
+  {
+    GNUNET_free (channel_key);
+    channel_key = NULL;
+  }
+  if (NULL != slave_key)
+  {
+    GNUNET_free (slave_key);
+    slave_key = NULL;
+  }
+
+  unload_plugin (db);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  char cfg_name[128];
+  char *const xargv[] = {
+    "test-plugin-psycstore",
+    "-c", cfg_name,
+    "-L", LOG_LEVEL,
+    NULL
+  };
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_OPTION_END
+  };
+
+  GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite");
+  GNUNET_log_setup ("test-plugin-psycstore", LOG_LEVEL, NULL);
+  plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
+  GNUNET_snprintf (cfg_name, sizeof (cfg_name), 
"test_plugin_psycstore_%s.conf",
+                   plugin_name);
+  GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv,
+                      "test-plugin-psycstore", "nohelp", options, &run, NULL);
+
+  if (ok != 0)
+    FPRINTF (stderr, "Missed some testcases: %d\n", ok);
+
+#if ! DEBUG_PSYCSTORE
+  GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite");
+#endif
+
+  return ok;
+}
+
+/* end of test_plugin_psycstore.c */

Added: gnunet/src/psycstore/test_plugin_psycstore_sqlite.conf
===================================================================
--- gnunet/src/psycstore/test_plugin_psycstore_sqlite.conf                      
        (rev 0)
+++ gnunet/src/psycstore/test_plugin_psycstore_sqlite.conf      2013-09-03 
22:33:21 UTC (rev 28974)
@@ -0,0 +1,2 @@
+[psycstore-sqlite]
+FILENAME = /tmp/gnunet-test-plugin-psycstore-sqlite/sqlite.db

Modified: gnunet/src/psycstore/test_psycstore.c
===================================================================
--- gnunet/src/psycstore/test_psycstore.c       2013-09-03 19:16:43 UTC (rev 
28973)
+++ gnunet/src/psycstore/test_psycstore.c       2013-09-03 22:33:21 UTC (rev 
28974)
@@ -48,14 +48,19 @@
 /**
  * Handle to PSYCstore operation.
  */
-static struct GNUNET_PSYCSTORE_Operation *op;
+static struct GNUNET_PSYCSTORE_OperationHandle *op;
 
 /**
  * Handle for task for timeout termination.
  */ 
 static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
 
+static struct GNUNET_CRYPTO_EccPrivateKey *channel_key;
+static struct GNUNET_CRYPTO_EccPrivateKey *slave_key;
 
+static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key;
+static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key;
+
 /**
  * Clean up all resources used.
  */
@@ -72,6 +77,16 @@
     GNUNET_PSYCSTORE_disconnect (h);
     h = NULL;
   }
+  if (NULL != channel_key)
+  {
+    GNUNET_free (channel_key);
+    channel_key = NULL;
+  }
+  if (NULL != slave_key)
+  {
+    GNUNET_free (slave_key);
+    slave_key = NULL;
+  }
   GNUNET_SCHEDULER_shutdown ();
 }
 
@@ -119,7 +134,12 @@
                                &end_normally, NULL);
 }
 
+void
+membership_store_result (void *cls, int result, const char *err_msg)
+{
 
+}
+
 /**
  * Main function of the test, run from scheduler.
  *
@@ -136,6 +156,17 @@
                                                &endbadly, NULL); 
   h = GNUNET_PSYCSTORE_connect (cfg);
   GNUNET_assert (NULL != h);
+
+  channel_key = GNUNET_CRYPTO_ecc_key_create ();
+  slave_key = GNUNET_CRYPTO_ecc_key_create ();
+
+  GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key);
+  GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key);
+
+  op = GNUNET_PSYCSTORE_membership_store (h, &channel_pub_key, &slave_pub_key,
+                                          GNUNET_YES, 2, 2, 1,
+                                          &membership_store_result, NULL);
+
   end ();
 }
 

Modified: gnunet/src/psycstore/test_psycstore.conf
===================================================================
--- gnunet/src/psycstore/test_psycstore.conf    2013-09-03 19:16:43 UTC (rev 
28973)
+++ gnunet/src/psycstore/test_psycstore.conf    2013-09-03 22:33:21 UTC (rev 
28974)
@@ -3,4 +3,13 @@
 UNIXPATH = /tmp/test-psycstore-service-arm.sock
 
 [psycstore]
-DBFILE = /tmp/test-psycstore-service.sqlite
+AUTOSTART = YES
+HOME = $SERVICEHOME
+BINARY = gnunet-service-psycstore
+UNIXPATH = /tmp/test-gnunet-service-psycstore.sock
+UNIX_MATCH_UID = NO
+UNIX_MATCH_GID = YES
+DATABASE = sqlite
+
+[psycstore-sqlite]
+FILENAME = $SERVICEHOME/psycstore/sqlite_test.db




reply via email to

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