make test_brandt ready for M+1st price auctions

This commit is contained in:
Markus Teich 2016-10-14 05:50:27 +02:00
parent e333dd0183
commit fc9fdd313b

View File

@ -28,6 +28,7 @@
#include "crypto.h" #include "crypto.h"
#include "util.h" #include "util.h"
#define MIN(A, B) ((A) < (B) ? (A) : (B))
struct msg { struct msg {
uint16_t sender; uint16_t sender;
@ -55,18 +56,20 @@ static struct testcase tcase;
static struct BRANDT_Result * static struct BRANDT_Result *
expected_outcome (uint16_t i) expected_outcome (uint16_t i)
{ {
struct BRANDT_Result *ret = NULL;
int32_t highest_bidder = -1; int32_t highest_bidder = -1;
int32_t highest_bid = -1; int32_t highest_bid = -1;
struct BRANDT_Result *ret; int32_t mpf_highest_bidder;
int32_t mpf_highest_bid;
int32_t prev_mpf_highest_bidder = -1;
uint16_t winners = MIN (tcase.m, tcase.n);
uint16_t cur_winner = 0;
if (0 == tcase.m)
{
for (uint16_t h = 0; h < tcase.n; h++) for (uint16_t h = 0; h < tcase.n; h++)
{
if (tcase.bids[h] > highest_bid) if (tcase.bids[h] > highest_bid)
{ highest_bid = tcase.bids[highest_bidder = h];
highest_bid = tcase.bids[h];
highest_bidder = h;
}
}
if (!tcase.outcome_public && !(i == highest_bidder || i == tcase.n)) if (!tcase.outcome_public && !(i == highest_bidder || i == tcase.n))
return NULL; return NULL;
@ -78,6 +81,51 @@ expected_outcome (uint16_t i)
return ret; return ret;
} }
/* find M+1st highest bidder to determine selling price */
for (uint16_t m = 0; m <= MIN (tcase.m, tcase.n - 1); m++)
{
for (uint16_t h = 0; h < tcase.n; h++)
{
mpf_highest_bidder = -1;
mpf_highest_bid = -1;
if (tcase.bids[h] > mpf_highest_bid &&
(-1 == prev_mpf_highest_bidder ||
tcase.bids[h] < tcase.bids[prev_mpf_highest_bidder] ||
h > prev_mpf_highest_bidder))
mpf_highest_bid = tcase.bids[mpf_highest_bidder = h];
}
prev_mpf_highest_bidder = mpf_highest_bidder;
}
/* for simplicity always locate the big block if we need to report at
* least one winner. with private outcome for losing bidders or winners
* only none or one element will be used respectively. */
if (tcase.outcome_public || i == tcase.n ||
tcase.bids[i] > mpf_highest_bid ||
(tcase.bids[i] == mpf_highest_bid && i < mpf_highest_bidder))
ret = GNUNET_new_array (winners, struct BRANDT_Result);
/* report winners */
for (uint16_t h = 0; h < tcase.n; h++)
{
if (((tcase.bids[h] == mpf_highest_bid && h < mpf_highest_bidder) ||
tcase.bids[h] > mpf_highest_bid) && /* h is a winner */
(tcase.outcome_public || i == h || i == tcase.n)) /* needs report */
{
if (cur_winner >= winners)
{
weprintf ("got too many winners");
_exit (1);
}
ret[cur_winner].bidder = h;
ret[cur_winner].price = mpf_highest_bid;
ret[cur_winner].status = BRANDT_bidder_won;
cur_winner++;
}
}
return ret;
}
static void static void
bidder_start (void *arg) bidder_start (void *arg)