diff options
-rw-r--r-- | src/consensus/consensus_protocol.h | 13 | ||||
-rw-r--r-- | src/consensus/gnunet-service-consensus.c | 119 |
2 files changed, 107 insertions, 25 deletions
diff --git a/src/consensus/consensus_protocol.h b/src/consensus/consensus_protocol.h index 43b6a9632..fa445dc2e 100644 --- a/src/consensus/consensus_protocol.h +++ b/src/consensus/consensus_protocol.h | |||
@@ -90,8 +90,8 @@ struct GNUNET_CONSENSUS_RoundContextMessage | |||
90 | 90 | ||
91 | 91 | ||
92 | enum { | 92 | enum { |
93 | CONSENSUS_MARKER_CONTESTED, | 93 | CONSENSUS_MARKER_CONTESTED = 1, |
94 | CONSENSUS_MARKER_SIZE, | 94 | CONSENSUS_MARKER_SIZE = 2, |
95 | }; | 95 | }; |
96 | 96 | ||
97 | 97 | ||
@@ -115,6 +115,15 @@ struct ConsensusElement | |||
115 | }; | 115 | }; |
116 | 116 | ||
117 | 117 | ||
118 | struct ConsensusSizeElement | ||
119 | { | ||
120 | struct ConsensusElement ce GNUNET_PACKED; | ||
121 | |||
122 | uint64_t size GNUNET_PACKED; | ||
123 | uint8_t sender_index; | ||
124 | }; | ||
125 | |||
126 | |||
118 | GNUNET_NETWORK_STRUCT_END | 127 | GNUNET_NETWORK_STRUCT_END |
119 | 128 | ||
120 | #endif | 129 | #endif |
diff --git a/src/consensus/gnunet-service-consensus.c b/src/consensus/gnunet-service-consensus.c index bfb14996a..8b02031fd 100644 --- a/src/consensus/gnunet-service-consensus.c +++ b/src/consensus/gnunet-service-consensus.c | |||
@@ -492,6 +492,13 @@ struct ConsensusSession | |||
492 | * Our set size from the first round. | 492 | * Our set size from the first round. |
493 | */ | 493 | */ |
494 | uint64_t first_size; | 494 | uint64_t first_size; |
495 | |||
496 | uint64_t *first_sizes_received; | ||
497 | |||
498 | /** | ||
499 | * Bounded Eppstein lower bound. | ||
500 | */ | ||
501 | uint64_t lower_bound; | ||
495 | }; | 502 | }; |
496 | 503 | ||
497 | /** | 504 | /** |
@@ -675,7 +682,10 @@ send_to_client_iter (void *cls, | |||
675 | GNUNET_assert (GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT == element->element_type); | 682 | GNUNET_assert (GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT == element->element_type); |
676 | ce = element->data; | 683 | ce = element->data; |
677 | 684 | ||
678 | GNUNET_assert (0 == ce->marker); | 685 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "marker is %u\n", (unsigned) ce->marker); |
686 | |||
687 | if (0 != ce->marker) | ||
688 | return GNUNET_YES; | ||
679 | 689 | ||
680 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 690 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
681 | "P%d: sending element %s to client\n", | 691 | "P%d: sending element %s to client\n", |
@@ -855,7 +865,7 @@ rfn_vote (struct ReferendumEntry *rfn, | |||
855 | } | 865 | } |
856 | 866 | ||
857 | 867 | ||
858 | uint16_t | 868 | static uint16_t |
859 | task_other_peer (struct TaskEntry *task) | 869 | task_other_peer (struct TaskEntry *task) |
860 | { | 870 | { |
861 | uint16_t me = task->step->session->local_peer_idx; | 871 | uint16_t me = task->step->session->local_peer_idx; |
@@ -865,6 +875,20 @@ task_other_peer (struct TaskEntry *task) | |||
865 | } | 875 | } |
866 | 876 | ||
867 | 877 | ||
878 | static int | ||
879 | cmp_uint64_t (const void *pa, const void *pb) | ||
880 | { | ||
881 | uint64_t a = *(uint64_t *) pa; | ||
882 | uint64_t b = *(uint64_t *) pb; | ||
883 | |||
884 | if (a == b) | ||
885 | return 0; | ||
886 | if (a < b) | ||
887 | return -1; | ||
888 | return 1; | ||
889 | } | ||
890 | |||
891 | |||
868 | /** | 892 | /** |
869 | * Callback for set operation results. Called for each element | 893 | * Callback for set operation results. Called for each element |
870 | * in the result set. | 894 | * in the result set. |
@@ -946,8 +970,11 @@ set_result_cb (void *cls, | |||
946 | return; | 970 | return; |
947 | } | 971 | } |
948 | 972 | ||
949 | if ( (GNUNET_SET_STATUS_ADD_LOCAL == status) || (GNUNET_SET_STATUS_ADD_REMOTE == status) ) | 973 | if ( (NULL != consensus_element) && (0 != consensus_element->marker) ) |
950 | { | 974 | { |
975 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
976 | "P%u: got some marker\n", | ||
977 | session->local_peer_idx); | ||
951 | if ( (GNUNET_YES == setop->transceive_contested) && | 978 | if ( (GNUNET_YES == setop->transceive_contested) && |
952 | (CONSENSUS_MARKER_CONTESTED == consensus_element->marker) ) | 979 | (CONSENSUS_MARKER_CONTESTED == consensus_element->marker) ) |
953 | { | 980 | { |
@@ -955,6 +982,35 @@ set_result_cb (void *cls, | |||
955 | rfn_contest (output_rfn, task_other_peer (task)); | 982 | rfn_contest (output_rfn, task_other_peer (task)); |
956 | return; | 983 | return; |
957 | } | 984 | } |
985 | |||
986 | if (CONSENSUS_MARKER_SIZE == consensus_element->marker) | ||
987 | { | ||
988 | |||
989 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
990 | "P%u: got size marker\n", | ||
991 | session->local_peer_idx); | ||
992 | |||
993 | |||
994 | struct ConsensusSizeElement *cse = (void *) consensus_element; | ||
995 | |||
996 | if (cse->sender_index == other_idx) | ||
997 | { | ||
998 | if (NULL == session->first_sizes_received) | ||
999 | session->first_sizes_received = GNUNET_new_array (session->num_peers, uint64_t); | ||
1000 | session->first_sizes_received[other_idx] = GNUNET_ntohll (cse->size); | ||
1001 | |||
1002 | uint64_t *copy = GNUNET_memdup (session->first_sizes_received, sizeof (uint64_t) * session->num_peers); | ||
1003 | qsort (copy, session->num_peers, sizeof (uint64_t), cmp_uint64_t); | ||
1004 | session->lower_bound = copy[session->num_peers / 3 + 1]; | ||
1005 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1006 | "P%u: lower bound %llu\n", | ||
1007 | session->local_peer_idx, | ||
1008 | (long long) session->lower_bound); | ||
1009 | } | ||
1010 | return; | ||
1011 | } | ||
1012 | |||
1013 | return; | ||
958 | } | 1014 | } |
959 | 1015 | ||
960 | switch (status) | 1016 | switch (status) |
@@ -1249,6 +1305,31 @@ commit_set (struct ConsensusSession *session, | |||
1249 | set = lookup_set (session, &setop->input_set); | 1305 | set = lookup_set (session, &setop->input_set); |
1250 | GNUNET_assert (NULL != set); | 1306 | GNUNET_assert (NULL != set); |
1251 | 1307 | ||
1308 | if ( (GNUNET_YES == setop->transceive_contested) && (GNUNET_YES == set->is_contested) ) | ||
1309 | { | ||
1310 | struct GNUNET_SET_Element element; | ||
1311 | struct ConsensusElement ce = { 0 }; | ||
1312 | ce.marker = CONSENSUS_MARKER_CONTESTED; | ||
1313 | element.data = &ce; | ||
1314 | element.size = sizeof (struct ConsensusElement); | ||
1315 | element.element_type = GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT; | ||
1316 | GNUNET_SET_add_element (set->h, &element, NULL, NULL); | ||
1317 | } | ||
1318 | |||
1319 | if (PHASE_KIND_ALL_TO_ALL_2 == task->key.kind) | ||
1320 | { | ||
1321 | struct GNUNET_SET_Element element; | ||
1322 | struct ConsensusSizeElement cse = { 0 }; | ||
1323 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "inserting size marker\n"); | ||
1324 | cse.ce.marker = CONSENSUS_MARKER_SIZE; | ||
1325 | cse.size = GNUNET_htonll (session->first_size); | ||
1326 | cse.sender_index = session->local_peer_idx; | ||
1327 | element.data = &cse; | ||
1328 | element.size = sizeof (struct ConsensusSizeElement); | ||
1329 | element.element_type = GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT; | ||
1330 | GNUNET_SET_add_element (set->h, &element, NULL, NULL); | ||
1331 | } | ||
1332 | |||
1252 | #ifdef EVIL | 1333 | #ifdef EVIL |
1253 | { | 1334 | { |
1254 | unsigned int i; | 1335 | unsigned int i; |
@@ -1338,24 +1419,6 @@ commit_set (struct ConsensusSession *session, | |||
1338 | } | 1419 | } |
1339 | } | 1420 | } |
1340 | #else | 1421 | #else |
1341 | |||
1342 | //if (PHASE_KIND_ALL_TO_ALL_2 == task->key.kind) | ||
1343 | //{ | ||
1344 | // struct GNUNET_SET_Element element; | ||
1345 | // struct ConsensusElement ce = { 0 }; | ||
1346 | //} | ||
1347 | |||
1348 | |||
1349 | if ( (GNUNET_YES == setop->transceive_contested) && (GNUNET_YES == set->is_contested) ) | ||
1350 | { | ||
1351 | struct GNUNET_SET_Element element; | ||
1352 | struct ConsensusElement ce = { 0 }; | ||
1353 | ce.marker = CONSENSUS_MARKER_CONTESTED; | ||
1354 | element.data = &ce; | ||
1355 | element.size = sizeof (struct ConsensusElement); | ||
1356 | element.element_type = GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT; | ||
1357 | GNUNET_SET_add_element (set->h, &element, NULL, NULL); | ||
1358 | } | ||
1359 | if (GNUNET_NO == session->peers_blacklisted[task_other_peer (task)]) | 1422 | if (GNUNET_NO == session->peers_blacklisted[task_other_peer (task)]) |
1360 | { | 1423 | { |
1361 | GNUNET_SET_commit (setop->op, set->h); | 1424 | GNUNET_SET_commit (setop->op, set->h); |
@@ -2039,13 +2102,18 @@ task_start_reconcile (struct TaskEntry *task) | |||
2039 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: initiating set op with P%u, our set is %s\n", | 2102 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: initiating set op with P%u, our set is %s\n", |
2040 | session->local_peer_idx, task->key.peer2, debug_str_set_key (&setop->input_set)); | 2103 | session->local_peer_idx, task->key.peer2, debug_str_set_key (&setop->input_set)); |
2041 | 2104 | ||
2105 | struct GNUNET_SET_Option opts[] = { | ||
2106 | {GNUNET_SET_OPTION_BYZANTINE, { .num = session->lower_bound } }, | ||
2107 | {0}, | ||
2108 | }; | ||
2109 | |||
2042 | // XXX: maybe this should be done while | 2110 | // XXX: maybe this should be done while |
2043 | // setting up tasks alreays? | 2111 | // setting up tasks alreays? |
2044 | setop->op = GNUNET_SET_prepare (&session->peers[task->key.peer2], | 2112 | setop->op = GNUNET_SET_prepare (&session->peers[task->key.peer2], |
2045 | &session->global_id, | 2113 | &session->global_id, |
2046 | &rcm.header, | 2114 | &rcm.header, |
2047 | GNUNET_SET_RESULT_SYMMETRIC, | 2115 | GNUNET_SET_RESULT_SYMMETRIC, |
2048 | (struct GNUNET_SET_Option[]) { 0 }, | 2116 | opts, |
2049 | set_result_cb, | 2117 | set_result_cb, |
2050 | task); | 2118 | task); |
2051 | 2119 | ||
@@ -2470,9 +2538,14 @@ set_listen_cb (void *cls, | |||
2470 | GNUNET_assert (! ((task->key.peer1 == session->local_peer_idx) && | 2538 | GNUNET_assert (! ((task->key.peer1 == session->local_peer_idx) && |
2471 | (task->key.peer2 == session->local_peer_idx))); | 2539 | (task->key.peer2 == session->local_peer_idx))); |
2472 | 2540 | ||
2541 | struct GNUNET_SET_Option opts[] = { | ||
2542 | {GNUNET_SET_OPTION_BYZANTINE, { .num = session->lower_bound } }, | ||
2543 | {0}, | ||
2544 | }; | ||
2545 | |||
2473 | task->cls.setop.op = GNUNET_SET_accept (request, | 2546 | task->cls.setop.op = GNUNET_SET_accept (request, |
2474 | GNUNET_SET_RESULT_SYMMETRIC, | 2547 | GNUNET_SET_RESULT_SYMMETRIC, |
2475 | (struct GNUNET_SET_Option[]) { 0 }, | 2548 | opts, |
2476 | set_result_cb, | 2549 | set_result_cb, |
2477 | task); | 2550 | task); |
2478 | 2551 | ||