#include "amduat/fed/replay.h" #include #include static amduat_reference_t make_ref(amduat_hash_id_t hash_id, const uint8_t *bytes, size_t len) { return amduat_reference(hash_id, amduat_octets(bytes, len)); } static amduat_fed_record_t make_record(uint32_t domain_id, uint64_t logseq, uint64_t snapshot_id, uint64_t log_prefix, amduat_fed_record_type_t type, amduat_reference_t ref) { amduat_fed_record_t record; memset(&record, 0, sizeof(record)); record.meta.domain_id = domain_id; record.meta.visibility = 1; record.meta.has_source = 0; record.id.type = type; record.id.ref = ref; record.location.domain_id = domain_id; record.location.ref = ref; record.logseq = logseq; record.snapshot_id = snapshot_id; record.log_prefix = log_prefix; return record; } static int test_ordering(void) { uint8_t d0[] = {0x00}; uint8_t d1[] = {0x01}; uint8_t d2[] = {0x02}; amduat_fed_record_t records[3]; amduat_fed_replay_view_t view; records[0] = make_record(1, 5, 1, 10, AMDUAT_FED_REC_ARTIFACT, make_ref(1, d1, sizeof(d1))); records[1] = make_record(1, 5, 1, 10, AMDUAT_FED_REC_ARTIFACT, make_ref(1, d0, sizeof(d0))); records[2] = make_record(1, 4, 1, 10, AMDUAT_FED_REC_ARTIFACT, make_ref(1, d2, sizeof(d2))); if (!amduat_fed_replay_domain(records, 3, 1, 1, 10, &view)) { fprintf(stderr, "replay failed\n"); return 1; } if (view.len != 3) { fprintf(stderr, "ordering length mismatch\n"); amduat_fed_replay_view_free(&view); return 1; } if (view.records[0].logseq != 4 || view.records[1].id.ref.digest.data[0] != 0x00 || view.records[2].id.ref.digest.data[0] != 0x01) { fprintf(stderr, "ordering mismatch\n"); amduat_fed_replay_view_free(&view); return 1; } amduat_fed_replay_view_free(&view); return 0; } static int test_tombstone_scope(void) { uint8_t key[] = {0xaa}; amduat_reference_t ref = make_ref(1, key, sizeof(key)); amduat_fed_record_t records[3]; amduat_fed_replay_view_t view; records[0] = make_record(1, 1, 1, 10, AMDUAT_FED_REC_ARTIFACT, ref); records[1] = make_record(1, 2, 1, 10, AMDUAT_FED_REC_TOMBSTONE, ref); records[2] = make_record(2, 1, 1, 10, AMDUAT_FED_REC_ARTIFACT, ref); if (!amduat_fed_replay_domain(records, 3, 1, 1, 10, &view)) { fprintf(stderr, "replay domain 1 failed\n"); return 1; } if (view.len != 0) { fprintf(stderr, "tombstone scope mismatch (domain 1)\n"); amduat_fed_replay_view_free(&view); return 1; } amduat_fed_replay_view_free(&view); if (!amduat_fed_replay_domain(records, 3, 2, 1, 10, &view)) { fprintf(stderr, "replay domain 2 failed\n"); return 1; } if (view.len != 1) { fprintf(stderr, "tombstone scope mismatch (domain 2)\n"); amduat_fed_replay_view_free(&view); return 1; } amduat_fed_replay_view_free(&view); return 0; } static int test_bounds(void) { uint8_t key[] = {0xbb}; amduat_reference_t ref = make_ref(1, key, sizeof(key)); amduat_fed_record_t records[2]; amduat_fed_replay_view_t view; records[0] = make_record(3, 1, 2, 10, AMDUAT_FED_REC_ARTIFACT, ref); records[1] = make_record(3, 5, 1, 4, AMDUAT_FED_REC_ARTIFACT, ref); if (!amduat_fed_replay_domain(records, 2, 3, 1, 4, &view)) { fprintf(stderr, "replay bounds failed\n"); return 1; } if (view.len != 0) { fprintf(stderr, "bounds mismatch\n"); amduat_fed_replay_view_free(&view); return 1; } amduat_fed_replay_view_free(&view); return 0; } int main(void) { if (test_ordering() != 0) { return 1; } if (test_tombstone_scope() != 0) { return 1; } if (test_bounds() != 0) { return 1; } return 0; }