diff options
author | Florian Dold <florian.dold@gmail.com> | 2015-10-05 22:27:46 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2015-10-05 22:27:46 +0000 |
commit | 2b8265dc5cbf796f01d40c6b1e82fd0852364d16 (patch) | |
tree | dd7ec7eac9972dff01c696a105bd589236ccaf63 /src/consensus/gnunet-service-consensus.c | |
parent | a11e17158609766f29c40de6daecf5ce02b38e6c (diff) | |
download | gnunet-2b8265dc5cbf796f01d40c6b1e82fd0852364d16.tar.gz gnunet-2b8265dc5cbf796f01d40c6b1e82fd0852364d16.zip |
consensus
- fix problem with evil peers and loopback set operations
- logging
- fix round numbering
Diffstat (limited to 'src/consensus/gnunet-service-consensus.c')
-rw-r--r-- | src/consensus/gnunet-service-consensus.c | 133 |
1 files changed, 47 insertions, 86 deletions
diff --git a/src/consensus/gnunet-service-consensus.c b/src/consensus/gnunet-service-consensus.c index 5a2f62cd5..60bc294ed 100644 --- a/src/consensus/gnunet-service-consensus.c +++ b/src/consensus/gnunet-service-consensus.c | |||
@@ -320,19 +320,10 @@ struct Step | |||
320 | unsigned int is_finished; | 320 | unsigned int is_finished; |
321 | 321 | ||
322 | /* | 322 | /* |
323 | * Round that this step should start. | 323 | * Synchrony round of the task. |
324 | * If not all prerequisites have run, | 324 | * Determines the deadline for the task. |
325 | * the task will run anyway. | ||
326 | */ | 325 | */ |
327 | unsigned int start_round; | 326 | unsigned int round; |
328 | |||
329 | /* | ||
330 | * Number of rounds this step occupies. | ||
331 | * | ||
332 | * Some steps are more expensive, and thus | ||
333 | * are allocated more rounds. | ||
334 | */ | ||
335 | unsigned int num_rounds; | ||
336 | 327 | ||
337 | /** | 328 | /** |
338 | * Human-readable name for | 329 | * Human-readable name for |
@@ -737,34 +728,6 @@ send_to_client_iter (void *cls, | |||
737 | } | 728 | } |
738 | 729 | ||
739 | 730 | ||
740 | /** | ||
741 | * Callback for set operation results. Called for each element | ||
742 | * in the result set. | ||
743 | * | ||
744 | * @param cls closure | ||
745 | * @param element a result element, only valid if status is GNUNET_SET_STATUS_OK | ||
746 | * @param status see enum GNUNET_SET_Status | ||
747 | */ | ||
748 | static void | ||
749 | set_result_cb_loop (void *cls, | ||
750 | const struct GNUNET_SET_Element *element, | ||
751 | enum GNUNET_SET_Status status) | ||
752 | { | ||
753 | /* Nothing to do here. | ||
754 | This is the callback for looped local set operations, everything is | ||
755 | handled by the first callback */ | ||
756 | |||
757 | struct TaskEntry *task = cls; | ||
758 | struct ConsensusSession *session = task->step->session; | ||
759 | |||
760 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
761 | "P%u: skipping looped set result for {%s}, status %u\n", | ||
762 | session->local_peer_idx, | ||
763 | debug_str_task_key (&task->key), | ||
764 | status); | ||
765 | } | ||
766 | |||
767 | |||
768 | static struct SetEntry * | 731 | static struct SetEntry * |
769 | lookup_set (struct ConsensusSession *session, struct SetKey *key) | 732 | lookup_set (struct ConsensusSession *session, struct SetKey *key) |
770 | { | 733 | { |
@@ -863,10 +826,6 @@ rfn_vote (struct ReferendumEntry *rfn, | |||
863 | 826 | ||
864 | GNUNET_assert (voting_peer < num_peers); | 827 | GNUNET_assert (voting_peer < num_peers); |
865 | 828 | ||
866 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
867 | "voting for element of size %u\n", | ||
868 | element->size); | ||
869 | |||
870 | rfn->peer_commited[voting_peer] = GNUNET_YES; | 829 | rfn->peer_commited[voting_peer] = GNUNET_YES; |
871 | 830 | ||
872 | GNUNET_SET_element_hash (element, &hash); | 831 | GNUNET_SET_element_hash (element, &hash); |
@@ -884,9 +843,6 @@ rfn_vote (struct ReferendumEntry *rfn, | |||
884 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); | 843 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); |
885 | } | 844 | } |
886 | 845 | ||
887 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
888 | "rfn vote element %p\n", | ||
889 | ri->element); | ||
890 | ri->votes[voting_peer] = vote; | 846 | ri->votes[voting_peer] = vote; |
891 | } | 847 | } |
892 | 848 | ||
@@ -1371,29 +1327,17 @@ diff_compose (struct DiffEntry *diff_1, | |||
1371 | iter = GNUNET_CONTAINER_multihashmap_iterator_create (diff_1->changes); | 1327 | iter = GNUNET_CONTAINER_multihashmap_iterator_create (diff_1->changes); |
1372 | while (GNUNET_YES == GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, (const void **) &di)) | 1328 | while (GNUNET_YES == GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, (const void **) &di)) |
1373 | { | 1329 | { |
1374 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1375 | "iterating first diff\n"); | ||
1376 | diff_insert (diff_new, di->weight, di->element); | 1330 | diff_insert (diff_new, di->weight, di->element); |
1377 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1378 | "insert done\n"); | ||
1379 | } | 1331 | } |
1380 | GNUNET_CONTAINER_multihashmap_iterator_destroy (iter); | 1332 | GNUNET_CONTAINER_multihashmap_iterator_destroy (iter); |
1381 | 1333 | ||
1382 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1383 | "iterating first diff done\n"); | ||
1384 | |||
1385 | iter = GNUNET_CONTAINER_multihashmap_iterator_create (diff_2->changes); | 1334 | iter = GNUNET_CONTAINER_multihashmap_iterator_create (diff_2->changes); |
1386 | while (GNUNET_YES == GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, (const void **) &di)) | 1335 | while (GNUNET_YES == GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, (const void **) &di)) |
1387 | { | 1336 | { |
1388 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1389 | "iterating second diff\n"); | ||
1390 | diff_insert (diff_new, di->weight, di->element); | 1337 | diff_insert (diff_new, di->weight, di->element); |
1391 | } | 1338 | } |
1392 | GNUNET_CONTAINER_multihashmap_iterator_destroy (iter); | 1339 | GNUNET_CONTAINER_multihashmap_iterator_destroy (iter); |
1393 | 1340 | ||
1394 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1395 | "iterating second diff done\n"); | ||
1396 | |||
1397 | return diff_new; | 1341 | return diff_new; |
1398 | } | 1342 | } |
1399 | 1343 | ||
@@ -1527,6 +1471,13 @@ task_start_reconcile (struct TaskEntry *task) | |||
1527 | } | 1471 | } |
1528 | } | 1472 | } |
1529 | 1473 | ||
1474 | if ( (task->key.peer1 == session->local_peer_idx) && (task->key.peer2 == session->local_peer_idx) ) | ||
1475 | { | ||
1476 | /* XXX: mark the corresponding rfn as commited if necessary */ | ||
1477 | finish_task (task); | ||
1478 | return; | ||
1479 | } | ||
1480 | |||
1530 | if (task->key.peer1 == session->local_peer_idx) | 1481 | if (task->key.peer1 == session->local_peer_idx) |
1531 | { | 1482 | { |
1532 | struct GNUNET_CONSENSUS_RoundContextMessage rcm = { 0 }; | 1483 | struct GNUNET_CONSENSUS_RoundContextMessage rcm = { 0 }; |
@@ -1598,6 +1549,11 @@ rfn_majority (uint16_t num_peers, | |||
1598 | unsigned int tv; | 1549 | unsigned int tv; |
1599 | unsigned int i; | 1550 | unsigned int i; |
1600 | 1551 | ||
1552 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1553 | "Computing rfn majority for element %s of rfn {%s}\n", | ||
1554 | debug_str_element (ri->element), | ||
1555 | debug_str_rfn_key (&rfn->key)); | ||
1556 | |||
1601 | for (i = 0; i < num_peers; i++) | 1557 | for (i = 0; i < num_peers; i++) |
1602 | { | 1558 | { |
1603 | if (GNUNET_NO == rfn->peer_commited[i]) | 1559 | if (GNUNET_NO == rfn->peer_commited[i]) |
@@ -2057,10 +2013,10 @@ run_ready_steps (struct ConsensusSession *session) | |||
2057 | GNUNET_assert (0 == step->finished_tasks); | 2013 | GNUNET_assert (0 == step->finished_tasks); |
2058 | 2014 | ||
2059 | #ifdef GNUNET_EXTRA_LOGGING | 2015 | #ifdef GNUNET_EXTRA_LOGGING |
2060 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Running step `%s' of round %d:%d with %d tasks and %d subordinates\n", | 2016 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Running step `%s' of round %d with %d tasks and %d subordinates\n", |
2061 | session->local_peer_idx, | 2017 | session->local_peer_idx, |
2062 | step->debug_name, | 2018 | step->debug_name, |
2063 | step->start_round, step->num_rounds, step->tasks_len, step->subordinates_len); | 2019 | step->round, step->tasks_len, step->subordinates_len); |
2064 | #endif | 2020 | #endif |
2065 | 2021 | ||
2066 | step->is_running = GNUNET_YES; | 2022 | step->is_running = GNUNET_YES; |
@@ -2239,7 +2195,6 @@ set_listen_cb (void *cls, | |||
2239 | struct TaskKey tk; | 2195 | struct TaskKey tk; |
2240 | struct TaskEntry *task; | 2196 | struct TaskEntry *task; |
2241 | struct GNUNET_CONSENSUS_RoundContextMessage *cm; | 2197 | struct GNUNET_CONSENSUS_RoundContextMessage *cm; |
2242 | GNUNET_SET_ResultIterator my_result_cb; | ||
2243 | 2198 | ||
2244 | if (NULL == context_msg) | 2199 | if (NULL == context_msg) |
2245 | { | 2200 | { |
@@ -2293,15 +2248,13 @@ set_listen_cb (void *cls, | |||
2293 | return; | 2248 | return; |
2294 | } | 2249 | } |
2295 | 2250 | ||
2296 | if (task->key.peer1 == task->key.peer2) | 2251 | GNUNET_assert (! ((task->key.peer1 == session->local_peer_idx) && |
2297 | my_result_cb = set_result_cb_loop; | 2252 | (task->key.peer2 == session->local_peer_idx))); |
2298 | else | ||
2299 | my_result_cb = set_result_cb; | ||
2300 | 2253 | ||
2301 | task->cls.setop.op = GNUNET_SET_accept (request, | 2254 | task->cls.setop.op = GNUNET_SET_accept (request, |
2302 | GNUNET_SET_RESULT_SYMMETRIC, | 2255 | GNUNET_SET_RESULT_SYMMETRIC, |
2303 | my_result_cb, | 2256 | set_result_cb, |
2304 | task); | 2257 | task); |
2305 | 2258 | ||
2306 | /* If the task hasn't been started yet, | 2259 | /* If the task hasn't been started yet, |
2307 | we wait for that until we commit. */ | 2260 | we wait for that until we commit. */ |
@@ -2413,7 +2366,7 @@ step_depend_on (struct Step *step, struct Step *dep) | |||
2413 | GNUNET_assert (NULL != step); | 2366 | GNUNET_assert (NULL != step); |
2414 | GNUNET_assert (NULL != dep); | 2367 | GNUNET_assert (NULL != dep); |
2415 | // XXX: make rounds work | 2368 | // XXX: make rounds work |
2416 | //GNUNET_assert (dep->start_round <= step->start_round); | 2369 | GNUNET_assert (dep->round <= step->round); |
2417 | 2370 | ||
2418 | #ifdef GNUNET_EXTRA_LOGGING | 2371 | #ifdef GNUNET_EXTRA_LOGGING |
2419 | /* Make sure we have complete debugging information. | 2372 | /* Make sure we have complete debugging information. |
@@ -2445,13 +2398,12 @@ step_depend_on (struct Step *step, struct Step *dep) | |||
2445 | 2398 | ||
2446 | 2399 | ||
2447 | static struct Step * | 2400 | static struct Step * |
2448 | create_step (struct ConsensusSession *session, int start_round, int num_rounds) | 2401 | create_step (struct ConsensusSession *session, int round) |
2449 | { | 2402 | { |
2450 | struct Step *step; | 2403 | struct Step *step; |
2451 | step = GNUNET_new (struct Step); | 2404 | step = GNUNET_new (struct Step); |
2452 | step->session = session; | 2405 | step->session = session; |
2453 | step->start_round = start_round; | 2406 | step->round = round; |
2454 | step->num_rounds = num_rounds; | ||
2455 | GNUNET_CONTAINER_DLL_insert_tail (session->steps_head, | 2407 | GNUNET_CONTAINER_DLL_insert_tail (session->steps_head, |
2456 | session->steps_tail, | 2408 | session->steps_tail, |
2457 | step); | 2409 | step); |
@@ -2488,11 +2440,11 @@ construct_task_graph_gradecast (struct ConsensusSession *session, | |||
2488 | 2440 | ||
2489 | unsigned int k; | 2441 | unsigned int k; |
2490 | 2442 | ||
2491 | round = step_before->start_round + step_before->num_rounds; | 2443 | round = step_before->round + 1; |
2492 | 2444 | ||
2493 | /* gcast step 1: leader disseminates */ | 2445 | /* gcast step 1: leader disseminates */ |
2494 | 2446 | ||
2495 | step = create_step (session, round, 1); | 2447 | step = create_step (session, round); |
2496 | 2448 | ||
2497 | #ifdef GNUNET_EXTRA_LOGGING | 2449 | #ifdef GNUNET_EXTRA_LOGGING |
2498 | GNUNET_asprintf (&step->debug_name, "disseminate leader %u rep %u", lead, rep); | 2450 | GNUNET_asprintf (&step->debug_name, "disseminate leader %u rep %u", lead, rep); |
@@ -2555,7 +2507,8 @@ construct_task_graph_gradecast (struct ConsensusSession *session, | |||
2555 | 2507 | ||
2556 | /* gcast phase 2: echo */ | 2508 | /* gcast phase 2: echo */ |
2557 | prev_step = step; | 2509 | prev_step = step; |
2558 | step = create_step (session, round, 1); | 2510 | round += 1; |
2511 | step = create_step (session, round); | ||
2559 | #ifdef GNUNET_EXTRA_LOGGING | 2512 | #ifdef GNUNET_EXTRA_LOGGING |
2560 | GNUNET_asprintf (&step->debug_name, "echo leader %u rep %u", lead, rep); | 2513 | GNUNET_asprintf (&step->debug_name, "echo leader %u rep %u", lead, rep); |
2561 | #endif | 2514 | #endif |
@@ -2578,7 +2531,8 @@ construct_task_graph_gradecast (struct ConsensusSession *session, | |||
2578 | } | 2531 | } |
2579 | 2532 | ||
2580 | prev_step = step; | 2533 | prev_step = step; |
2581 | step = create_step (session, round, 1); | 2534 | /* Same round, since step only has local tasks */ |
2535 | step = create_step (session, round); | ||
2582 | #ifdef GNUNET_EXTRA_LOGGING | 2536 | #ifdef GNUNET_EXTRA_LOGGING |
2583 | GNUNET_asprintf (&step->debug_name, "echo grade leader %u rep %u", lead, rep); | 2537 | GNUNET_asprintf (&step->debug_name, "echo grade leader %u rep %u", lead, rep); |
2584 | #endif | 2538 | #endif |
@@ -2597,7 +2551,8 @@ construct_task_graph_gradecast (struct ConsensusSession *session, | |||
2597 | put_task (session->taskmap, &task); | 2551 | put_task (session->taskmap, &task); |
2598 | 2552 | ||
2599 | prev_step = step; | 2553 | prev_step = step; |
2600 | step = create_step (session, round, 1); | 2554 | round += 1; |
2555 | step = create_step (session, round); | ||
2601 | #ifdef GNUNET_EXTRA_LOGGING | 2556 | #ifdef GNUNET_EXTRA_LOGGING |
2602 | GNUNET_asprintf (&step->debug_name, "confirm leader %u rep %u", lead, rep); | 2557 | GNUNET_asprintf (&step->debug_name, "confirm leader %u rep %u", lead, rep); |
2603 | #endif | 2558 | #endif |
@@ -2621,7 +2576,8 @@ construct_task_graph_gradecast (struct ConsensusSession *session, | |||
2621 | } | 2576 | } |
2622 | 2577 | ||
2623 | prev_step = step; | 2578 | prev_step = step; |
2624 | step = create_step (session, round, 1); | 2579 | /* Same round, since step only has local tasks */ |
2580 | step = create_step (session, round); | ||
2625 | #ifdef GNUNET_EXTRA_LOGGING | 2581 | #ifdef GNUNET_EXTRA_LOGGING |
2626 | GNUNET_asprintf (&step->debug_name, "confirm grade leader %u rep %u", lead, rep); | 2582 | GNUNET_asprintf (&step->debug_name, "confirm grade leader %u rep %u", lead, rep); |
2627 | #endif | 2583 | #endif |
@@ -2641,7 +2597,8 @@ construct_task_graph_gradecast (struct ConsensusSession *session, | |||
2641 | 2597 | ||
2642 | 2598 | ||
2643 | prev_step = step; | 2599 | prev_step = step; |
2644 | step = create_step (session, round, 1); | 2600 | /* Same round, since step only has local tasks */ |
2601 | step = create_step (session, round); | ||
2645 | #ifdef GNUNET_EXTRA_LOGGING | 2602 | #ifdef GNUNET_EXTRA_LOGGING |
2646 | GNUNET_asprintf (&step->debug_name, "gc apply, lead %u rep %u", lead, rep); | 2603 | GNUNET_asprintf (&step->debug_name, "gc apply, lead %u rep %u", lead, rep); |
2647 | #endif | 2604 | #endif |
@@ -2695,7 +2652,7 @@ construct_task_graph (struct ConsensusSession *session) | |||
2695 | 2652 | ||
2696 | /* all-to-all step */ | 2653 | /* all-to-all step */ |
2697 | 2654 | ||
2698 | step = create_step (session, round, 1); | 2655 | step = create_step (session, round); |
2699 | 2656 | ||
2700 | #ifdef GNUNET_EXTRA_LOGGING | 2657 | #ifdef GNUNET_EXTRA_LOGGING |
2701 | step->debug_name = GNUNET_strdup ("all to all"); | 2658 | step->debug_name = GNUNET_strdup ("all to all"); |
@@ -2718,11 +2675,11 @@ construct_task_graph (struct ConsensusSession *session) | |||
2718 | put_task (session->taskmap, &task); | 2675 | put_task (session->taskmap, &task); |
2719 | } | 2676 | } |
2720 | 2677 | ||
2721 | round++; | ||
2722 | |||
2723 | prev_step = step; | 2678 | prev_step = step; |
2724 | step = NULL; | 2679 | step = NULL; |
2725 | 2680 | ||
2681 | round += 1; | ||
2682 | |||
2726 | /* Byzantine union */ | 2683 | /* Byzantine union */ |
2727 | 2684 | ||
2728 | /* sequential repetitions of the gradecasts */ | 2685 | /* sequential repetitions of the gradecasts */ |
@@ -2731,14 +2688,17 @@ construct_task_graph (struct ConsensusSession *session) | |||
2731 | struct Step *step_rep_start; | 2688 | struct Step *step_rep_start; |
2732 | struct Step *step_rep_end; | 2689 | struct Step *step_rep_end; |
2733 | 2690 | ||
2734 | step_rep_start = create_step (session, round, 1); | 2691 | /* Every repetition is in a separate round. */ |
2692 | step_rep_start = create_step (session, round); | ||
2735 | #ifdef GNUNET_EXTRA_LOGGING | 2693 | #ifdef GNUNET_EXTRA_LOGGING |
2736 | GNUNET_asprintf (&step_rep_start->debug_name, "gradecast start rep %u", i); | 2694 | GNUNET_asprintf (&step_rep_start->debug_name, "gradecast start rep %u", i); |
2737 | #endif | 2695 | #endif |
2738 | 2696 | ||
2739 | step_depend_on (step_rep_start, prev_step); | 2697 | step_depend_on (step_rep_start, prev_step); |
2740 | 2698 | ||
2741 | step_rep_end = create_step (session, round, 1); | 2699 | /* gradecast has three rounds */ |
2700 | round += 3; | ||
2701 | step_rep_end = create_step (session, round); | ||
2742 | #ifdef GNUNET_EXTRA_LOGGING | 2702 | #ifdef GNUNET_EXTRA_LOGGING |
2743 | GNUNET_asprintf (&step_rep_end->debug_name, "gradecast end rep %u", i); | 2703 | GNUNET_asprintf (&step_rep_end->debug_name, "gradecast end rep %u", i); |
2744 | #endif | 2704 | #endif |
@@ -2764,7 +2724,8 @@ construct_task_graph (struct ConsensusSession *session) | |||
2764 | 2724 | ||
2765 | /* There is no next gradecast round, thus the final | 2725 | /* There is no next gradecast round, thus the final |
2766 | start step is the overall end step of the gradecasts */ | 2726 | start step is the overall end step of the gradecasts */ |
2767 | step = create_step (session, round, 1); | 2727 | round += 1; |
2728 | step = create_step (session, round); | ||
2768 | #ifdef GNUNET_EXTRA_LOGGING | 2729 | #ifdef GNUNET_EXTRA_LOGGING |
2769 | GNUNET_asprintf (&step->debug_name, "finish"); | 2730 | GNUNET_asprintf (&step->debug_name, "finish"); |
2770 | #endif | 2731 | #endif |