aboutsummaryrefslogtreecommitdiff
path: root/test_brandt.c
diff options
context:
space:
mode:
Diffstat (limited to 'test_brandt.c')
-rw-r--r--test_brandt.c70
1 files changed, 59 insertions, 11 deletions
diff --git a/test_brandt.c b/test_brandt.c
index ee53a0d..8a27748 100644
--- a/test_brandt.c
+++ b/test_brandt.c
@@ -28,6 +28,7 @@
#include "crypto.h"
#include "util.h"
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
struct msg {
uint16_t sender;
@@ -55,26 +56,73 @@ static struct testcase tcase;
static struct BRANDT_Result *
expected_outcome (uint16_t i)
{
+ struct BRANDT_Result *ret = NULL;
int32_t highest_bidder = -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;
- for (uint16_t h = 0; h < tcase.n; h++)
+ if (0 == tcase.m)
{
- if (tcase.bids[h] > highest_bid)
+ for (uint16_t h = 0; h < tcase.n; h++)
+ if (tcase.bids[h] > highest_bid)
+ highest_bid = tcase.bids[highest_bidder = h];
+
+ if (!tcase.outcome_public && !(i == highest_bidder || i == tcase.n))
+ return NULL;
+
+ ret = GNUNET_new (struct BRANDT_Result);
+ ret->bidder = highest_bidder;
+ ret->price = highest_bid;
+ ret->status = BRANDT_bidder_won;
+ 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++)
{
- highest_bid = tcase.bids[h];
- highest_bidder = 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;
}
- if (!tcase.outcome_public && !(i == highest_bidder || i == tcase.n))
- return NULL;
+ /* 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);
- ret = GNUNET_new (struct BRANDT_Result);
- ret->bidder = highest_bidder;
- ret->price = highest_bid;
- ret->status = BRANDT_bidder_won;
+ /* 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;
}