aboutsummaryrefslogtreecommitdiff
path: root/src/consensus
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2012-11-28 16:32:15 +0000
committerFlorian Dold <florian.dold@gmail.com>2012-11-28 16:32:15 +0000
commit12dc2e752c7faf28d63049b2b308ce5316df8dc3 (patch)
tree73004461bacd772a604c593b2a06afb4bbeaac4e /src/consensus
parentdbb17853368c11b2a9a4a19c6e38f8ef02d2f258 (diff)
downloadgnunet-12dc2e752c7faf28d63049b2b308ce5316df8dc3.tar.gz
gnunet-12dc2e752c7faf28d63049b2b308ce5316df8dc3.zip
dummy consensus service
Diffstat (limited to 'src/consensus')
-rw-r--r--src/consensus/Makefile.am3
-rw-r--r--src/consensus/consensus_api.c32
-rw-r--r--src/consensus/gnunet-service-consensus.c608
-rw-r--r--src/consensus/gnunet-service-consensus.cc124
-rw-r--r--src/consensus/test_consensus.conf8
-rw-r--r--src/consensus/test_consensus_api.c62
6 files changed, 682 insertions, 155 deletions
diff --git a/src/consensus/Makefile.am b/src/consensus/Makefile.am
index 4eb06ceea..8d6a9aaff 100644
--- a/src/consensus/Makefile.am
+++ b/src/consensus/Makefile.am
@@ -31,9 +31,10 @@ gnunet_consensus_LDADD = \
31 $(GN_LIBINTL) 31 $(GN_LIBINTL)
32 32
33gnunet_service_consensus_SOURCES = \ 33gnunet_service_consensus_SOURCES = \
34 gnunet-service-consensus.cc 34 gnunet-service-consensus.c
35gnunet_service_consensus_LDADD = \ 35gnunet_service_consensus_LDADD = \
36 $(top_builddir)/src/util/libgnunetutil.la \ 36 $(top_builddir)/src/util/libgnunetutil.la \
37 $(top_builddir)/src/core/libgnunetcore.la \
37 $(GN_LIBINTL) 38 $(GN_LIBINTL)
38 39
39libgnunetconsensus_la_SOURCES = \ 40libgnunetconsensus_la_SOURCES = \
diff --git a/src/consensus/consensus_api.c b/src/consensus/consensus_api.c
index b1de10edd..90b0fdf16 100644
--- a/src/consensus/consensus_api.c
+++ b/src/consensus/consensus_api.c
@@ -124,7 +124,7 @@ handle_new_element(struct GNUNET_CONSENSUS_Handle *consensus,
124 element.type = msg->element_type; 124 element.type = msg->element_type;
125 element.size = msg->header.size - sizeof (struct GNUNET_CONSENSUS_ElementMessage); 125 element.size = msg->header.size - sizeof (struct GNUNET_CONSENSUS_ElementMessage);
126 element.data = &msg[1]; 126 element.data = &msg[1];
127 consensus->new_element_cb(consensus->new_element_cls, &element); 127 consensus->new_element_cb (consensus->new_element_cls, &element);
128} 128}
129 129
130static void 130static void
@@ -152,12 +152,15 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
152{ 152{
153 struct GNUNET_CONSENSUS_Handle *consensus = cls; 153 struct GNUNET_CONSENSUS_Handle *consensus = cls;
154 154
155 LOG (GNUNET_ERROR_TYPE_INFO, "received message from consensus service\n");
156
155 if (msg == NULL) 157 if (msg == NULL)
156 { 158 {
157 /* Error, timeout, death */ 159 /* Error, timeout, death */
160 LOG (GNUNET_ERROR_TYPE_ERROR, "error receiving\n");
158 GNUNET_CLIENT_disconnect (consensus->client); 161 GNUNET_CLIENT_disconnect (consensus->client);
159 consensus->client = NULL; 162 consensus->client = NULL;
160 consensus->new_element_cb(NULL, NULL); 163 consensus->new_element_cb (NULL, NULL);
161 if (NULL != consensus->idc) 164 if (NULL != consensus->idc)
162 { 165 {
163 consensus->idc(consensus->idc_cls, GNUNET_NO); 166 consensus->idc(consensus->idc_cls, GNUNET_NO);
@@ -170,10 +173,10 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
170 switch (ntohs(msg->type)) 173 switch (ntohs(msg->type))
171 { 174 {
172 case GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT: 175 case GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT:
173 handle_new_element(consensus, (struct GNUNET_CONSENSUS_ElementMessage *) msg); 176 handle_new_element (consensus, (struct GNUNET_CONSENSUS_ElementMessage *) msg);
174 break; 177 break;
175 case GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE_DONE: 178 case GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE_DONE:
176 handle_conclude_done(consensus, (struct GNUNET_CONSENSUS_ConcludeDoneMessage *) msg); 179 handle_conclude_done (consensus, (struct GNUNET_CONSENSUS_ConcludeDoneMessage *) msg);
177 break; 180 break;
178 default: 181 default:
179 LOG(GNUNET_ERROR_TYPE_WARNING, "did not understand message type sent by service, ignoring"); 182 LOG(GNUNET_ERROR_TYPE_WARNING, "did not understand message type sent by service, ignoring");
@@ -220,16 +223,16 @@ transmit_insert (void *cls, size_t size, void *buf)
220 223
221 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT); 224 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT);
222 msg->header.size = htons (msize); 225 msg->header.size = htons (msize);
223 memcpy(&msg[1], 226 memcpy (&msg[1],
224 consensus->insert_element->data, 227 consensus->insert_element->data,
225 consensus->insert_element->size); 228 consensus->insert_element->size);
226 229
227 230
228 idc = consensus->idc; 231 idc = consensus->idc;
229 consensus->idc = NULL; 232 consensus->idc = NULL;
230 idc_cls = consensus->idc_cls; 233 idc_cls = consensus->idc_cls;
231 consensus->idc_cls = NULL; 234 consensus->idc_cls = NULL;
232 idc(idc_cls, GNUNET_YES); 235 idc (idc_cls, GNUNET_YES);
233 236
234 return msize; 237 return msize;
235} 238}
@@ -253,10 +256,10 @@ transmit_join (void *cls, size_t size, void *buf)
253 struct GNUNET_CONSENSUS_Handle *consensus; 256 struct GNUNET_CONSENSUS_Handle *consensus;
254 int msize; 257 int msize;
255 258
256 LOG(GNUNET_ERROR_TYPE_DEBUG, "transmitting CLIENT_JOIN to service\n");
257
258 GNUNET_assert (NULL != buf); 259 GNUNET_assert (NULL != buf);
259 260
261 LOG (GNUNET_ERROR_TYPE_DEBUG, "transmitting join message\n");
262
260 consensus = cls; 263 consensus = cls;
261 consensus->th = NULL; 264 consensus->th = NULL;
262 consensus->joined = 1; 265 consensus->joined = 1;
@@ -283,7 +286,6 @@ transmit_join (void *cls, size_t size, void *buf)
283 GNUNET_NO, &transmit_insert, consensus); 286 GNUNET_NO, &transmit_insert, consensus);
284 } 287 }
285 288
286
287 GNUNET_CLIENT_receive (consensus->client, &message_handler, consensus, 289 GNUNET_CLIENT_receive (consensus->client, &message_handler, consensus,
288 GNUNET_TIME_UNIT_FOREVER_REL); 290 GNUNET_TIME_UNIT_FOREVER_REL);
289 291
@@ -321,7 +323,7 @@ transmit_conclude (void *cls, size_t size, void *buf)
321 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE); 323 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE);
322 msg->header.size = htons (msize); 324 msg->header.size = htons (msize);
323 msg->timeout = 325 msg->timeout =
324 GNUNET_TIME_relative_hton(GNUNET_TIME_absolute_get_remaining(consensus->conclude_deadline)); 326 GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining(consensus->conclude_deadline));
325 327
326 return msize; 328 return msize;
327} 329}
@@ -386,7 +388,6 @@ GNUNET_CONSENSUS_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
386 struct GNUNET_CONSENSUS_Handle *consensus; 388 struct GNUNET_CONSENSUS_Handle *consensus;
387 size_t join_message_size; 389 size_t join_message_size;
388 390
389
390 consensus = GNUNET_malloc (sizeof (struct GNUNET_CONSENSUS_Handle)); 391 consensus = GNUNET_malloc (sizeof (struct GNUNET_CONSENSUS_Handle));
391 consensus->cfg = cfg; 392 consensus->cfg = cfg;
392 consensus->new_element_cb = new_element_cb; 393 consensus->new_element_cb = new_element_cb;
@@ -394,15 +395,12 @@ GNUNET_CONSENSUS_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
394 consensus->num_peers = num_peers; 395 consensus->num_peers = num_peers;
395 consensus->session_id = *session_id; 396 consensus->session_id = *session_id;
396 397
397
398
399 if (0 == num_peers) 398 if (0 == num_peers)
400 { 399 {
401 consensus->peers = NULL; 400 consensus->peers = NULL;
402 } 401 }
403 else if (num_peers > 0) 402 else if (num_peers > 0)
404 { 403 {
405
406 consensus->peers = GNUNET_memdup (peers, num_peers * sizeof (struct GNUNET_PeerIdentity)); 404 consensus->peers = GNUNET_memdup (peers, num_peers * sizeof (struct GNUNET_PeerIdentity));
407 } 405 }
408 else 406 else
@@ -410,7 +408,6 @@ GNUNET_CONSENSUS_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
410 GNUNET_break (0); 408 GNUNET_break (0);
411 } 409 }
412 410
413
414 consensus->client = GNUNET_CLIENT_connect ("consensus", cfg); 411 consensus->client = GNUNET_CLIENT_connect ("consensus", cfg);
415 412
416 GNUNET_assert (consensus->client != NULL); 413 GNUNET_assert (consensus->client != NULL);
@@ -424,7 +421,6 @@ GNUNET_CONSENSUS_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
424 GNUNET_TIME_UNIT_FOREVER_REL, 421 GNUNET_TIME_UNIT_FOREVER_REL,
425 GNUNET_NO, &transmit_join, consensus); 422 GNUNET_NO, &transmit_join, consensus);
426 423
427
428 GNUNET_assert (consensus->th != NULL); 424 GNUNET_assert (consensus->th != NULL);
429 425
430 return consensus; 426 return consensus;
diff --git a/src/consensus/gnunet-service-consensus.c b/src/consensus/gnunet-service-consensus.c
new file mode 100644
index 000000000..6cf3c0653
--- /dev/null
+++ b/src/consensus/gnunet-service-consensus.c
@@ -0,0 +1,608 @@
1/*
2 This file is part of GNUnet
3 (C) 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21
22#include "platform.h"
23#include "gnunet_protocols.h"
24#include "gnunet_common.h"
25#include "gnunet_service_lib.h"
26#include "gnunet_consensus_service.h"
27#include "gnunet_core_service.h"
28#include "gnunet_container_lib.h"
29#include "consensus.h"
30
31
32struct ConsensusClient;
33
34static void
35send_next (struct ConsensusClient *cli);
36
37
38/**
39 * An element that is waiting to be transmitted to a client.
40 */
41struct PendingElement
42{
43 /**
44 * Pending elements are kept in a DLL.
45 */
46 struct PendingElement *next;
47
48 /**
49 * Pending elements are kept in a DLL.
50 */
51 struct PendingElement *prev;
52
53 /**
54 * The actual element
55 */
56 struct GNUNET_CONSENSUS_Element *element;
57};
58
59
60/**
61 * A consensus session consists of one or more local clients,
62 * as well as zero or more remote authorities.
63 */
64struct ConsensusSession
65{
66 /**
67 * Consensus sessions are kept in a DLL.
68 */
69 struct ConsensusSession *next;
70
71 /**
72 * Consensus sessions are kept in a DLL.
73 */
74 struct ConsensusSession *prev;
75
76 /**
77 * Consensus clients are kept in a DLL.
78 */
79 struct ConsensusClient *clients_head;
80
81 /**
82 * Consensus clients are kept in a DLL.
83 */
84 struct ConsensusClient *clients_tail;
85
86 /**
87 * Local consensus identification, chosen by clients.
88 */
89 struct GNUNET_HashCode *local_id;
90
91 /**
92 * Global consensus identification, computed
93 * from the local id and participating authorities.
94 */
95 struct GNUNET_HashCode *global_id;
96
97 /**
98 * Values in the consensus set of this session.
99 */
100 struct GNUNET_CONTAINER_MultiHashMap *values;
101};
102
103
104struct ConsensusClient
105{
106 /**
107 * Consensus clients are kept in a DLL.
108 */
109 struct ConsensusClient *next;
110 /**
111 * Consensus clients are kept in a DLL.
112 */
113 struct ConsensusClient *prev;
114
115 /**
116 * Corresponding server handle.
117 */
118 struct GNUNET_SERVER_Client *client;
119
120 /**
121 * Client wants to receive and send updates.
122 */
123 int begin;
124
125 /**
126 * Session this client belongs to
127 */
128 struct ConsensusSession *session;
129
130 /**
131 * Values in the consensus set of this client.
132 * Includes pending elements.
133 */
134 struct GNUNET_CONTAINER_MultiHashMap *values;
135
136 /**
137 * Elements that have not been set to the client yet.
138 */
139 struct PendingElement *pending_head;
140 /**
141 * Elements that have not been set to the client yet.
142 */
143 struct PendingElement *pending_tail;
144
145 /**
146 * Currently active transmit handle for sending to the client
147 */
148 struct GNUNET_SERVER_TransmitHandle *th;
149
150 /**
151 * Once conclude_requested is GNUNET_YES, the client may not
152 * insert any more values.
153 */
154 int conclude_requested;
155
156 /**
157 * Client has been informed about the conclusion.
158 */
159 int conclude_sent;
160};
161
162
163/**
164 * Linked list of sesstions this peer participates in.
165 */
166static struct ConsensusSession *sessions_head;
167
168/**
169 * Linked list of sesstions this peer participates in.
170 */
171static struct ConsensusSession *sessions_tail;
172
173/**
174 * Configuration of the consensus service.
175 */
176static const struct GNUNET_CONFIGURATION_Handle *cfg;
177
178/**
179 * Handle to the server for this service.
180 */
181static struct GNUNET_SERVER_Handle *srv;
182
183/**
184 * Peer that runs this service
185 */
186static struct GNUNET_PeerIdentity *my_peer;
187
188
189struct ConsensusClient *
190find_client (const struct GNUNET_SERVER_Client *srv_client)
191{
192 struct ConsensusSession *session;
193 struct ConsensusClient *client;
194
195 session = sessions_head;
196 while (NULL != session)
197 {
198 client = session->clients_head;
199 while (NULL != client)
200 {
201 if (client->client == srv_client)
202 {
203 return client;
204 }
205 client = client->next;
206 }
207 session = session->next;
208 }
209 return NULL;
210}
211
212static void
213disconnect_client (struct GNUNET_SERVER_Client *client)
214{
215 /* FIXME */
216}
217
218static void
219compute_global_id (struct GNUNET_HashCode *dst,
220 const struct GNUNET_HashCode *local_id,
221 const struct GNUNET_PeerIdentity *peers,
222 int num_peers)
223{
224 *dst = *local_id;
225
226 /* FIXME: hash other peers into global id */
227}
228
229
230
231/**
232 * Iterator over hash map entries.
233 *
234 * @param cls closure, the client
235 * @param key current key code
236 * @param value value in the hash map
237 * @return GNUNET_YES if we should continue to
238 * iterate,
239 * GNUNET_NO if not.
240 */
241int
242update_pending (void *cls,
243 const struct GNUNET_HashCode *key,
244 void *value)
245{
246 struct ConsensusClient *cli;
247 struct GNUNET_CONSENSUS_Element *element;
248 struct PendingElement *pending_element;
249
250 cli = (struct ConsensusClient *) cls;
251 element = (struct GNUNET_CONSENSUS_Element *) value;
252 pending_element = GNUNET_malloc (sizeof (struct PendingElement));
253 pending_element->element = element;
254
255 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (cli->values, key))
256 {
257 GNUNET_CONTAINER_DLL_insert_tail (cli->pending_head, cli->pending_tail, pending_element);
258 GNUNET_CONTAINER_multihashmap_put (cli->values, key, element, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
259 }
260
261 return GNUNET_YES;
262}
263
264
265
266
267static size_t
268transmit_pending (void *cls, size_t size, void *buf)
269{
270 struct GNUNET_CONSENSUS_Element *element;
271 struct GNUNET_CONSENSUS_ElementMessage *msg;
272 struct ConsensusClient *cli;
273
274 cli = (struct ConsensusClient *) cls;
275 msg = (struct GNUNET_CONSENSUS_ElementMessage *) buf;
276 element = cli->pending_head->element;
277
278 GNUNET_assert (NULL != element);
279
280 cli->th = NULL;
281
282 msg->element_type = element->type;
283 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT);
284 msg->header.size = htons (sizeof (struct GNUNET_CONSENSUS_ElementMessage) + element->size);
285 memcpy (&msg[1], &element[1], element->size);
286
287
288 cli->pending_head = cli->pending_head->next;
289
290 send_next (cli);
291
292 return sizeof (struct GNUNET_CONSENSUS_ElementMessage) + element->size;
293}
294
295
296static size_t
297transmit_conclude_done (void *cls, size_t size, void *buf)
298{
299 struct GNUNET_CONSENSUS_ConcludeDoneMessage *msg;
300
301 msg = (struct GNUNET_CONSENSUS_ConcludeDoneMessage *) buf;
302 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE);
303 msg->header.size = htons (sizeof (struct GNUNET_CONSENSUS_ConcludeDoneMessage));
304 msg->num_peers = htons (0);
305
306 return sizeof (struct GNUNET_CONSENSUS_ConcludeDoneMessage);
307}
308
309
310/**
311 * Schedule sending the next message (if there is any) to a client.
312 *
313 * @param cli the client to send the next message to
314 */
315static void
316send_next (struct ConsensusClient *cli)
317{
318 int msize;
319
320 GNUNET_assert (NULL != cli);
321
322 if (NULL != cli->th)
323 {
324 return;
325 }
326
327 if ((cli->conclude_requested == GNUNET_YES) && (cli->conclude_sent == GNUNET_NO))
328 {
329 /* just the conclude message with no other authorities in the dummy */
330 msize = sizeof (struct GNUNET_CONSENSUS_ConcludeMessage);
331 cli->th =
332 GNUNET_SERVER_notify_transmit_ready (cli->client, msize,
333 GNUNET_TIME_UNIT_FOREVER_REL, &transmit_conclude_done, cli);
334 cli->conclude_sent = GNUNET_YES;
335 }
336 else if (NULL != cli->pending_head)
337 {
338 msize = cli->pending_head->element->size + sizeof (struct GNUNET_CONSENSUS_ElementMessage);
339 cli->th =
340 GNUNET_SERVER_notify_transmit_ready (cli->client, msize,
341 GNUNET_TIME_UNIT_FOREVER_REL, &transmit_pending, cli);
342 }
343}
344
345
346/**
347 * Called when a client wants to join a consensus session.
348 */
349static void
350client_join (void *cls,
351 struct GNUNET_SERVER_Client *client,
352 const struct GNUNET_MessageHeader *m)
353{
354 struct GNUNET_HashCode global_id;
355 const struct GNUNET_CONSENSUS_JoinMessage *msg;
356 struct ConsensusSession *session;
357 struct ConsensusClient *consensus_client;
358
359 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "join\n");
360
361 fprintf(stderr, "foobar\n");
362
363 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "client joined\n");
364
365 msg = (struct GNUNET_CONSENSUS_JoinMessage *) m;
366
367 /* kill the client if it already is in a session */
368 if (NULL != find_client (client))
369 {
370 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "client tried to join twice\n");
371 disconnect_client (client);
372 return;
373 }
374
375 consensus_client = GNUNET_malloc (sizeof (struct ConsensusClient));
376 consensus_client->client = client;
377 consensus_client->begin = GNUNET_NO;
378 consensus_client->values = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
379
380 GNUNET_SERVER_client_keep (client);
381
382 GNUNET_assert (NULL != consensus_client->values);
383
384 compute_global_id (&global_id, &msg->session_id, (struct GNUNET_PeerIdentity *) &m[1], msg->num_peers);
385
386 /* look if we already have a session for this local id */
387 session = sessions_head;
388 while (NULL != session)
389 {
390 if (0 == memcmp(&global_id, session->global_id, sizeof (struct GNUNET_HashCode)))
391 {
392 GNUNET_CONTAINER_DLL_insert (session->clients_head, session->clients_tail, consensus_client);
393 GNUNET_SERVER_receive_done (client, GNUNET_OK);
394 return;
395 }
396 session = session->next;
397 }
398
399 /* session does not exist yet, create it */
400 session = GNUNET_malloc (sizeof (struct ConsensusSession));
401 session->local_id = GNUNET_memdup (&msg->session_id, sizeof (struct GNUNET_HashCode));
402 session->global_id = GNUNET_memdup (&global_id, sizeof (struct GNUNET_HashCode));
403 session->values = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
404
405 GNUNET_CONTAINER_DLL_insert (sessions_head, sessions_tail, session);
406 GNUNET_CONTAINER_DLL_insert (session->clients_head, session->clients_tail, consensus_client);
407
408 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "created new session");
409
410 GNUNET_SERVER_receive_done (client, GNUNET_OK);
411}
412
413
414/**
415 * Called when a client performs an insert operation.
416 */
417void
418client_insert (void *cls,
419 struct GNUNET_SERVER_Client *client,
420 const struct GNUNET_MessageHeader *m)
421{
422 struct ConsensusClient *consensus_client;
423 struct GNUNET_CONSENSUS_ElementMessage *msg;
424 struct GNUNET_CONSENSUS_Element *element;
425 struct PendingElement *pending_element;
426 struct GNUNET_HashCode key;
427 int element_size;
428
429 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "insert\n");
430
431 consensus_client = find_client (client);
432
433 if (NULL == consensus_client)
434 {
435 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "client tried to insert, but client is not in any session\n");
436 GNUNET_SERVER_client_disconnect (client);
437 return;
438 }
439
440 msg = (struct GNUNET_CONSENSUS_ElementMessage *) m;
441 element_size = msg->header.size - sizeof (struct GNUNET_CONSENSUS_ElementMessage);
442
443 element = GNUNET_malloc (sizeof (struct GNUNET_CONSENSUS_Element) + element_size);
444
445 element->type = msg->element_type;
446 element->size = element_size;
447 memcpy (&element[1], &msg[1], element_size);
448 element->data = &element[1];
449
450 GNUNET_CRYPTO_hash (element, element_size, &key);
451
452 GNUNET_CONTAINER_multihashmap_put (consensus_client->session->values, &key, element,
453 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
454 GNUNET_CONTAINER_multihashmap_put (consensus_client->values, &key, element,
455 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
456
457 /* send the new value to all clients that don't have it */
458
459 consensus_client = consensus_client->session->clients_head;
460 while (NULL != consensus_client)
461 {
462 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (consensus_client->values, &key))
463 {
464 pending_element = GNUNET_malloc (sizeof (struct PendingElement));
465 pending_element->element = element;
466 GNUNET_CONTAINER_DLL_insert_tail (consensus_client->pending_head, consensus_client->pending_tail, pending_element);
467 GNUNET_CONTAINER_multihashmap_put (consensus_client->values, &key, element,
468 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
469 send_next (consensus_client);
470 }
471 }
472
473 GNUNET_SERVER_receive_done (client, GNUNET_OK);
474}
475
476
477/**
478 * Called when a client wants to begin
479 */
480void
481client_begin (void *cls,
482 struct GNUNET_SERVER_Client *client,
483 const struct GNUNET_MessageHeader *message)
484{
485 struct ConsensusClient *consensus_client;
486
487 consensus_client = find_client (client);
488
489 if (NULL == consensus_client)
490 {
491 GNUNET_SERVER_client_disconnect (client);
492 return;
493 }
494
495 consensus_client->begin = GNUNET_YES;
496
497 GNUNET_CONTAINER_multihashmap_iterate (consensus_client->session->values, &update_pending, NULL);
498 send_next (consensus_client);
499
500 GNUNET_SERVER_receive_done (client, GNUNET_OK);
501}
502
503
504
505/**
506 * Called when a client performs the conclude operation.
507 */
508void
509client_conclude (void *cls,
510 struct GNUNET_SERVER_Client *client,
511 const struct GNUNET_MessageHeader *message)
512{
513 struct ConsensusClient *consensus_client;
514
515 consensus_client = find_client (client);
516 if (NULL == consensus_client)
517 {
518 GNUNET_SERVER_client_disconnect (client);
519 return;
520 }
521 consensus_client->conclude_requested = GNUNET_YES;
522 send_next (consensus_client);
523
524 GNUNET_SERVER_receive_done (client, GNUNET_OK);
525}
526
527/**
528 * Task that disconnects from core.
529 *
530 * @param cls core handle
531 * @param tc context information (why was this task triggered now)
532 */
533static void
534disconnect_core (void *cls,
535 const struct GNUNET_SCHEDULER_TaskContext *tc)
536{
537 struct GNUNET_CORE_Handle *core;
538 core = (struct GNUNET_CORE_Handle *) cls;
539 GNUNET_CORE_disconnect (core);
540
541 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "disconnected from core\n");
542}
543
544
545static void
546core_startup (void *cls,
547 struct GNUNET_CORE_Handle *core,
548 const struct GNUNET_PeerIdentity *peer)
549{
550 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
551 {&client_join, NULL, GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_JOIN, 0},
552 {&client_insert, NULL, GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT, 0},
553 {&client_begin, NULL, GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_BEGIN,
554 sizeof (struct GNUNET_MessageHeader)},
555 {&client_conclude, NULL, GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE,
556 sizeof (struct GNUNET_CONSENSUS_ConcludeMessage)},
557 {NULL, NULL, 0, 0}
558 };
559
560
561 GNUNET_SERVER_add_handlers (srv, handlers);
562
563 my_peer = GNUNET_memdup(peer, sizeof (struct GNUNET_PeerIdentity));
564
565 GNUNET_SCHEDULER_add_now (&disconnect_core, core);
566
567 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "connected to core\n");
568}
569
570
571/**
572 * Process consensus requests.
573 *
574 * @param cls closure
575 * @param server the initialized server
576 * @param c configuration to use
577 */
578static void
579run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c)
580{
581 struct GNUNET_CORE_Handle *my_core;
582 static const struct GNUNET_CORE_MessageHandler handlers[] = {
583 {NULL, 0, 0}
584 };
585
586 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "run\n");
587
588 cfg = c;
589 srv = server;
590 my_core = GNUNET_CORE_connect (c, NULL, &core_startup, NULL, NULL, NULL, GNUNET_NO, NULL, GNUNET_NO, handlers);
591 GNUNET_assert (NULL != my_core);
592}
593
594
595/**
596 * The main function for the statistics service.
597 *
598 * @param argc number of arguments from the command line
599 * @param argv command line arguments
600 * @return 0 ok, 1 on error
601 */
602int
603main (int argc, char *const *argv)
604{
605 return (GNUNET_OK ==
606 GNUNET_SERVICE_run (argc, argv, "consensus", GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
607}
608
diff --git a/src/consensus/gnunet-service-consensus.cc b/src/consensus/gnunet-service-consensus.cc
deleted file mode 100644
index 9e8aba6bb..000000000
--- a/src/consensus/gnunet-service-consensus.cc
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 This file is part of GNUnet
3 (C) 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21
22#include <cstdio>
23#include <iostream>
24#include <stdint.h>
25
26#include "platform.h"
27#include "gnunet_protocols.h"
28#include "gnunet_common.h"
29#include "gnunet_service_lib.h"
30#include "gnunet_consensus_service.h"
31#include "consensus.h"
32
33using namespace std;
34
35
36
37struct ConsensusSession
38{
39
40};
41
42
43
44struct ConsensusClient
45{
46
47};
48
49
50
51/**
52 * Called when a client wants to join a consensus session.
53 */
54void
55client_join (void *cls,
56 struct GNUNET_SERVER_Client *client,
57 const struct GNUNET_MessageHeader *message)
58{
59 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "client joined");
60}
61
62
63/**
64 * Called when a client performs an insert operation.
65 */
66void
67client_insert (void *cls,
68 struct GNUNET_SERVER_Client *client,
69 const struct GNUNET_MessageHeader *message)
70{
71
72}
73
74
75
76/**
77 * Called when a client performs the conclude operation.
78 */
79void
80client_conclude (void *cls,
81 struct GNUNET_SERVER_Client *client,
82 const struct GNUNET_MessageHeader *message)
83{
84
85}
86
87
88
89/**
90 * Process consensus requests.
91 *
92 * @param cls closure
93 * @param server the initialized server
94 * @param c configuration to use
95 */
96static void
97run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c)
98{
99 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
100 {&client_join, NULL, GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_JOIN, 0},
101 {&client_insert, NULL, GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT, 0},
102 {&client_conclude, NULL, GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE,
103 sizeof (struct GNUNET_CONSENSUS_ConcludeMessage)},
104 {NULL, NULL, 0, 0}
105 };
106
107 GNUNET_SERVER_add_handlers(server, handlers);
108}
109
110
111/**
112 * The main function for the statistics service.
113 *
114 * @param argc number of arguments from the command line
115 * @param argv command line arguments
116 * @return 0 ok, 1 on error
117 */
118int
119main (int argc, char *const *argv)
120{
121 return (GNUNET_OK ==
122 GNUNET_SERVICE_run (argc, argv, "consensus", GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
123}
124
diff --git a/src/consensus/test_consensus.conf b/src/consensus/test_consensus.conf
index 143313ff2..5bd57631b 100644
--- a/src/consensus/test_consensus.conf
+++ b/src/consensus/test_consensus.conf
@@ -1,9 +1,10 @@
1[consensus] 1[consensus]
2AUTOSTART = YES 2AUTOSTART = YES
3# PORT = 2103 3PORT = 2103
4HOSTNAME = localhost 4HOSTNAME = localhost
5HOME = $SERVICEHOME 5HOME = $SERVICEHOME
6BINARY = gnunet-service-consensus 6BINARY = gnunet-service-consensus
7#PREFIX = gdbserver :12345
7ACCEPT_FROM = 127.0.0.1; 8ACCEPT_FROM = 127.0.0.1;
8ACCEPT_FROM6 = ::1; 9ACCEPT_FROM6 = ::1;
9UNIXPATH = /tmp/gnunet-service-consensus.sock 10UNIXPATH = /tmp/gnunet-service-consensus.sock
@@ -11,5 +12,10 @@ UNIX_MATCH_UID = YES
11UNIX_MATCH_GID = YES 12UNIX_MATCH_GID = YES
12OPTIONS = -LDEBUG 13OPTIONS = -LDEBUG
13 14
15
14[transport] 16[transport]
15OPTIONS = -LERROR 17OPTIONS = -LERROR
18
19
20[arm]
21DEFAULTSERVICES = core
diff --git a/src/consensus/test_consensus_api.c b/src/consensus/test_consensus_api.c
index a6bd60119..53f04c8b1 100644
--- a/src/consensus/test_consensus_api.c
+++ b/src/consensus/test_consensus_api.c
@@ -27,18 +27,50 @@
27#include "gnunet_testing_lib-new.h" 27#include "gnunet_testing_lib-new.h"
28 28
29 29
30static struct GNUNET_CONSENSUS_Handle *consensus; 30static struct GNUNET_CONSENSUS_Handle *consensus1;
31static struct GNUNET_CONSENSUS_Handle *consensus2;
32
33static int concluded1;
34static int concluded2;
35
36static int insert1;
37static int insert2;
31 38
32static struct GNUNET_HashCode session_id; 39static struct GNUNET_HashCode session_id;
33 40
34 41
35void 42static void conclude_done (void *cls,
43 unsigned int num_peers_in_consensus,
44 const struct GNUNET_PeerIdentity *peers_in_consensus)
45{
46 struct GNUNET_CONSENSUS_Handle *consensus;
47 consensus = (struct GNUNET_CONSENSUS_Handle *) cls;
48 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "concluded\n");
49}
50
51static void
36on_new_element (void *cls, 52on_new_element (void *cls,
37 struct GNUNET_CONSENSUS_Element *element) 53 struct GNUNET_CONSENSUS_Element *element)
38{ 54{
55 struct GNUNET_CONSENSUS_Handle *consensus;
56
57 GNUNET_assert (NULL != element);
58
59 consensus = *(struct GNUNET_CONSENSUS_Handle **) cls;
60
39 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "received new element\n"); 61 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "received new element\n");
62
63 GNUNET_CONSENSUS_conclude (consensus, GNUNET_TIME_UNIT_FOREVER_REL, &conclude_done, consensus);
64
40} 65}
41 66
67static void
68insert_done (void *cls, int success)
69{
70 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "insert done\n");
71}
72
73
42 74
43static void 75static void
44run (void *cls, 76run (void *cls,
@@ -47,10 +79,24 @@ run (void *cls,
47{ 79{
48 char *str = "foo"; 80 char *str = "foo";
49 81
82 struct GNUNET_CONSENSUS_Element el1 = {"foo", 4, 0};
83 struct GNUNET_CONSENSUS_Element el2 = {"bar", 4, 0};
84
85 GNUNET_log_setup ("test_consensus_api",
86 "DEBUG",
87 NULL);
88
89 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "testing consensus api\n");
90
50 GNUNET_CRYPTO_hash (str, strlen (str), &session_id); 91 GNUNET_CRYPTO_hash (str, strlen (str), &session_id);
51 consensus = GNUNET_CONSENSUS_create (cfg, 0, NULL, &session_id, on_new_element, cls); 92 consensus1 = GNUNET_CONSENSUS_create (cfg, 0, NULL, &session_id, on_new_element, &consensus1);
52 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to consensus service.\n"); 93 /*
53 GNUNET_assert (consensus != NULL); 94 consensus2 = GNUNET_CONSENSUS_create (cfg, 0, NULL, &session_id, on_new_element, &consensus2);
95 GNUNET_assert (consensus1 != NULL);
96 GNUNET_assert (consensus2 != NULL);
97 GNUNET_CONSENSUS_insert (consensus1, &el1, &insert_done, &consensus1);
98 GNUNET_CONSENSUS_insert (consensus2, &el2, &insert_done, &consensus2);
99 */
54} 100}
55 101
56 102
@@ -59,12 +105,6 @@ main (int argc, char **argv)
59{ 105{
60 int ret; 106 int ret;
61 107
62 GNUNET_log_setup ("test_consensus_api",
63 "DEBUG",
64 NULL);
65
66 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "testing consensus api\n");
67
68 ret = GNUNET_TESTING_peer_run ("test_consensus_api", 108 ret = GNUNET_TESTING_peer_run ("test_consensus_api",
69 "test_consensus.conf", 109 "test_consensus.conf",
70 &run, NULL); 110 &run, NULL);