diff options
Diffstat (limited to 'src/consensus/consensus_api.c')
-rw-r--r-- | src/consensus/consensus_api.c | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/src/consensus/consensus_api.c b/src/consensus/consensus_api.c deleted file mode 100644 index b4a9e5d39..000000000 --- a/src/consensus/consensus_api.c +++ /dev/null | |||
@@ -1,349 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file consensus/consensus_api.c | ||
23 | * @brief | ||
24 | * @author Florian Dold | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_protocols.h" | ||
29 | #include "gnunet_client_lib.h" | ||
30 | #include "gnunet_consensus_service.h" | ||
31 | #include "consensus.h" | ||
32 | |||
33 | |||
34 | #define LOG(kind, ...) GNUNET_log_from (kind, "consensus-api", __VA_ARGS__) | ||
35 | |||
36 | |||
37 | /** | ||
38 | * Handle for the service. | ||
39 | */ | ||
40 | struct GNUNET_CONSENSUS_Handle | ||
41 | { | ||
42 | /** | ||
43 | * Configuration to use. | ||
44 | */ | ||
45 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
46 | |||
47 | /** | ||
48 | * Callback for new elements. Not called for elements added locally. | ||
49 | */ | ||
50 | GNUNET_CONSENSUS_ElementCallback new_element_cb; | ||
51 | |||
52 | /** | ||
53 | * Closure for @e new_element_cb | ||
54 | */ | ||
55 | void *new_element_cls; | ||
56 | |||
57 | /** | ||
58 | * The (local) session identifier for the consensus session. | ||
59 | */ | ||
60 | struct GNUNET_HashCode session_id; | ||
61 | |||
62 | /** | ||
63 | * #GNUNET_YES iff the join message has been sent to the service. | ||
64 | */ | ||
65 | int joined; | ||
66 | |||
67 | /** | ||
68 | * Called when the conclude operation finishes or fails. | ||
69 | */ | ||
70 | GNUNET_CONSENSUS_ConcludeCallback conclude_cb; | ||
71 | |||
72 | /** | ||
73 | * Closure for the @e conclude_cb callback. | ||
74 | */ | ||
75 | void *conclude_cls; | ||
76 | |||
77 | /** | ||
78 | * Deadline for the conclude operation. | ||
79 | */ | ||
80 | struct GNUNET_TIME_Absolute conclude_deadline; | ||
81 | |||
82 | /** | ||
83 | * Message queue for the client. | ||
84 | */ | ||
85 | struct GNUNET_MQ_Handle *mq; | ||
86 | }; | ||
87 | |||
88 | |||
89 | /** | ||
90 | * FIXME: this should not bee necessary when the API | ||
91 | * issue has been fixed | ||
92 | */ | ||
93 | struct InsertDoneInfo | ||
94 | { | ||
95 | GNUNET_CONSENSUS_InsertDoneCallback idc; | ||
96 | void *cls; | ||
97 | }; | ||
98 | |||
99 | |||
100 | /** | ||
101 | * Called when the server has sent is a new element | ||
102 | * | ||
103 | * @param cls consensus handle | ||
104 | * @param msg element message | ||
105 | */ | ||
106 | static int | ||
107 | check_new_element (void *cls, | ||
108 | const struct GNUNET_CONSENSUS_ElementMessage *msg) | ||
109 | { | ||
110 | /* any size is fine, elements are variable-size */ | ||
111 | return GNUNET_OK; | ||
112 | } | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Called when the server has sent is a new element | ||
117 | * | ||
118 | * @param cls consensus handle | ||
119 | * @param msg element message | ||
120 | */ | ||
121 | static void | ||
122 | handle_new_element (void *cls, | ||
123 | const struct GNUNET_CONSENSUS_ElementMessage *msg) | ||
124 | { | ||
125 | struct GNUNET_CONSENSUS_Handle *consensus = cls; | ||
126 | struct GNUNET_SET_Element element; | ||
127 | |||
128 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
129 | "received new element\n"); | ||
130 | element.element_type = msg->element_type; | ||
131 | element.size = ntohs (msg->header.size) - sizeof(struct | ||
132 | GNUNET_CONSENSUS_ElementMessage); | ||
133 | element.data = &msg[1]; | ||
134 | consensus->new_element_cb (consensus->new_element_cls, | ||
135 | &element); | ||
136 | } | ||
137 | |||
138 | |||
139 | /** | ||
140 | * Called when the server has announced | ||
141 | * that the conclusion is over. | ||
142 | * | ||
143 | * @param cls consensus handle | ||
144 | * @param msg conclude done message | ||
145 | */ | ||
146 | static void | ||
147 | handle_conclude_done (void *cls, | ||
148 | const struct GNUNET_MessageHeader *msg) | ||
149 | { | ||
150 | struct GNUNET_CONSENSUS_Handle *consensus = cls; | ||
151 | GNUNET_CONSENSUS_ConcludeCallback cc; | ||
152 | |||
153 | GNUNET_MQ_destroy (consensus->mq); | ||
154 | consensus->mq = NULL; | ||
155 | GNUNET_assert (NULL != (cc = consensus->conclude_cb)); | ||
156 | consensus->conclude_cb = NULL; | ||
157 | cc (consensus->conclude_cls); | ||
158 | } | ||
159 | |||
160 | |||
161 | /** | ||
162 | * Generic error handler, called with the appropriate | ||
163 | * error code and the same closure specified at the creation of | ||
164 | * the message queue. | ||
165 | * Not every message queue implementation supports an error handler. | ||
166 | * | ||
167 | * @param cls closure, same closure as for the message handlers | ||
168 | * @param error error code | ||
169 | */ | ||
170 | static void | ||
171 | mq_error_handler (void *cls, | ||
172 | enum GNUNET_MQ_Error error) | ||
173 | { | ||
174 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
175 | "consensus service disconnected us\n"); | ||
176 | } | ||
177 | |||
178 | |||
179 | /** | ||
180 | * Create a consensus session. | ||
181 | * | ||
182 | * @param cfg configuration to use for connecting to the consensus service | ||
183 | * @param num_peers number of peers in the peers array | ||
184 | * @param peers array of peers participating in this consensus session | ||
185 | * Inclusion of the local peer is optional. | ||
186 | * @param session_id session identifier | ||
187 | * Allows a group of peers to have more than consensus session. | ||
188 | * @param start start time of the consensus, conclude should be called before | ||
189 | * the start time. | ||
190 | * @param deadline time when the consensus should have concluded | ||
191 | * @param new_element_cb callback, called when a new element is added to the set by | ||
192 | * another peer | ||
193 | * @param new_element_cls closure for new_element | ||
194 | * @return handle to use, NULL on error | ||
195 | */ | ||
196 | struct GNUNET_CONSENSUS_Handle * | ||
197 | GNUNET_CONSENSUS_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
198 | unsigned int num_peers, | ||
199 | const struct GNUNET_PeerIdentity *peers, | ||
200 | const struct GNUNET_HashCode *session_id, | ||
201 | struct GNUNET_TIME_Absolute start, | ||
202 | struct GNUNET_TIME_Absolute deadline, | ||
203 | GNUNET_CONSENSUS_ElementCallback new_element_cb, | ||
204 | void *new_element_cls) | ||
205 | { | ||
206 | struct GNUNET_CONSENSUS_Handle *consensus | ||
207 | = GNUNET_new (struct GNUNET_CONSENSUS_Handle); | ||
208 | struct GNUNET_MQ_MessageHandler mq_handlers[] = { | ||
209 | GNUNET_MQ_hd_var_size (new_element, | ||
210 | GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT, | ||
211 | struct GNUNET_CONSENSUS_ElementMessage, | ||
212 | consensus), | ||
213 | GNUNET_MQ_hd_fixed_size (conclude_done, | ||
214 | GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE_DONE, | ||
215 | struct GNUNET_MessageHeader, | ||
216 | consensus), | ||
217 | GNUNET_MQ_handler_end () | ||
218 | }; | ||
219 | struct GNUNET_CONSENSUS_JoinMessage *join_msg; | ||
220 | struct GNUNET_MQ_Envelope *ev; | ||
221 | |||
222 | consensus->cfg = cfg; | ||
223 | consensus->new_element_cb = new_element_cb; | ||
224 | consensus->new_element_cls = new_element_cls; | ||
225 | consensus->session_id = *session_id; | ||
226 | consensus->mq = GNUNET_CLIENT_connect (cfg, | ||
227 | "consensus", | ||
228 | mq_handlers, | ||
229 | &mq_error_handler, | ||
230 | consensus); | ||
231 | if (NULL == consensus->mq) | ||
232 | { | ||
233 | GNUNET_free (consensus); | ||
234 | return NULL; | ||
235 | } | ||
236 | ev = GNUNET_MQ_msg_extra (join_msg, | ||
237 | (num_peers * sizeof(struct GNUNET_PeerIdentity)), | ||
238 | GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_JOIN); | ||
239 | |||
240 | join_msg->session_id = consensus->session_id; | ||
241 | join_msg->start = GNUNET_TIME_absolute_hton (start); | ||
242 | join_msg->deadline = GNUNET_TIME_absolute_hton (deadline); | ||
243 | join_msg->num_peers = htonl (num_peers); | ||
244 | GNUNET_memcpy (&join_msg[1], | ||
245 | peers, | ||
246 | num_peers * sizeof(struct GNUNET_PeerIdentity)); | ||
247 | |||
248 | GNUNET_MQ_send (consensus->mq, ev); | ||
249 | return consensus; | ||
250 | } | ||
251 | |||
252 | |||
253 | static void | ||
254 | idc_adapter (void *cls) | ||
255 | { | ||
256 | struct InsertDoneInfo *i = cls; | ||
257 | |||
258 | i->idc (i->cls, GNUNET_OK); | ||
259 | GNUNET_free (i); | ||
260 | } | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Insert an element in the set being reconsiled. Must not be called after | ||
265 | * "GNUNET_CONSENSUS_conclude". | ||
266 | * | ||
267 | * @param consensus handle for the consensus session | ||
268 | * @param element the element to be inserted | ||
269 | * @param idc function called when we are done with this element and it | ||
270 | * is thus allowed to call GNUNET_CONSENSUS_insert again | ||
271 | * @param idc_cls closure for 'idc' | ||
272 | */ | ||
273 | void | ||
274 | GNUNET_CONSENSUS_insert (struct GNUNET_CONSENSUS_Handle *consensus, | ||
275 | const struct GNUNET_SET_Element *element, | ||
276 | GNUNET_CONSENSUS_InsertDoneCallback idc, | ||
277 | void *idc_cls) | ||
278 | { | ||
279 | struct GNUNET_CONSENSUS_ElementMessage *element_msg; | ||
280 | struct GNUNET_MQ_Envelope *ev; | ||
281 | struct InsertDoneInfo *i; | ||
282 | |||
283 | LOG (GNUNET_ERROR_TYPE_DEBUG, "inserting, size=%u\n", element->size); | ||
284 | |||
285 | ev = GNUNET_MQ_msg_extra (element_msg, element->size, | ||
286 | GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT); | ||
287 | |||
288 | GNUNET_memcpy (&element_msg[1], element->data, element->size); | ||
289 | |||
290 | if (NULL != idc) | ||
291 | { | ||
292 | i = GNUNET_new (struct InsertDoneInfo); | ||
293 | i->idc = idc; | ||
294 | i->cls = idc_cls; | ||
295 | GNUNET_MQ_notify_sent (ev, idc_adapter, i); | ||
296 | } | ||
297 | GNUNET_MQ_send (consensus->mq, ev); | ||
298 | } | ||
299 | |||
300 | |||
301 | /** | ||
302 | * We are done with inserting new elements into the consensus; | ||
303 | * try to conclude the consensus within a given time window. | ||
304 | * After conclude has been called, no further elements may be | ||
305 | * inserted by the client. | ||
306 | * | ||
307 | * @param consensus consensus session | ||
308 | * @param deadline deadline after which the conculde callback | ||
309 | * must be called | ||
310 | * @param conclude called when the conclusion was successful | ||
311 | * @param conclude_cls closure for the conclude callback | ||
312 | */ | ||
313 | void | ||
314 | GNUNET_CONSENSUS_conclude (struct GNUNET_CONSENSUS_Handle *consensus, | ||
315 | GNUNET_CONSENSUS_ConcludeCallback conclude, | ||
316 | void *conclude_cls) | ||
317 | { | ||
318 | struct GNUNET_MQ_Envelope *ev; | ||
319 | |||
320 | GNUNET_assert (NULL != conclude); | ||
321 | GNUNET_assert (NULL == consensus->conclude_cb); | ||
322 | |||
323 | consensus->conclude_cls = conclude_cls; | ||
324 | consensus->conclude_cb = conclude; | ||
325 | |||
326 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE); | ||
327 | GNUNET_MQ_send (consensus->mq, ev); | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * Destroy a consensus handle (free all state associated with | ||
333 | * it, no longer call any of the callbacks). | ||
334 | * | ||
335 | * @param consensus handle to destroy | ||
336 | */ | ||
337 | void | ||
338 | GNUNET_CONSENSUS_destroy (struct GNUNET_CONSENSUS_Handle *consensus) | ||
339 | { | ||
340 | if (NULL != consensus->mq) | ||
341 | { | ||
342 | GNUNET_MQ_destroy (consensus->mq); | ||
343 | consensus->mq = NULL; | ||
344 | } | ||
345 | GNUNET_free (consensus); | ||
346 | } | ||
347 | |||
348 | |||
349 | /* end of consensus_api.c */ | ||