diff --git a/brandt.c b/brandt.c index dab0ad2..ff106fb 100644 --- a/brandt.c +++ b/brandt.c @@ -67,6 +67,31 @@ BRANDT_bidder_start (struct BRANDT_Auction *auction, atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; outcome = auction->outcome_public ? outcome_public : outcome_private; + if (auction_mPlusFirstPrice == atype && n <= auction->m) + { /* fewer bidders than items to sell. every bidder won with lowest price */ + struct BRANDT_Result *res; + if (auction->outcome_public) + { + res = GNUNET_new_array (n, struct BRANDT_Result); + for (uint16_t h = 0; h < n; h++) + { + res[h].bidder = h; + res[h].price = 0; + res[h].status = BRANDT_bidder_won; + } + auction->result (auction->closure, res, n); + } + else + { + res = GNUNET_new (struct BRANDT_Result); + res->bidder = i; + res->price = 0; + res->status = BRANDT_bidder_won; + auction->result (auction->closure, res, 1); + } + return; + } + /* On M+1st price auctions we multiply the amount of prizes by the amount of * bidders and resctrict each bidder to his own distinct subset of the * prices. This is done for tie breaking. An additional proof is used in the @@ -104,12 +129,26 @@ seller_start (void *arg) ad->task = NULL; - if (0 == (ad->n = ad->start (ad->closure))) + ad->n = ad->start (ad->closure); + if (0 == ad->n) { weprintf ("no bidders registered for auction"); ad->result (ad->closure, NULL, 0); return; } + else if (ad->n <= ad->m) + { + struct BRANDT_Result *res = GNUNET_new_array (ad->n, struct BRANDT_Result); + + weprintf ("less bidders than needed, selling for lowest price"); + for (uint16_t i = 0; i < ad->n; i++) + { + res[i].bidder = i; + res[i].price = 0; + res[i].status = BRANDT_bidder_won; + } + ad->result (ad->closure, res, ad->n); + } atype = ad->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; outcome = ad->outcome_public ? outcome_public : outcome_private; diff --git a/test_brandt.c b/test_brandt.c index 1fb985c..46ec90d 100644 --- a/test_brandt.c +++ b/test_brandt.c @@ -84,6 +84,29 @@ expected_outcome (uint16_t i) return ret; } + /* fewer bidders than needed -> everyone wins with lowest price */ + if (tcase.n <= tcase.m) + { + if (tcase.outcome_public || i == tcase.n) + { + ret = GNUNET_new_array (tcase.n, struct BRANDT_Result); + for (uint16_t h = 0; h < tcase.n; h++) + { + ret[h].bidder = h; + ret[h].price = 0; + ret[h].status = BRANDT_bidder_won; + } + } + else + { + ret = GNUNET_new (struct BRANDT_Result); + ret->bidder = i; + ret->price = 0; + ret->status = BRANDT_bidder_won; + } + return ret; + } + /* find M+1st highest bidder to determine selling price */ for (uint16_t h = 0; h < tcase.n; h++) if (tcase.bids[h] > mpf_highest_bid) @@ -387,6 +410,9 @@ main (int argc, char *argv[]) test_auction (0, 2, NULL, 0, 1) || test_auction (0, 2, NULL, 1, 0) || test_auction (0, 2, NULL, 2, 0) || + test_auction (1, 2, (uint16_t[]) { 1 }, 1, 0) || + test_auction (1, 2, (uint16_t[]) { 0 }, 2, 0) || + test_auction (2, 2, (uint16_t[]) { 1, 0 }, 2, 0) || test_auction (2, 2, (uint16_t[]) { 1, 0 }, 1, 0) || test_auction (3, 2, (uint16_t[]) { 0, 0, 1 }, 2, 0) || test_auction (3, 2, (uint16_t[]) { 0, 1, 1 }, 0, 0) ||