19 uint32_t nat_score = (4 - metrics->nat_tier) * 1000;
23 uint32_t bw_score = metrics->upload_kbps / 10;
28 uint32_t rtt_score = (metrics->rtt_ns < 500 * NS_PER_MS) ? (500 - (metrics->rtt_ns / NS_PER_MS)) : 0;
31 uint32_t probe_score = metrics->stun_probe_success_pct;
34 uint32_t total = nat_score + bw_score + rtt_score + probe_score;
68 int *out_best_index,
int *out_backup_index) {
69 if (!metrics || !out_best_index || !out_backup_index || num_metrics < 1) {
70 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid election parameters");
74 uint32_t *scores = SAFE_MALLOC(
sizeof(uint32_t) * num_metrics, uint32_t *);
76 for (
int i = 0; i < num_metrics; i++) {
81 find_best_two(scores, num_metrics, out_best_index, out_backup_index);
88 const uint8_t announced_host_id[16],
const uint8_t announced_backup_id[16],
90 if (!metrics || !announced_host_id || !announced_backup_id || !out_valid) {
91 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid verification parameters");
95 int host_idx = -1, backup_idx = -1;
97 for (
int i = 0; i < num_metrics; i++) {
98 if (memcmp(metrics[i].
participant_id, announced_host_id, 16) == 0) {
101 if (memcmp(metrics[i].
participant_id, announced_backup_id, 16) == 0) {
107 if (host_idx < 0 || backup_idx < 0) {
113 int computed_host, computed_backup;
116 if (err != ASCIICHAT_OK) {
121 *out_valid = (host_idx == computed_host && backup_idx == computed_backup);
asciichat_error_t consensus_election_verify(const participant_metrics_t *metrics, int num_metrics, const uint8_t announced_host_id[16], const uint8_t announced_backup_id[16], bool *out_valid)