#include "online.h" #include "hosts.h" #include "msg.h" #include #include #include #include #include extern struct host *conns[1024]; extern int num_conns; extern uint32_t curr_view; extern uint32_t view_next_seq_num; extern uint32_t state_machine_state; extern struct msg_log *mlog; extern struct msg_log *out_responses; extern uint32_t glob_replica_index; uint32_t small_digest(struct msg *request) { char data[20] = {0}; char *out = malloc(32 * sizeof(char)); for (int i = 0; i < 32; i++) { out[i] = 0; } data[0] = request->req_message; ((uint32_t *)data)[1] = request->option_value; ((uint64_t *)data)[1] = request->timestamp; ((uint32_t *)data)[4] = request->client_index; SHA256((unsigned char *)data, 20, (unsigned char *)out); uint32_t x = ((uint32_t *)out)[0]; free(out); return x; } void handle_primary_recv_request(struct msg *request, struct sigpriv *privkey) { struct msg *pre_prepare = init_msg(); uint32_t d = small_digest(request); pre_prepare->msg_type = 1; pre_prepare->seq = view_next_seq_num; pre_prepare->view = curr_view; pre_prepare->digest = d; pre_prepare->signature = sign_msg(pre_prepare, privkey); broadcast(conns, num_conns, parse_msg_as_packet(pre_prepare)); broadcast(conns, num_conns, parse_msg_as_packet(request)); struct msg_log *out_msg = malloc(sizeof(struct msg_log)); struct msg *o = malloc(sizeof(struct msg)); memcpy(o, request, sizeof(struct msg)); out_msg->m = o; out_msg->next = mlog; mlog = out_msg; struct msg_log *out2 = malloc(sizeof(struct msg_log)); out2->m = pre_prepare; out2->next = mlog; mlog = out2; } void handle_send_prepare(struct msg *preprepare, struct sigpriv *privkey) { struct msg *prepare = init_msg(); prepare->msg_type = 2; prepare->seq = preprepare->seq; prepare->view = preprepare->view; prepare->server_index = glob_replica_index; prepare->digest = preprepare->digest; prepare->signature = sign_msg(prepare, privkey); broadcast(conns, num_conns, parse_msg_as_packet(prepare)); struct msg_log *out2 = malloc(sizeof(struct msg_log)); out2->m = prepare; out2->next = mlog; mlog = out2; } void handle_send_commit(struct msg *msg, struct msg *prepare, struct sigpriv *privkey) { struct msg *commit = init_msg(); commit->msg_type = 3; commit->seq = prepare->seq; commit->view = prepare->view; commit->server_index = glob_replica_index; commit->digest = small_digest(msg); commit->signature = sign_msg(commit, privkey); broadcast(conns, num_conns, parse_msg_as_packet(commit)); struct msg_log *out2 = malloc(sizeof(struct msg_log)); out2->m = commit; out2->next = mlog; mlog = out2; } void handle_operation(struct msg *msg, struct sigpriv *privkey) { struct msg *m = init_msg(); m->msg_type = 5; if (msg->req_message == 0) { state_machine_state += msg->option_value; m->option_value = 1; m->timestamp = msg->timestamp; m->signature = sign_msg(m, privkey); for (int i = 0; i < num_conns; i++) { if ((uint32_t)conns[i]->replica_index == msg->client_index) { send_to(conns[i], parse_msg_as_packet(m)); } } if (msg->client_index == glob_replica_index) { struct msg_log *out_msg = malloc(sizeof(struct msg_log)); out_msg->m = m; out_msg->next = out_responses; out_responses = out_msg; } } else if (msg->req_message == 1) { state_machine_state -= msg->option_value; m->option_value = 1; m->timestamp = msg->timestamp; m->signature = sign_msg(m, privkey); for (int i = 0; i < num_conns; i++) { if ((uint32_t)conns[i]->replica_index == msg->client_index) { send_to(conns[i], parse_msg_as_packet(m)); } } if (msg->client_index == glob_replica_index) { struct msg_log *out_msg = malloc(sizeof(struct msg_log)); out_msg->m = m; out_msg->next = out_responses; out_responses = out_msg; } } else if (msg->req_message == 2) { state_machine_state *= msg->option_value; m->option_value = 1; m->timestamp = msg->timestamp; m->signature = sign_msg(m, privkey); for (int i = 0; i < num_conns; i++) { if ((uint32_t)conns[i]->replica_index == msg->client_index) { send_to(conns[i], parse_msg_as_packet(m)); } } if (msg->client_index == glob_replica_index) { struct msg_log *out_msg = malloc(sizeof(struct msg_log)); out_msg->m = m; out_msg->next = out_responses; out_responses = out_msg; } } else if (msg->req_message == 3) { m->option_value = state_machine_state; m->timestamp = msg->timestamp; m->signature = sign_msg(m, privkey); for (int i = 0; i < num_conns; i++) { if ((uint32_t)conns[i]->replica_index == msg->client_index) { send_to(conns[i], parse_msg_as_packet(m)); } } if (msg->client_index == glob_replica_index) { struct msg_log *out_msg = malloc(sizeof(struct msg_log)); out_msg->m = m; out_msg->next = out_responses; out_responses = out_msg; } } clean_msg(m); } bool prepared(struct msg_log *mlog, int f, struct msg *request, uint32_t view, uint32_t seq) { bool is_request_in = false; bool is_preprepare_in = false; uint8_t num_prepares = 0; uint32_t digest_req = small_digest(request); struct msg_log *m; for (m = mlog; m != NULL; m = m->next) { if (m->m->msg_type == 0 && request->msg_type == 0 && m->m->req_message == request->req_message && m->m->option_value == request->option_value && m->m->timestamp == request->timestamp && m->m->client_index == request->client_index) { is_request_in = true; } if (m->m->msg_type == 1 && m->m->view == view && m->m->seq == seq && m->m->digest == digest_req) { is_preprepare_in = true; } if (m->m->msg_type == 2 && m->m->view == view && m->m->seq == seq && m->m->digest == digest_req) { num_prepares += 1; } } return (is_request_in && is_preprepare_in && (num_prepares >= 2 * f)); } bool committed_local(struct msg_log *mlog, int f, struct msg *request, uint32_t view, uint32_t seq) { bool is_prepared = prepared(mlog, f, request, view, seq); uint32_t cor_seq = request->seq; request->seq = 0; uint32_t dg = small_digest(request); request->seq = cor_seq; struct msg_log *m; uint8_t commits = 0; for (m = mlog; m != NULL; m = m->next) { if (m->m->msg_type == 3 && m->m->view == view && m->m->digest == dg && m->m->seq == request->seq) { struct msg_log *k; uint32_t factor = 1; for (k = mlog; k != m; k = k->next) { if (k->m->msg_type == 3 && k->m->view == view && k->m->digest == dg && k->m->seq == request->seq && k->m->server_index == m->m->server_index) { factor = 0; } } commits += 1 * factor; } } // printf("committed? %d %d %d \n", is_prepared, commits, 2 * f + 1); return (is_prepared && (commits >= 2 * f + 1)); } uint32_t sign_msg(struct msg *_message, struct sigpriv *_key) { return 0; } bool validate_signature(struct msg *_message, struct sigkey *_privkey) { return true; } void *todo_key() { return NULL; }