aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2012-11-21 20:56:49 +0000
committerFlorian Dold <florian.dold@gmail.com>2012-11-21 20:56:49 +0000
commit6b1559589726297aa372048b4e388d2e1473a6f6 (patch)
treee4edfd3bc5865905de4db27229427ac998484824 /src
parent84d88f3ddc67f50c4493a20f33883c9242fd0d57 (diff)
downloadgnunet-6b1559589726297aa372048b4e388d2e1473a6f6.tar.gz
gnunet-6b1559589726297aa372048b4e388d2e1473a6f6.zip
started implementing consensus api and service
Diffstat (limited to 'src')
-rw-r--r--src/consensus/Makefile.am35
-rw-r--r--src/consensus/consensus.h95
-rw-r--r--src/consensus/consensus_api.c502
-rw-r--r--src/consensus/gnunet-service-consensus.cc74
-rw-r--r--src/consensus/test_consensus.conf15
-rw-r--r--src/consensus/test_consensus_api.c73
-rw-r--r--src/include/gnunet_consensus_service.h45
-rw-r--r--src/include/gnunet_protocols.h39
8 files changed, 850 insertions, 28 deletions
diff --git a/src/consensus/Makefile.am b/src/consensus/Makefile.am
index 5929a4d97..4eb06ceea 100644
--- a/src/consensus/Makefile.am
+++ b/src/consensus/Makefile.am
@@ -21,6 +21,9 @@ bin_PROGRAMS = \
21libexec_PROGRAMS = \ 21libexec_PROGRAMS = \
22 gnunet-service-consensus 22 gnunet-service-consensus
23 23
24lib_LTLIBRARIES = \
25 libgnunetconsensus.la
26
24gnunet_consensus_SOURCES = \ 27gnunet_consensus_SOURCES = \
25 gnunet-consensus.c 28 gnunet-consensus.c
26gnunet_consensus_LDADD = \ 29gnunet_consensus_LDADD = \
@@ -33,16 +36,28 @@ gnunet_service_consensus_LDADD = \
33 $(top_builddir)/src/util/libgnunetutil.la \ 36 $(top_builddir)/src/util/libgnunetutil.la \
34 $(GN_LIBINTL) 37 $(GN_LIBINTL)
35 38
39libgnunetconsensus_la_SOURCES = \
40 consensus_api.c
41libgnunetconsensus_la_LIBADD = \
42 $(top_builddir)/src/util/libgnunetutil.la \
43 $(LTLIBINTL)
44libgnunetconsensus_la_LDFLAGS = \
45 $(GN_LIB_LDFLAGS)
46
47check_PROGRAMS = \
48 test_consensus_api
36 49
37#check_PROGRAMS = \ 50if ENABLE_TEST_RUN
38# test_consensus_api 51TESTS = $(check_PROGRAMS)
52endif
53
54test_consensus_api_SOURCES = \
55 test_consensus_api.c
56test_consensus_api_LDADD = \
57 $(top_builddir)/src/util/libgnunetutil.la \
58 $(top_builddir)/src/testing/libgnunettesting.la \
59 $(top_builddir)/src/consensus/libgnunetconsensus.la
39 60
40#if ENABLE_TEST_RUN
41#TESTS = $(check_PROGRAMS)
42#endif
43#
44#test_consensus_api_SOURCES = \
45# test_consensus_api.c
46#test_consensus_api_LDADD = \
47# $(top_builddir)/src/util/libgnunetutil.la
48 61
62EXTRA_DIST = \
63 test_consensus.conf
diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h
new file mode 100644
index 000000000..3f1efe340
--- /dev/null
+++ b/src/consensus/consensus.h
@@ -0,0 +1,95 @@
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 * @author Florian Dold
23 * @file consensus/consensus.h
24 * @brief
25 */
26#ifndef NSE_H
27#define NSE_H
28
29#include "gnunet_common.h"
30
31GNUNET_NETWORK_STRUCT_BEGIN
32
33struct GNUNET_CONSENSUS_JoinMessage
34{
35 /**
36 * Type: GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_JOIN
37 */
38 struct GNUNET_MessageHeader header;
39
40 struct GNUNET_HashCode session_id;
41
42 uint16_t num_peers;
43
44 /* GNUNET_PeerIdentity[num_peers] */
45};
46
47
48struct GNUNET_CONSENSUS_ConcludeMessage
49{
50 /**
51 * Type: GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE
52 */
53 struct GNUNET_MessageHeader header;
54
55 struct GNUNET_TIME_RelativeNBO timeout;
56};
57
58
59struct GNUNET_CONSENSUS_ConcludeDoneMessage
60{
61 /**
62 * Type: GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE_DONE
63 */
64 struct GNUNET_MessageHeader header;
65
66 uint16_t num_peers;
67
68 /** PeerIdentity[num_peers] */
69};
70
71
72/**
73 * Message with an element
74 */
75struct GNUNET_CONSENSUS_ElementMessage
76{
77
78 /**
79 * Type:
80 * Either GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT
81 * or GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT_ELEMENT
82 */
83 struct GNUNET_MessageHeader header;
84
85 /**
86 * Type: GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_NEW_ELEMENT
87 */
88 uint16_t element_type;
89
90 /* rest: element data */
91};
92
93GNUNET_NETWORK_STRUCT_END
94
95#endif
diff --git a/src/consensus/consensus_api.c b/src/consensus/consensus_api.c
new file mode 100644
index 000000000..0d7e6c8e4
--- /dev/null
+++ b/src/consensus/consensus_api.c
@@ -0,0 +1,502 @@
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 3, 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 * @file consensus/consensus_api.c
23 * @brief
24 * @author Florian Dold
25 */
26#include "platform.h"
27#include "gnunet_protocols.h"
28#include "gnunet_client_lib.h"
29#include "gnunet_consensus_service.h"
30#include "consensus.h"
31
32
33#define LOG(kind,...) GNUNET_log_from (kind, "consensus-api",__VA_ARGS__)
34
35
36/**
37 * Handle for the service.
38 */
39struct GNUNET_CONSENSUS_Handle
40{
41 /**
42 * Configuration to use.
43 */
44 const struct GNUNET_CONFIGURATION_Handle *cfg;
45
46 /**
47 * Socket (if available).
48 */
49 struct GNUNET_CLIENT_Connection *client;
50
51 /**
52 * Callback for new elements. Not called for elements added locally.
53 */
54 GNUNET_CONSENSUS_NewElementCallback new_element_cb;
55
56 /**
57 * Closure for new_element_cb
58 */
59 void *new_element_cls;
60
61 /**
62 * Session identifier for the consensus session.
63 */
64 struct GNUNET_HashCode session_id;
65
66 /**
67 * Number of peers in the consensus. Optionally includes the local peer.
68 */
69 int num_peers;
70
71 /**
72 * Peer identities of peers in the consensus. Optionally includes the local peer.
73 */
74 struct GNUNET_PeerIdentity *peers;
75
76 /**
77 * Currently active transmit request.
78 */
79 struct GNUNET_CLIENT_TransmitHandle *th;
80
81 /**
82 * GNUNES_YES iff the join message has been sent to the service.
83 */
84 int joined;
85
86 /**
87 * Called when the current insertion operation finishes.
88 * NULL if there is no insert operation active.
89 */
90 GNUNET_CONSENSUS_InsertDoneCallback idc;
91
92 /**
93 * Closure for the insert done callback.
94 */
95 void *idc_cls;
96
97 /**
98 * An element that was requested to be inserted.
99 */
100 struct GNUNET_CONSENSUS_Element *insert_element;
101
102 /**
103 * Called when the conclude operation finishes or fails.
104 */
105 GNUNET_CONSENSUS_ConcludeCallback conclude_cb;
106
107 /**
108 * Closure for the conclude callback.
109 */
110 void *conclude_cls;
111
112 /**
113 * Deadline for the conclude operation.
114 */
115 struct GNUNET_TIME_Absolute conclude_deadline;
116};
117
118
119static void
120handle_new_element(struct GNUNET_CONSENSUS_Handle *consensus,
121 struct GNUNET_CONSENSUS_ElementMessage *msg)
122{
123 struct GNUNET_CONSENSUS_Element element;
124 element.type = msg->element_type;
125 element.size = msg->header.size - sizeof (struct GNUNET_CONSENSUS_ElementMessage);
126 element.data = &msg[1];
127 consensus->new_element_cb(consensus->new_element_cls, &element);
128}
129
130static void
131handle_conclude_done(struct GNUNET_CONSENSUS_Handle *consensus,
132 struct GNUNET_CONSENSUS_ConcludeDoneMessage *msg)
133{
134 GNUNET_assert (NULL != consensus->conclude_cb);
135 consensus->conclude_cb(consensus->conclude_cls,
136 msg->num_peers,
137 (struct GNUNET_PeerIdentity *) &msg[1]);
138 consensus->conclude_cb = NULL;
139}
140
141
142
143/**
144 * Type of a function to call when we receive a message
145 * from the service.
146 *
147 * @param cls closure
148 * @param msg message received, NULL on timeout or fatal error
149 */
150static void
151message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
152{
153 struct GNUNET_CONSENSUS_Handle *consensus = cls;
154 GNUNET_CONSENSUS_InsertDoneCallback idc;
155 void *idc_cls;
156
157 if (msg == NULL)
158 {
159 /* Error, timeout, death */
160 GNUNET_CLIENT_disconnect (consensus->client);
161 consensus->client = NULL;
162 consensus->new_element_cb(NULL, NULL);
163 if (NULL != consensus->idc)
164 {
165 consensus->idc(consensus->idc_cls, GNUNET_NO);
166 consensus->idc = NULL;
167 consensus->idc_cls = NULL;
168 }
169 return;
170 }
171
172 switch (ntohs(msg->type))
173 {
174 case GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT_ACK:
175 idc = consensus->idc;
176 consensus->idc = NULL;
177 idc_cls = consensus->idc_cls;
178 consensus->idc_cls = NULL;
179 idc(idc_cls, GNUNET_YES);
180 break;
181 case GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT:
182 handle_new_element(consensus, (struct GNUNET_CONSENSUS_ElementMessage *) msg);
183 break;
184 case GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE_DONE:
185 handle_conclude_done(consensus, (struct GNUNET_CONSENSUS_ConcludeDoneMessage *) msg);
186 break;
187 default:
188 LOG(GNUNET_ERROR_TYPE_WARNING, "did not understand message type sent by service, ignoring");
189 }
190 GNUNET_CLIENT_receive (consensus->client, &message_handler, consensus,
191 GNUNET_TIME_UNIT_FOREVER_REL);
192}
193
194
195
196
197/**
198 * Function called to notify a client about the connection
199 * begin ready to queue more data. "buf" will be
200 * NULL and "size" zero if the connection was closed for
201 * writing in the meantime.
202 *
203 * @param cls closure
204 * @param size number of bytes available in buf
205 * @param buf where the callee should write the message
206 * @return number of bytes written to buf
207 */
208static size_t
209transmit_insert (void *cls, size_t size, void *buf)
210{
211 struct GNUNET_CONSENSUS_ElementMessage *msg;
212 struct GNUNET_CONSENSUS_Handle *consensus;
213 int msize;
214
215 GNUNET_assert (NULL != buf);
216
217 consensus = cls;
218
219 GNUNET_assert (NULL != consensus->insert_element);
220
221 consensus->th = NULL;
222
223
224 msg = buf;
225
226 msize = sizeof (struct GNUNET_CONSENSUS_ElementMessage) +
227 consensus->insert_element->size;
228
229 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT);
230 msg->header.size = htons (msize);
231 memcpy(&msg[1],
232 consensus->insert_element->data,
233 consensus->insert_element->size);
234
235 return msize;
236}
237
238
239/**
240 * Function called to notify a client about the connection
241 * begin ready to queue more data. "buf" will be
242 * NULL and "size" zero if the connection was closed for
243 * writing in the meantime.
244 *
245 * @param cls closure
246 * @param size number of bytes available in buf
247 * @param buf where the callee should write the message
248 * @return number of bytes written to buf
249 */
250static size_t
251transmit_join (void *cls, size_t size, void *buf)
252{
253 struct GNUNET_CONSENSUS_JoinMessage *msg;
254 struct GNUNET_CONSENSUS_Handle *consensus;
255 int msize;
256
257 LOG(GNUNET_ERROR_TYPE_DEBUG, "transmitting CLIENT_JOIN to service\n");
258
259 GNUNET_assert (NULL != buf);
260
261 consensus = cls;
262 consensus->th = NULL;
263 consensus->joined = 1;
264
265 msg = buf;
266
267 msize = sizeof (struct GNUNET_CONSENSUS_JoinMessage) +
268 consensus->num_peers * sizeof (struct GNUNET_PeerIdentity);
269
270 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_JOIN);
271 msg->header.size = htons (msize);
272 msg->session_id = consensus->session_id;
273 msg->num_peers = htons (consensus->num_peers);
274 memcpy(&msg[1],
275 consensus->peers,
276 consensus->num_peers * sizeof (struct GNUNET_PeerIdentity));
277
278 if (consensus->insert_element != NULL)
279 {
280 consensus->th =
281 GNUNET_CLIENT_notify_transmit_ready (consensus->client,
282 msize,
283 GNUNET_TIME_UNIT_FOREVER_REL,
284 GNUNET_NO, &transmit_insert, consensus);
285 }
286
287
288 GNUNET_CLIENT_receive (consensus->client, &message_handler, consensus,
289 GNUNET_TIME_UNIT_FOREVER_REL);
290
291 return msize;
292}
293
294
295/**
296 * Function called to notify a client about the connection
297 * begin ready to queue more data. "buf" will be
298 * NULL and "size" zero if the connection was closed for
299 * writing in the meantime.
300 *
301 * @param cls closure
302 * @param size number of bytes available in buf
303 * @param buf where the callee should write the message
304 * @return number of bytes written to buf
305 */
306static size_t
307transmit_conclude (void *cls, size_t size, void *buf)
308{
309 struct GNUNET_CONSENSUS_ConcludeMessage *msg;
310 struct GNUNET_CONSENSUS_Handle *consensus;
311 int msize;
312
313 GNUNET_assert (NULL != buf);
314
315 consensus = cls;
316 consensus->th = NULL;
317
318 msg = buf;
319
320 msize = sizeof (struct GNUNET_CONSENSUS_ConcludeMessage);
321
322 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE);
323 msg->header.size = htons (msize);
324 msg->timeout =
325 GNUNET_TIME_relative_hton(GNUNET_TIME_absolute_get_remaining(consensus->conclude_deadline));
326
327 return msize;
328}
329
330
331
332
333/**
334 * Create a consensus session.
335 *
336 * @param cfg
337 * @param num_peers
338 * @param peers array of peers participating in this consensus session
339 * Inclusion of the local peer is optional.
340 * @param session_id session identifier
341 * Allows a group of peers to have more than consensus session.
342 * @param num_initial_elements number of entries in the 'initial_elements' array
343 * @param initial_elements our elements for the consensus (each of 'element_size'
344 * @param new_element callback, called when a new element is added to the set by
345 * another peer
346 * @param new_element_cls closure for new_element
347 * @return handle to use, NULL on error
348 */
349struct GNUNET_CONSENSUS_Handle *
350GNUNET_CONSENSUS_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
351 unsigned int num_peers,
352 const struct GNUNET_PeerIdentity *peers,
353 const struct GNUNET_HashCode *session_id,
354 /*
355 unsigned int num_initial_elements,
356 const struct GNUNET_CONSENSUS_Element **initial_elements,
357 */
358 GNUNET_CONSENSUS_NewElementCallback new_element,
359 void *new_element_cls)
360{
361 struct GNUNET_CONSENSUS_Handle *consensus;
362 size_t join_message_size;
363
364
365 consensus = GNUNET_malloc (sizeof (struct GNUNET_CONSENSUS_Handle));
366 consensus->cfg = cfg;
367 consensus->new_element_cb = new_element;
368 consensus->new_element_cls = new_element_cls;
369 consensus->num_peers = num_peers;
370 consensus->session_id = *session_id;
371
372
373
374 if (0 == num_peers)
375 {
376 consensus->peers = NULL;
377 }
378 else if (num_peers > 0)
379 {
380
381 consensus->peers = GNUNET_memdup (peers, num_peers * sizeof (struct GNUNET_PeerIdentity));
382 }
383 else
384 {
385 GNUNET_break (0);
386 }
387
388
389 consensus->client = GNUNET_CLIENT_connect ("consensus", cfg);
390
391 GNUNET_assert (consensus->client != NULL);
392
393 join_message_size = (sizeof (struct GNUNET_CONSENSUS_JoinMessage)) +
394 (num_peers * sizeof (struct GNUNET_PeerIdentity));
395
396 consensus->th =
397 GNUNET_CLIENT_notify_transmit_ready (consensus->client,
398 join_message_size,
399 GNUNET_TIME_UNIT_FOREVER_REL,
400 GNUNET_NO, &transmit_join, consensus);
401
402
403 GNUNET_assert (consensus->th != NULL);
404
405 return consensus;
406}
407
408
409
410/**
411 * Insert an element in the set being reconsiled. Must not be called after
412 * "GNUNET_CONSENSUS_conclude".
413 *
414 * @param consensus handle for the consensus session
415 * @param element the element to be inserted
416 * @param idc function called when we are done with this element and it
417 * is thus allowed to call GNUNET_CONSENSUS_insert again
418 * @param idc_cls closure for 'idc'
419 */
420void
421GNUNET_CONSENSUS_insert (struct GNUNET_CONSENSUS_Handle *consensus,
422 const struct GNUNET_CONSENSUS_Element *element,
423 GNUNET_CONSENSUS_InsertDoneCallback idc,
424 void *idc_cls)
425{
426
427 GNUNET_assert (NULL == consensus->idc);
428 GNUNET_assert (NULL == consensus->insert_element);
429
430 consensus->idc = idc;
431 consensus->idc_cls = idc_cls;
432 consensus->insert_element = GNUNET_memdup(element, sizeof (struct GNUNET_CONSENSUS_Element) + element->size);
433
434 if (consensus->joined == 0)
435 {
436 GNUNET_assert (NULL != consensus->th);
437 return;
438 }
439
440 GNUNET_assert (NULL == consensus->th);
441
442 consensus->th =
443 GNUNET_CLIENT_notify_transmit_ready (consensus->client,
444 element->size + sizeof (struct GNUNET_CONSENSUS_ElementMessage),
445 GNUNET_TIME_UNIT_FOREVER_REL,
446 GNUNET_NO, &transmit_insert, consensus);
447}
448
449
450/**
451 * We are finished inserting new elements into the consensus;
452 * try to conclude the consensus within a given time window.
453 *
454 * @param consensus consensus session
455 * @param timeout timeout after which the conculde callback
456 * must be called
457 * @param conclude called when the conclusion was successful
458 * @param conclude_cls closure for the conclude callback
459 */
460void
461GNUNET_CONSENSUS_conclude (struct GNUNET_CONSENSUS_Handle *consensus,
462 struct GNUNET_TIME_Relative timeout,
463 GNUNET_CONSENSUS_ConcludeCallback conclude,
464 void *conclude_cls)
465{
466 GNUNET_assert (NULL == consensus->th);
467 GNUNET_assert (NULL == consensus->conclude_cb);
468
469 consensus->conclude_cls = conclude_cls;
470 consensus->conclude_cb = conclude;
471 consensus->conclude_deadline = GNUNET_TIME_relative_to_absolute(timeout);
472
473 consensus->th =
474 GNUNET_CLIENT_notify_transmit_ready (consensus->client,
475 sizeof (struct GNUNET_CONSENSUS_ConcludeMessage),
476 timeout,
477 GNUNET_NO, &transmit_conclude, consensus);
478 if (NULL == consensus->th)
479 {
480 conclude(conclude_cls, 0, NULL);
481 }
482}
483
484
485/**
486 * Destroy a consensus handle (free all state associated with
487 * it, no longer call any of the callbacks).
488 *
489 * @param consensus handle to destroy
490 */
491void
492GNUNET_CONSENSUS_destroy (struct GNUNET_CONSENSUS_Handle *consensus)
493{
494 if (consensus->client != NULL)
495 {
496 GNUNET_CLIENT_disconnect (consensus->client);
497 consensus->client = NULL;
498 }
499 GNUNET_free (consensus->peers);
500 GNUNET_free (consensus);
501}
502
diff --git a/src/consensus/gnunet-service-consensus.cc b/src/consensus/gnunet-service-consensus.cc
index 82ea5ef79..9e8aba6bb 100644
--- a/src/consensus/gnunet-service-consensus.cc
+++ b/src/consensus/gnunet-service-consensus.cc
@@ -24,23 +24,87 @@
24#include <stdint.h> 24#include <stdint.h>
25 25
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_protocols.h"
27#include "gnunet_common.h" 28#include "gnunet_common.h"
28#include "gnunet_service_lib.h" 29#include "gnunet_service_lib.h"
30#include "gnunet_consensus_service.h"
31#include "consensus.h"
29 32
30using namespace std; 33using namespace std;
31 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
32/** 63/**
33 * Process statistics requests. 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.
34 * 91 *
35 * @param cls closure 92 * @param cls closure
36 * @param server the initialized server 93 * @param server the initialized server
37 * @param c configuration to use 94 * @param c configuration to use
38 */ 95 */
39static void 96static void
40run (void *cls, struct GNUNET_SERVER_Handle *server, 97run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c)
41 const struct GNUNET_CONFIGURATION_Handle *c)
42{ 98{
43 /* TODO */ 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);
44} 108}
45 109
46 110
@@ -55,6 +119,6 @@ int
55main (int argc, char *const *argv) 119main (int argc, char *const *argv)
56{ 120{
57 return (GNUNET_OK == 121 return (GNUNET_OK ==
58 GNUNET_SERVICE_run (argc, argv, "statistics", GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; 122 GNUNET_SERVICE_run (argc, argv, "consensus", GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
59} 123}
60 124
diff --git a/src/consensus/test_consensus.conf b/src/consensus/test_consensus.conf
new file mode 100644
index 000000000..143313ff2
--- /dev/null
+++ b/src/consensus/test_consensus.conf
@@ -0,0 +1,15 @@
1[consensus]
2AUTOSTART = YES
3# PORT = 2103
4HOSTNAME = localhost
5HOME = $SERVICEHOME
6BINARY = gnunet-service-consensus
7ACCEPT_FROM = 127.0.0.1;
8ACCEPT_FROM6 = ::1;
9UNIXPATH = /tmp/gnunet-service-consensus.sock
10UNIX_MATCH_UID = YES
11UNIX_MATCH_GID = YES
12OPTIONS = -LDEBUG
13
14[transport]
15OPTIONS = -LERROR
diff --git a/src/consensus/test_consensus_api.c b/src/consensus/test_consensus_api.c
new file mode 100644
index 000000000..a6bd60119
--- /dev/null
+++ b/src/consensus/test_consensus_api.c
@@ -0,0 +1,73 @@
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 3, 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 * @file consensus/test_consensus_api.c
22 * @brief testcase for consensus_api.c
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_consensus_service.h"
27#include "gnunet_testing_lib-new.h"
28
29
30static struct GNUNET_CONSENSUS_Handle *consensus;
31
32static struct GNUNET_HashCode session_id;
33
34
35void
36on_new_element (void *cls,
37 struct GNUNET_CONSENSUS_Element *element)
38{
39 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "received new element\n");
40}
41
42
43static void
44run (void *cls,
45 const struct GNUNET_CONFIGURATION_Handle *cfg,
46 struct GNUNET_TESTING_Peer *peer)
47{
48 char *str = "foo";
49
50 GNUNET_CRYPTO_hash (str, strlen (str), &session_id);
51 consensus = GNUNET_CONSENSUS_create (cfg, 0, NULL, &session_id, on_new_element, cls);
52 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to consensus service.\n");
53 GNUNET_assert (consensus != NULL);
54}
55
56
57int
58main (int argc, char **argv)
59{
60 int ret;
61
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",
69 "test_consensus.conf",
70 &run, NULL);
71 return ret;
72}
73
diff --git a/src/include/gnunet_consensus_service.h b/src/include/gnunet_consensus_service.h
index a2bf69021..8e2d8f572 100644
--- a/src/include/gnunet_consensus_service.h
+++ b/src/include/gnunet_consensus_service.h
@@ -38,20 +38,42 @@ extern "C"
38#include "platform.h" 38#include "platform.h"
39#include "gnunet_common.h" 39#include "gnunet_common.h"
40#include "gnunet_time_lib.h" 40#include "gnunet_time_lib.h"
41#include "gnunet_configuration_lib.h"
41 42
42 43
43/** 44/**
44 * Called when a new element was received from another peer; elements 45 * An element of the consensus set.
45 * given to a consensus operation by the local peer are NOT given 46 */
47struct GNUNET_CONSENSUS_Element
48{
49 /**
50 * The actual data of the element.
51 */
52 const void *data;
53
54 /**
55 * Size of the element's data.
56 */
57 uint16_t size;
58
59 /**
60 * Application specific element type
61 */
62 uint16_t type;
63};
64
65
66/**
67 * Called when a new element was received from another peer, or an error occured.
68 *
69 * Elements given to a consensus operation by the local peer are NOT given
46 * to this callback. 70 * to this callback.
47 * 71 *
48 * @param cls closure 72 * @param cls closure
49 * @param element_size will match the size given to GNUNET_CONSENSUS_create 73 * @param element new element, NULL on error
50 * @param element
51 */ 74 */
52typedef void (*GNUNET_CONSENSUS_NewElementCallback) (void *cls, 75typedef void (*GNUNET_CONSENSUS_NewElementCallback) (void *cls,
53 size_t element_size, 76 struct GNUNET_CONSENSUS_Element *element);
54 const void *element);
55 77
56 78
57 79
@@ -67,9 +89,9 @@ struct GNUNET_CONSENSUS_Handle;
67 * @param cfg 89 * @param cfg
68 * @param num_peers 90 * @param num_peers
69 * @param peers array of peers participating in this consensus session 91 * @param peers array of peers participating in this consensus session
92 * Inclusion of the local peer is optional.
70 * @param session_id session identifier 93 * @param session_id session identifier
71 * Allows a group of peers to have more than consensus session. 94 * Allows a group of peers to have more than consensus session.
72 * @param element_size size of the elements in the reconciled set in bytes
73 * @param num_initial_elements number of entries in the 'initial_elements' array 95 * @param num_initial_elements number of entries in the 'initial_elements' array
74 * @param initial_elements our elements for the consensus (each of 'element_size' 96 * @param initial_elements our elements for the consensus (each of 'element_size'
75 * @param new_element callback, called when a new element is added to the set by 97 * @param new_element callback, called when a new element is added to the set by
@@ -82,9 +104,10 @@ GNUNET_CONSENSUS_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
82 unsigned int num_peers, 104 unsigned int num_peers,
83 const struct GNUNET_PeerIdentity *peers, 105 const struct GNUNET_PeerIdentity *peers,
84 const struct GNUNET_HashCode *session_id, 106 const struct GNUNET_HashCode *session_id,
85 size_t element_size, 107 /*
86 unsigned int num_initial_elements, 108 unsigned int num_initial_elements,
87 const void **initial_elements, 109 const struct GNUNET_CONSENSUS_Element **initial_elements,
110 */
88 GNUNET_CONSENSUS_NewElementCallback new_element, 111 GNUNET_CONSENSUS_NewElementCallback new_element,
89 void *new_element_cls); 112 void *new_element_cls);
90 113
@@ -107,7 +130,6 @@ typedef void (*GNUNET_CONSENSUS_InsertDoneCallback) (void *cls,
107 * "GNUNET_CONSENSUS_conclude". 130 * "GNUNET_CONSENSUS_conclude".
108 * 131 *
109 * @param consensus handle for the consensus session 132 * @param consensus handle for the consensus session
110 * @param element_size must match element size from GNUNET_CONSENSUS_create
111 * @param element the element to be inserted 133 * @param element the element to be inserted
112 * @param idc function called when we are done with this element and it 134 * @param idc function called when we are done with this element and it
113 * is thus allowed to call GNUNET_CONSENSUS_insert again 135 * is thus allowed to call GNUNET_CONSENSUS_insert again
@@ -115,8 +137,7 @@ typedef void (*GNUNET_CONSENSUS_InsertDoneCallback) (void *cls,
115 */ 137 */
116void 138void
117GNUNET_CONSENSUS_insert (struct GNUNET_CONSENSUS_Handle *consensus, 139GNUNET_CONSENSUS_insert (struct GNUNET_CONSENSUS_Handle *consensus,
118 size_t element_size, 140 const struct GNUNET_CONSENSUS_Element *element,
119 const void *element,
120 GNUNET_CONSENSUS_InsertDoneCallback idc, 141 GNUNET_CONSENSUS_InsertDoneCallback idc,
121 void *idc_cls); 142 void *idc_cls);
122 143
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index b9102f429..21ebbfdfe 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -1606,8 +1606,45 @@ extern "C"
1606#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT 505 1606#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT 505
1607 1607
1608 1608
1609/*******************************************************************************
1610 * CONSENSUS message types
1611 ******************************************************************************/
1612
1613/**
1614 * Join a consensus session. Sent by client to service as first message.
1615 */
1616#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_JOIN 520
1617
1618/**
1619 * Insert an element. Sent by client to service.
1620 */
1621#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT 521
1622
1623/**
1624 * The has accepted the inserted element and is ready to receive new elements.
1625 * Sent by service to client.
1626 */
1627#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT_ACK 522
1628
1629/**
1630 * Sent by service when a new element is added.
1631 */
1632#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT 523
1633
1634/**
1635 * Sent by client to service in order to start the consensus conclusion.
1636 */
1637#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE 524
1638
1639/**
1640 * Sent by service to client in order to signal a completed consensus conclusion.
1641 * Last message sent in a consensus session.
1642 */
1643#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE_DONE 524
1644
1645
1609/** 1646/**
1610 * Next available: 520 1647 * Next available: 570
1611 */ 1648 */
1612 1649
1613 1650