tiny-chain/bft/generals.c

100 lines
2.5 KiB
C

// This time writing in C because c++ gives me agita
#include "stdio.h"
#include "stdlib.h"
#define HOLD 0
#define ATTACK 1
#define RETREAT 2
#define g_idx(idx) (idx * sizeof(struct General))
struct General {
int id;
int plan;
int check;
// two neighbors max because why tf not
struct General* neighbor_a;
struct General* neighbor_b;
};
void general_init(struct General* g, int id) {
g->id = id;
g->plan = rand() % 3;
g->neighbor_a = NULL;
g->neighbor_b = NULL;
g->check = 0;
}
void general_connect_neighbors(struct General* a, struct General* b) {
// aa
if(a->neighbor_a == NULL && b->neighbor_a == NULL) {
a->neighbor_a = b;
b->neighbor_a = a;
}
// bb
else if(a->neighbor_b == NULL && b->neighbor_b == NULL) {
a->neighbor_b = b;
b->neighbor_b = a;
}
// ab
else if(a->neighbor_a == NULL && b->neighbor_b == NULL) {
a->neighbor_a = b;
b->neighbor_b = a;
}
// ba
else {
a->neighbor_b = b;
b->neighbor_a = a;
}
}
void generals_assign_neighbors(int id_g, struct General[] generals, int pool_size) {
// make sure we don't pick ourselves by acdident
int a = rand() % pool_size;
int b = rand() % pool_size;
// make sure we don't pick ourselves ever
while(a == id_g) {a = rand() % pool_size;}
while(b == id_g && b == a) {b = rand() % pool_size;}
general_connect_neighbors(generals[id_g], &generals[a], &generals[b]);
}
void generals_vote_rr(struct General* generals, int pool_size) {
// Each general must now tell the other generals what their plan actually is
// We keep track of this by a value flag in the generals struct `check`
for(int i = 0; i < pool_size; i++) {
}
}
void general_reveal_info(const struct General* g) {
char* plans[3] = {"Hold", "Attack", "Retreat"};
printf("ID: %d\tPlan%s\tNeighbors: %d &%d\n",
g->id, plans[g->plan],g->neighbor_a->id, g->neighbor_b->id);
}
int main(void) {
const int general_count = 5;
struct General generals[general_count];
// connect the commander to two of the generals
for(int i = 0; i < general_count; i++) {
general_init(&generals[i], i);
// pick two random generals that aren't us to befriend
generals_assign_neighbors(i, generals, general_count);
}
// Show off each generals starting state
for(int i = 0; i<general_count;i++) {
general_reveal_info(&generals[i]);
}
// For `n` Byzantine generals and `m` Albanian generals
// We demonstrate the "three-general" solution
// This solution implies that 3 Byzantine generals can handle 1 traitor
// First the byzantine commander simulates
return 0;
}