diff --git a/brandt.c b/brandt.c index 1c42d41..b6d3466 100644 --- a/brandt.c +++ b/brandt.c @@ -78,8 +78,8 @@ BRANDT_bidder_start (struct BRANDT_Auction *auction, } weprintf("broadcasting msg_init %p from bidder %d", buf, i); - if (0 == auction->bcast (auction->closure, buf, buflen)) - gcry_mpi_set_bit (auction->round_progress, auction->i); + auction->bcast (auction->closure, buf, buflen); + gcry_mpi_set_bit (auction->round_progress, auction->i); free (buf); } @@ -293,88 +293,89 @@ BRANDT_destroy (struct BRANDT_Auction *auction) } +static void +report_outcome (struct BRANDT_Auction *ad, + enum auction_type atype, + enum outcome_type outcome) +{ + struct BRANDT_Result *res; + uint16_t reslen = 0; + + if (!handler_res[atype][outcome] || + !(res = handler_res[atype][outcome] (ad, &reslen))) + ad->result (ad->closure, NULL, 0); + else + ad->result (ad->closure, res, reslen); +} + + static void advance_round (struct BRANDT_Auction *ad, enum auction_type atype, enum outcome_type outcome) { - struct BRANDT_Result *res; - uint16_t reslen = 0; unsigned char *buf; size_t buflen; - /* if we did not got the current round message from all participants, don't - * advance to the next round yet. Early return, since we have to wait for - * the other participants messages. In the msg_decrypt round as a bidder we - * only need the one message from the seller. */ - for (uint16_t i = 0; i < ad->n; i++) - if (!gcry_mpi_test_bit (ad->round_progress, i) && - (ad->seller_mode || msg_decrypt != ad->cur_round)) - return; - - /* Do not advance to the next round if we are the seller and got all - * msg_decrypt messages from the bidders. We need to broadcast our combined - * msg_decrypt message back to the sellers first */ - if (!ad->seller_mode || msg_decrypt != ad->cur_round) + if (!ad->seller_mode && msg_decrypt == ad->cur_round) { - /* clear old round progress and advance to next one */ - gcry_mpi_clear_highbit (ad->round_progress, 0); - ad->cur_round++; - - /* prepare next round. */ - if (handler_prep[atype][outcome][ad->cur_round]) - handler_prep[atype][outcome][ad->cur_round] (ad); - - /** \todo: setup round timeout trigger */ - if (ad->seller_mode) - { - } + /* we are a bidder and successfully parsed the msg_decrypt from the + * seller => we can determine the auction result */ + report_outcome (ad, atype, outcome); + return; } - /* send next message if we are not done yet */ - if ((!ad->seller_mode && msg_last > ad->cur_round) || - (ad->seller_mode && msg_decrypt == ad->cur_round && - gcry_mpi_test_bit (ad->round_progress, 0))) + /* only continue if the round is complete */ + for (uint16_t i = 0; i < ad->n; i++) + if (!gcry_mpi_test_bit (ad->round_progress, i)) + return; + + if (ad->seller_mode && msg_decrypt == ad->cur_round) { + /* all bidders msg_decrypt received, broadcast combined msg_decrypt */ if (!handler_out[atype][outcome][ad->cur_round] || !(buf = handler_out[atype][outcome][ad->cur_round](ad, &buflen))) { - weprintf ("failed to create message %d buffer", ad->cur_round); + weprintf ("failed to create msg %d buffer as seller", + ad->cur_round); return; } + ad->bcast (ad->closure, buf, buflen); - /* msg_decrypt unicast to seller or broadcast from seller. - * All other messages are broadcasted */ - if (msg_decrypt == ad->cur_round && !ad->seller_mode) - { - if (0 == ad->ucast (ad->closure, buf, buflen)) - gcry_mpi_set_bit (ad->round_progress, ad->i); - } - else - { - if (!ad->seller_mode && 0 == ad->bcast (ad->closure, buf, buflen)) - gcry_mpi_set_bit (ad->round_progress, ad->i); - } + /* now we are done as seller and can determine the outcome */ + report_outcome (ad, atype, outcome); + return; } - if (msg_last == ad->cur_round || - (msg_decrypt == ad->cur_round && ad->seller_mode && - gcry_mpi_test_bit (ad->round_progress, 0))) + /* round complete, advance to next one */ + gcry_mpi_clear_highbit (ad->round_progress, 0); + ad->cur_round++; + + /* prepare next round. */ + if (handler_prep[atype][outcome][ad->cur_round]) + handler_prep[atype][outcome][ad->cur_round] (ad); + + if (ad->seller_mode) { - /* done with all rounds, determine outcome here */ - if (!handler_res[atype][outcome] || - !(res = handler_res[atype][outcome] (ad, &reslen))) - { - weprintf ("failed to determine result"); - /** \todo: call result with null pointer here? */ - return; - } - - ad->result (ad->closure, res, reslen); - /* seller still needs to broadcast the decryption to all bidders */ - if (!ad->seller_mode) - return; + /** \todo: setup round timeout trigger */ + /* seller does not send regular messages */ + return; } + + /* create next message buffer */ + if (!handler_out[atype][outcome][ad->cur_round] || + !(buf = handler_out[atype][outcome][ad->cur_round](ad, &buflen))) + { + weprintf ("failed to create msg %d buffer as bidder", ad->cur_round); + return; + } + + /* msg_decrypt unicast to seller. All other messages are broadcasted */ + if (msg_decrypt == ad->cur_round) + ad->ucast (ad->closure, buf, buflen); + else + ad->bcast (ad->closure, buf, buflen); + gcry_mpi_set_bit (ad->round_progress, ad->i); } diff --git a/test_brandt.c b/test_brandt.c index 0c7e4e2..b3d9b1e 100644 --- a/test_brandt.c +++ b/test_brandt.c @@ -133,6 +133,17 @@ cb_result (void *auction_closure, struct BRANDT_Result results[], uint16_t results_len) { + uint16_t *s = (uint16_t *)auction_closure; + + if (0 == results_len) + weprintf ("result determined by agent %d: none", *s); + + for (uint16_t i = 0; i < results_len; i++) + weprintf ("result determined by agent %d: bidder %d got status %d with price %d", + *s, + results[i].bidder, + results[i].status, + results[i].price); }