16#include <ascii-chat/session/consensus.h>
17#include <ascii-chat/network/consensus/metrics.h>
18#include <ascii-chat/common.h>
19#include <ascii-chat/log/logging.h>
20#include <ascii-chat/util/endian.h>
21#include <ascii-chat/util/time.h>
22#include <ascii-chat/network/packet.h>
32static asciichat_error_t consensus_send_via_discovery(
void *context,
const uint8_t next_participant_id[16],
33 const uint8_t *packet,
size_t packet_size) {
37 if (!context || !next_participant_id || !packet) {
38 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters");
46 log_debug(
"Consensus would send %zu bytes to participant %.*s via ACDS", packet_size, 16, next_participant_id);
57static asciichat_error_t consensus_on_election_result(
void *context,
const uint8_t host_id[16],
58 const char host_address[64], uint16_t host_port,
59 const uint8_t backup_id[16],
const char backup_address[64],
60 uint16_t backup_port) {
65 if (!context || !host_id || !backup_id) {
66 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters");
74 log_info(
"Consensus election result: host=%.*s backup=%.*s (addr=%s:%u)", 16, host_id, 16, backup_id, host_address,
86static asciichat_error_t consensus_get_metrics(
void *context,
const uint8_t my_id[16],
87 participant_metrics_t *out_metrics) {
89 if (!context || !my_id || !out_metrics) {
90 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters");
101 memcpy(out_metrics->participant_id, my_id, 16);
102 out_metrics->nat_tier = 1;
103 out_metrics->upload_kbps = htonl(50000);
104 out_metrics->rtt_ns = htonl(25000000);
105 out_metrics->stun_probe_success_pct = 95;
106 SAFE_STRNCPY(out_metrics->public_address,
"203.0.113.42",
sizeof(out_metrics->public_address));
107 out_metrics->public_port = htons(54321);
108 out_metrics->connection_type = 0;
109 out_metrics->measurement_time_ns = htonll(
time_get_ns());
110 out_metrics->measurement_window_ns = htonll(5000000000ULL);
112 log_debug(
"Consensus measured metrics: NAT tier=%d, upload=%u Kbps, RTT=%u ns", out_metrics->nat_tier,
113 ntohl(out_metrics->upload_kbps), ntohl(out_metrics->rtt_ns));
130 if (!context || !out_callbacks) {
131 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters: context=%p, out_callbacks=%p", context, out_callbacks);
135 out_callbacks->send_packet = consensus_send_via_discovery;
136 out_callbacks->on_election = consensus_on_election_result;
137 out_callbacks->get_metrics = consensus_get_metrics;
138 out_callbacks->election = NULL;
139 out_callbacks->context = context;
160 const uint8_t participant_ids[64][16],
int num_participants,
164 if (!my_id || !participant_ids || !discovery_context || !out_consensus) {
165 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters");
168 if (num_participants < 1 || num_participants > 64) {
169 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid participant count: %d", num_participants);
174 bool is_leader =
false;
177 session_consensus_callbacks_t callbacks = {0};
179 if (err != ASCIICHAT_OK) {
198 return current_timeout_ms;
205 uint64_t time_to_next_ms = time_ns_to_ms(time_to_next_ns);
208 if (time_to_next_ms == 0) {
212 if (time_to_next_ms < current_timeout_ms) {
213 return (uint32_t)time_to_next_ms;
216 return current_timeout_ms;
asciichat_error_t session_consensus_create(const uint8_t my_id[16], bool is_leader, const uint8_t participant_ids[64][16], int num_participants, const session_consensus_callbacks_t *callbacks, session_consensus_t **out_consensus)
uint64_t session_consensus_time_until_next_round(session_consensus_t *consensus)
asciichat_error_t consensus_get_discovery_callbacks(void *context, session_consensus_callbacks_t *out_callbacks)
Get callbacks configured for discovery mode integration.
uint32_t consensus_suggest_timeout_ms(session_consensus_t *consensus, uint32_t current_timeout_ms)
Calculate how long to wait until next consensus processing.
asciichat_error_t consensus_create_for_discovery(const uint8_t session_id[16], const uint8_t my_id[16], const uint8_t participant_ids[64][16], int num_participants, void *discovery_context, session_consensus_t **out_consensus)
Example: Create session consensus for discovery mode.
Session consensus handle - wraps all consensus modules.
uint64_t time_get_ns(void)