2026-01-24 18:11:44 +01:00
|
|
|
#include "amduatd_fed_until.h"
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
static void amduatd_fed_until_report_clear_cursor(
|
|
|
|
|
amduatd_fed_until_report_t *report) {
|
|
|
|
|
if (report == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (report->cursor_ref_set) {
|
|
|
|
|
amduat_reference_free(&report->cursor_ref);
|
|
|
|
|
report->cursor_ref_set = false;
|
|
|
|
|
}
|
|
|
|
|
report->cursor_has_logseq = false;
|
|
|
|
|
report->cursor_logseq = 0u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void amduatd_fed_until_report_set_cursor(
|
|
|
|
|
amduatd_fed_until_report_t *report,
|
|
|
|
|
bool has_logseq,
|
|
|
|
|
uint64_t logseq,
|
|
|
|
|
bool has_ref,
|
|
|
|
|
amduat_reference_t ref) {
|
|
|
|
|
if (report == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
amduatd_fed_until_report_clear_cursor(report);
|
|
|
|
|
if (has_logseq) {
|
|
|
|
|
report->cursor_has_logseq = true;
|
|
|
|
|
report->cursor_logseq = logseq;
|
|
|
|
|
}
|
|
|
|
|
if (has_ref) {
|
|
|
|
|
if (amduat_reference_clone(ref, &report->cursor_ref)) {
|
|
|
|
|
report->cursor_ref_set = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void amduatd_fed_until_report_error(amduatd_fed_until_report_t *report,
|
|
|
|
|
const char *msg,
|
|
|
|
|
int remote_status) {
|
|
|
|
|
if (report == NULL || msg == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
memset(report->error, 0, sizeof(report->error));
|
|
|
|
|
strncpy(report->error, msg, sizeof(report->error) - 1u);
|
|
|
|
|
report->remote_status = remote_status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void amduatd_fed_until_report_init(amduatd_fed_until_report_t *report) {
|
|
|
|
|
if (report == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
memset(report, 0, sizeof(*report));
|
|
|
|
|
report->cursor_ref = amduat_reference(0u, amduat_octets(NULL, 0u));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void amduatd_fed_until_report_free(amduatd_fed_until_report_t *report) {
|
|
|
|
|
if (report == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (report->cursor_ref_set) {
|
|
|
|
|
amduat_reference_free(&report->cursor_ref);
|
|
|
|
|
}
|
|
|
|
|
memset(report, 0, sizeof(*report));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
amduatd_fed_pull_apply_status_t amduatd_fed_pull_until(
|
|
|
|
|
amduat_asl_store_t *store,
|
|
|
|
|
amduat_asl_pointer_store_t *pointer_store,
|
|
|
|
|
const amduatd_space_t *effective_space,
|
|
|
|
|
const char *peer_key,
|
2026-01-24 19:50:13 +01:00
|
|
|
const char *remote_space_id,
|
2026-01-24 18:11:44 +01:00
|
|
|
uint64_t limit,
|
|
|
|
|
uint64_t max_rounds,
|
|
|
|
|
const amduatd_fed_cfg_t *fed_cfg,
|
|
|
|
|
const amduatd_fed_pull_transport_t *transport,
|
|
|
|
|
amduatd_fed_until_report_t *out_report) {
|
|
|
|
|
amduatd_fed_pull_apply_status_t status = AMDUATD_FED_PULL_APPLY_OK;
|
|
|
|
|
amduatd_fed_pull_apply_report_t round_report;
|
|
|
|
|
|
|
|
|
|
if (out_report == NULL) {
|
|
|
|
|
return AMDUATD_FED_PULL_APPLY_ERR_INVALID;
|
|
|
|
|
}
|
|
|
|
|
amduatd_fed_until_report_init(out_report);
|
|
|
|
|
out_report->peer_key = peer_key;
|
|
|
|
|
out_report->effective_space = effective_space;
|
|
|
|
|
out_report->limit = limit;
|
|
|
|
|
out_report->max_rounds = max_rounds;
|
|
|
|
|
|
|
|
|
|
if (store == NULL || pointer_store == NULL || peer_key == NULL ||
|
|
|
|
|
fed_cfg == NULL || transport == NULL || max_rounds == 0u) {
|
|
|
|
|
amduatd_fed_until_report_error(out_report, "invalid inputs", 0);
|
|
|
|
|
return AMDUATD_FED_PULL_APPLY_ERR_INVALID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint64_t round = 0u; round < max_rounds; ++round) {
|
|
|
|
|
amduatd_fed_pull_apply_report_init(&round_report);
|
|
|
|
|
status = amduatd_fed_pull_apply(store,
|
|
|
|
|
pointer_store,
|
|
|
|
|
effective_space,
|
|
|
|
|
peer_key,
|
2026-01-24 19:50:13 +01:00
|
|
|
remote_space_id,
|
2026-01-24 18:11:44 +01:00
|
|
|
limit,
|
|
|
|
|
fed_cfg,
|
|
|
|
|
transport,
|
|
|
|
|
&round_report);
|
|
|
|
|
out_report->rounds_executed++;
|
|
|
|
|
|
|
|
|
|
if (status != AMDUATD_FED_PULL_APPLY_OK) {
|
|
|
|
|
amduatd_fed_until_report_error(out_report,
|
|
|
|
|
round_report.error[0] != '\0'
|
|
|
|
|
? round_report.error
|
|
|
|
|
: "error",
|
|
|
|
|
round_report.remote_status);
|
|
|
|
|
amduatd_fed_pull_apply_report_free(&round_report);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out_report->total_records += round_report.applied_record_count;
|
|
|
|
|
out_report->total_artifacts += round_report.applied_artifact_count;
|
|
|
|
|
if (round_report.cursor_advanced) {
|
|
|
|
|
amduatd_fed_until_report_set_cursor(
|
|
|
|
|
out_report,
|
|
|
|
|
round_report.cursor_after_has_logseq,
|
|
|
|
|
round_report.cursor_after_logseq,
|
|
|
|
|
round_report.cursor_after_ref_set,
|
|
|
|
|
round_report.cursor_after_ref);
|
|
|
|
|
} else if (round_report.cursor_present) {
|
|
|
|
|
amduatd_fed_until_report_set_cursor(
|
|
|
|
|
out_report,
|
|
|
|
|
round_report.cursor_has_logseq,
|
|
|
|
|
round_report.cursor_logseq,
|
|
|
|
|
round_report.cursor_ref_set,
|
|
|
|
|
round_report.cursor_ref);
|
|
|
|
|
} else {
|
|
|
|
|
amduatd_fed_until_report_clear_cursor(out_report);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (round_report.plan_record_count == 0u) {
|
|
|
|
|
out_report->caught_up = true;
|
|
|
|
|
amduatd_fed_pull_apply_report_free(&round_report);
|
|
|
|
|
return AMDUATD_FED_PULL_APPLY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
amduatd_fed_pull_apply_report_free(&round_report);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out_report->caught_up = false;
|
|
|
|
|
return AMDUATD_FED_PULL_APPLY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
amduatd_fed_push_apply_status_t amduatd_fed_push_until(
|
|
|
|
|
amduat_asl_store_t *store,
|
|
|
|
|
amduat_asl_pointer_store_t *pointer_store,
|
|
|
|
|
const amduatd_space_t *effective_space,
|
|
|
|
|
const char *peer_key,
|
2026-01-24 19:50:13 +01:00
|
|
|
const char *remote_space_id,
|
2026-01-24 18:11:44 +01:00
|
|
|
uint64_t limit,
|
|
|
|
|
uint64_t max_rounds,
|
|
|
|
|
const char *root_path,
|
|
|
|
|
const amduatd_fed_cfg_t *fed_cfg,
|
|
|
|
|
const amduatd_fed_push_transport_t *transport,
|
|
|
|
|
amduatd_fed_until_report_t *out_report) {
|
|
|
|
|
amduatd_fed_push_apply_status_t status = AMDUATD_FED_PUSH_APPLY_OK;
|
|
|
|
|
amduatd_fed_push_apply_report_t round_report;
|
|
|
|
|
|
|
|
|
|
if (out_report == NULL) {
|
|
|
|
|
return AMDUATD_FED_PUSH_APPLY_ERR_INVALID;
|
|
|
|
|
}
|
|
|
|
|
amduatd_fed_until_report_init(out_report);
|
|
|
|
|
out_report->peer_key = peer_key;
|
|
|
|
|
out_report->effective_space = effective_space;
|
|
|
|
|
out_report->limit = limit;
|
|
|
|
|
out_report->max_rounds = max_rounds;
|
|
|
|
|
|
|
|
|
|
if (store == NULL || pointer_store == NULL || peer_key == NULL ||
|
|
|
|
|
root_path == NULL || fed_cfg == NULL || transport == NULL ||
|
|
|
|
|
max_rounds == 0u) {
|
|
|
|
|
amduatd_fed_until_report_error(out_report, "invalid inputs", 0);
|
|
|
|
|
return AMDUATD_FED_PUSH_APPLY_ERR_INVALID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint64_t round = 0u; round < max_rounds; ++round) {
|
|
|
|
|
amduatd_fed_push_apply_report_init(&round_report);
|
|
|
|
|
status = amduatd_fed_push_apply(store,
|
|
|
|
|
pointer_store,
|
|
|
|
|
effective_space,
|
|
|
|
|
peer_key,
|
2026-01-24 19:50:13 +01:00
|
|
|
remote_space_id,
|
2026-01-24 18:11:44 +01:00
|
|
|
limit,
|
|
|
|
|
root_path,
|
|
|
|
|
fed_cfg,
|
|
|
|
|
transport,
|
|
|
|
|
&round_report);
|
|
|
|
|
out_report->rounds_executed++;
|
|
|
|
|
|
|
|
|
|
if (status != AMDUATD_FED_PUSH_APPLY_OK) {
|
|
|
|
|
amduatd_fed_until_report_error(out_report,
|
|
|
|
|
round_report.error[0] != '\0'
|
|
|
|
|
? round_report.error
|
|
|
|
|
: "error",
|
|
|
|
|
round_report.remote_status);
|
|
|
|
|
amduatd_fed_push_apply_report_free(&round_report);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out_report->total_records += round_report.sent_record_count;
|
|
|
|
|
out_report->total_artifacts += round_report.sent_artifact_count;
|
|
|
|
|
if (round_report.cursor_advanced) {
|
|
|
|
|
amduatd_fed_until_report_set_cursor(
|
|
|
|
|
out_report,
|
|
|
|
|
round_report.cursor_after_has_logseq,
|
|
|
|
|
round_report.cursor_after_logseq,
|
|
|
|
|
round_report.cursor_after_ref_set,
|
|
|
|
|
round_report.cursor_after_ref);
|
|
|
|
|
} else if (round_report.cursor_present) {
|
|
|
|
|
amduatd_fed_until_report_set_cursor(
|
|
|
|
|
out_report,
|
|
|
|
|
round_report.cursor_has_logseq,
|
|
|
|
|
round_report.cursor_logseq,
|
|
|
|
|
round_report.cursor_ref_set,
|
|
|
|
|
round_report.cursor_ref);
|
|
|
|
|
} else {
|
|
|
|
|
amduatd_fed_until_report_clear_cursor(out_report);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (round_report.plan_record_count == 0u) {
|
|
|
|
|
out_report->caught_up = true;
|
|
|
|
|
amduatd_fed_push_apply_report_free(&round_report);
|
|
|
|
|
return AMDUATD_FED_PUSH_APPLY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
amduatd_fed_push_apply_report_free(&round_report);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out_report->caught_up = false;
|
|
|
|
|
return AMDUATD_FED_PUSH_APPLY_OK;
|
|
|
|
|
}
|