diff --git a/docs/federation-implementation-notes.md b/docs/federation-implementation-notes.md index bbf4444..94f9356 100644 --- a/docs/federation-implementation-notes.md +++ b/docs/federation-implementation-notes.md @@ -264,6 +264,28 @@ Core resolve returns only artifact references. The middle layer is responsible for fetching remote bytes by reference over its transport and caching them separately from the authoritative local store. +## Ownership and lifecycle + +- `amduat_fed_registry_decode` allocates policy hash buffers; free with + `amduat_fed_registry_value_free`. +- `amduat_fed_registry_encode` returns allocated bytes; free with + `amduat_octets_free`. +- `amduat_fed_view_build` allocates view records and denies; free with + `amduat_fed_view_free`. +- `amduat_fed_replay_domain` allocates replay records; free with + `amduat_fed_replay_view_free`. + +## Middle-layer fetch example (informative) + +```c +err = amduat_fed_resolve(view, local_store, ref, &artifact); +if (err == AMDUAT_FED_RESOLVE_FOUND_REMOTE_NO_BYTES) { + if (fetch_remote_bytes(ref, &artifact) && cache_store_put(artifact)) { + err = amduat_fed_resolve(view, local_store, ref, &artifact); + } +} +``` + ## Tests (minimal) 1) Replay ordering determinism across two domains with interleaved logseq. diff --git a/include/amduat/fed/replay.h b/include/amduat/fed/replay.h index 18414e6..315feb1 100644 --- a/include/amduat/fed/replay.h +++ b/include/amduat/fed/replay.h @@ -47,6 +47,14 @@ typedef struct { /* Caller frees record ids with amduat_fed_replay_view_free. */ bool amduat_fed_record_validate(const amduat_fed_record_t *record); +bool amduat_fed_replay_build(const amduat_fed_record_t *records, + size_t count, + uint32_t domain_id, + uint64_t snapshot_id, + uint64_t log_prefix, + amduat_fed_replay_view_t *out_view); + +/* Backwards-compatible alias for amduat_fed_replay_build. */ bool amduat_fed_replay_domain(const amduat_fed_record_t *records, size_t count, uint32_t domain_id, diff --git a/src/near_core/fed/replay.c b/src/near_core/fed/replay.c index 3829bb1..1231e27 100644 --- a/src/near_core/fed/replay.c +++ b/src/near_core/fed/replay.c @@ -153,12 +153,12 @@ bool amduat_fed_record_validate(const amduat_fed_record_t *record) { return true; } -bool amduat_fed_replay_domain(const amduat_fed_record_t *records, - size_t count, - uint32_t domain_id, - uint64_t snapshot_id, - uint64_t log_prefix, - amduat_fed_replay_view_t *out_view) { +bool amduat_fed_replay_build(const amduat_fed_record_t *records, + size_t count, + uint32_t domain_id, + uint64_t snapshot_id, + uint64_t log_prefix, + amduat_fed_replay_view_t *out_view) { amduat_fed_record_t *scratch; amduat_reference_t *tombstones; size_t tombstones_len; @@ -278,6 +278,20 @@ bool amduat_fed_replay_domain(const amduat_fed_record_t *records, return true; } +bool amduat_fed_replay_domain(const amduat_fed_record_t *records, + size_t count, + uint32_t domain_id, + uint64_t snapshot_id, + uint64_t log_prefix, + amduat_fed_replay_view_t *out_view) { + return amduat_fed_replay_build(records, + count, + domain_id, + snapshot_id, + log_prefix, + out_view); +} + void amduat_fed_replay_view_free(amduat_fed_replay_view_t *view) { size_t i; diff --git a/src/near_core/fed/view.c b/src/near_core/fed/view.c index 0098bff..a4d9c3a 100644 --- a/src/near_core/fed/view.c +++ b/src/near_core/fed/view.c @@ -241,12 +241,12 @@ amduat_fed_view_error_t amduat_fed_view_build( domain_count++; } - ok = amduat_fed_replay_domain(domain_records, - domain_count, - bound.domain_id, - bound.snapshot_id, - bound.log_prefix, - &domain_view); + ok = amduat_fed_replay_build(domain_records, + domain_count, + bound.domain_id, + bound.snapshot_id, + bound.log_prefix, + &domain_view); for (j = 0; j < domain_count; ++j) { amduat_fed_record_free(&domain_records[j]); } diff --git a/tests/fed/test_fed_replay.c b/tests/fed/test_fed_replay.c index 1504558..45e46dc 100644 --- a/tests/fed/test_fed_replay.c +++ b/tests/fed/test_fed_replay.c @@ -43,7 +43,7 @@ static int test_ordering(void) { 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)) { + if (!amduat_fed_replay_build(records, 3, 1, 1, 10, &view)) { fprintf(stderr, "replay failed\n"); return 1; } @@ -74,7 +74,7 @@ static int test_tombstone_scope(void) { 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)) { + if (!amduat_fed_replay_build(records, 3, 1, 1, 10, &view)) { fprintf(stderr, "replay domain 1 failed\n"); return 1; } @@ -85,7 +85,7 @@ static int test_tombstone_scope(void) { } amduat_fed_replay_view_free(&view); - if (!amduat_fed_replay_domain(records, 3, 2, 1, 10, &view)) { + if (!amduat_fed_replay_build(records, 3, 2, 1, 10, &view)) { fprintf(stderr, "replay domain 2 failed\n"); return 1; } @@ -107,7 +107,7 @@ static int test_bounds(void) { 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)) { + if (!amduat_fed_replay_build(records, 2, 3, 1, 4, &view)) { fprintf(stderr, "replay bounds failed\n"); return 1; } @@ -137,11 +137,11 @@ static int test_multi_domain_ordering(void) { records[3] = make_record(2, 2, 1, 10, AMDUAT_FED_REC_ARTIFACT, make_ref(1, d2, sizeof(d2))); - if (!amduat_fed_replay_domain(records, 4, 1, 1, 10, &view_a)) { + if (!amduat_fed_replay_build(records, 4, 1, 1, 10, &view_a)) { fprintf(stderr, "replay domain 1 failed\n"); return 1; } - if (!amduat_fed_replay_domain(records, 4, 2, 1, 10, &view_b)) { + if (!amduat_fed_replay_build(records, 4, 2, 1, 10, &view_b)) { fprintf(stderr, "replay domain 2 failed\n"); amduat_fed_replay_view_free(&view_a); return 1;