increase
[oweals/gnunet.git] / src / nse / gnunet-service-nse.c
index e70d6c29e82e3a0bc9992749f5a6fd3da71f2ce8..32b81b080b3ae867a75587e17ba1868a023ce82d 100644 (file)
@@ -36,6 +36,7 @@
  * this can calculate the expected number of peers in the network.
  */
 #include "platform.h"
+#include <math.h>
 #include "gnunet_util_lib.h"
 #include "gnunet_constants.h"
 #include "gnunet_protocols.h"
 /**
  * Over how many values do we calculate the weighted average?
  */
-#define HISTORY_SIZE 8
-
-/**
- * Size of the queue to core.
- */
-#define CORE_QUEUE_SIZE 2
+#define HISTORY_SIZE 64
 
 /**
  * Message priority to use.
  */
 #define NSE_PRIORITY 5
 
+#if FREEBSD
+#define log2(a) (log(a)/log(2))
+#endif
+
 /**
  * Amount of work required (W-bit collisions) for NSE proofs, in collision-bits.
  */
@@ -298,37 +298,67 @@ static void
 setup_estimate_message (struct GNUNET_NSE_ClientMessage *em)
 {
   unsigned int i;
+  unsigned int j;
   double mean;
   double sum;
   double std_dev;
   double variance;
   double val;
-  double weight;
+  double nsize;
+
+  /* Weighted incremental algorithm for stddev according to West (1979) */
+#if WEST
   double sumweight;
+  double weight;
   double q;
   double r;
   double temp;
 
-  /* Weighted incremental algorithm for stddev according to West (1979) */
   mean = 0.0;
   sum = 0.0;
   sumweight = 0.0;
   for (i = 0; i < estimate_count; i++)
   {
-    val =
-        htonl (size_estimate_messages
-               [(estimate_index - i +
-                 HISTORY_SIZE) % HISTORY_SIZE].matching_bits);
-    weight = 1;                 /* was: estimate_count + 1 - i; */
+    j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
+    val = htonl (size_estimate_messages[j].matching_bits);
+    weight = 1.0;              /* was: estimate_count + 1 - i; */
 
     temp = weight + sumweight;
     q = val - mean;
     r = q * weight / temp;
-    sum += sumweight * q * r;
     mean += r;
+    sum += sumweight * q * r;
     sumweight = temp;
   }
-  variance = sum / (sumweight - 1.0);
+  if (estimate_count > 0)
+    variance = (sum / sumweight) * estimate_count / (estimate_count - 1.0);
+#else
+  /* trivial version for debugging */
+  double vsq;
+
+  /* non-weighted trivial version */
+  sum = 0.0;
+  vsq = 0.0;
+  variance = 0.0;
+  mean = 0.0;
+
+  for (i = 0; i < estimate_count; i++)
+  {
+    j = (estimate_index - i + HISTORY_SIZE) % HISTORY_SIZE;
+    val = htonl (size_estimate_messages[j].matching_bits);
+    sum += val;
+    vsq += val * val;
+  }
+  if (0 != estimate_count)
+  {
+    mean = sum / estimate_count;
+    variance = (vsq - mean * sum) / (estimate_count - 1.0); // terrible for numerical stability...
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
+               "(%f - %f) / %u = %f\n", 
+               vsq, mean * sum, estimate_count - 1, variance);
+
+  }
+#endif
   GNUNET_assert (variance >= 0);
   std_dev = sqrt (variance);
   current_std_dev = std_dev;
@@ -338,7 +368,10 @@ setup_estimate_message (struct GNUNET_NSE_ClientMessage *em)
   em->header.type = htons (GNUNET_MESSAGE_TYPE_NSE_ESTIMATE);
   em->reserved = htonl (0);
   em->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
-  em->size_estimate = mean - 1.0 / 3.0;
+  em->size_estimate = mean - 0.332747;
+  nsize = log2 (GNUNET_CONTAINER_multihashmap_size (peers) + 1);
+  if (em->size_estimate < nsize)
+    em->size_estimate = nsize;
   em->std_deviation = std_dev;
   GNUNET_STATISTICS_set (stats, "# nodes in the network (estimate)",
                          (uint64_t) pow (2, mean - 1.0 / 3.0), GNUNET_NO);
@@ -628,7 +661,8 @@ setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
   fm->pkey = my_public_key;
   fm->proof_of_work = my_proof;
   GNUNET_assert (GNUNET_OK ==
-                GNUNET_CRYPTO_rsa_sign (my_private_key, &fm->purpose, &fm->signature));
+                 GNUNET_CRYPTO_rsa_sign (my_private_key, &fm->purpose,
+                                         &fm->signature));
 }
 
 
@@ -817,9 +851,11 @@ find_proof (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
         {
           size_estimate_messages[i].proof_of_work = my_proof;
           GNUNET_assert (GNUNET_OK ==
-                        GNUNET_CRYPTO_rsa_sign (my_private_key,
-                                                &size_estimate_messages[i].purpose,
-                                                &size_estimate_messages[i].signature));
+                         GNUNET_CRYPTO_rsa_sign (my_private_key,
+                                                 &size_estimate_messages
+                                                 [i].purpose,
+                                                 &size_estimate_messages
+                                                 [i].signature));
         }
       write_proof ();
       return;
@@ -929,12 +965,13 @@ update_flood_times (void *cls, const GNUNET_HashCode * key, void *value)
  * @param message message
  * @param peer peer identity this message is from (ignored)
  * @param atsi performance data (ignored)
- *
+ * @param atsi_count number of records in 'atsi'
  */
 static int
 handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer,
                           const struct GNUNET_MessageHeader *message,
-                          const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+                          const struct GNUNET_ATS_Information *atsi,
+                          unsigned int atsi_count)
 {
   const struct GNUNET_NSE_FloodMessage *incoming_flood;
   struct GNUNET_TIME_Absolute ts;
@@ -1085,10 +1122,12 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer,
  * @param cls closure
  * @param peer peer identity this notification is about
  * @param atsi performance data
+ * @param atsi_count number of records in 'atsi'
  */
 static void
 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
-                     const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+                     const struct GNUNET_ATS_Information *atsi,
+                     unsigned int atsi_count)
 {
   struct NSEPeerEntry *peer_entry;
 
@@ -1098,8 +1137,9 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
 #endif
   peer_entry = GNUNET_malloc (sizeof (struct NSEPeerEntry));
   peer_entry->id = *peer;
-  GNUNET_CONTAINER_multihashmap_put (peers, &peer->hashPubKey, peer_entry,
-                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+  GNUNET_assert (GNUNET_OK ==
+                GNUNET_CONTAINER_multihashmap_put (peers, &peer->hashPubKey, peer_entry,
+                                                   GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
   peer_entry->transmit_task =
       GNUNET_SCHEDULER_add_delayed (get_transmit_delay (-1), &transmit_task,
                                     peer_entry);
@@ -1202,12 +1242,10 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * @param cls service closure
  * @param server handle to the server for this service
  * @param identity the public identity of this peer
- * @param publicKey the public key of this peer
  */
 static void
 core_init (void *cls, struct GNUNET_CORE_Handle *server,
-           const struct GNUNET_PeerIdentity *identity,
-           const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
+           const struct GNUNET_PeerIdentity *identity)
 {
   struct GNUNET_TIME_Absolute now;
   struct GNUNET_TIME_Absolute prev_time;
@@ -1348,12 +1386,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
   nc = GNUNET_SERVER_notification_context_create (server, 1);
   /* Connect to core service and register core handlers */
   coreAPI = GNUNET_CORE_connect (cfg,   /* Main configuration */
-                                 CORE_QUEUE_SIZE,       /* queue size */
+                                 1,
                                  NULL,  /* Closure passed to functions */
                                  &core_init,    /* Call core_init once connected */
                                  &handle_core_connect,  /* Handle connects */
                                  &handle_core_disconnect,       /* Handle disconnects */
-                                 NULL,  /* Do we care about "status" updates? */
                                  NULL,  /* Don't want notified about all incoming messages */
                                  GNUNET_NO,     /* For header only inbound notification */
                                  NULL,  /* Don't want notified about all outbound messages */