Document FER/1 v1.1 TLVs and test helpers
This commit is contained in:
parent
b506cc6c7c
commit
4d2fb250cd
|
|
@ -174,3 +174,28 @@ Concrete rules:
|
||||||
References:
|
References:
|
||||||
- `tier1/srs.md`
|
- `tier1/srs.md`
|
||||||
- `tier1/enc-fer1-receipt-1.md`
|
- `tier1/enc-fer1-receipt-1.md`
|
||||||
|
|
||||||
|
## FER/1 v1.1 Encoding Notes (Implementation)
|
||||||
|
|
||||||
|
Decision:
|
||||||
|
- The v1.1 encoder appends a TLV extension block after the v1 base layout.
|
||||||
|
- Unknown or duplicate TLV tags are rejected during decode.
|
||||||
|
|
||||||
|
TLV tags (implementation):
|
||||||
|
- `0x0001` executor fingerprint reference (encoded reference bytes).
|
||||||
|
- `0x0002` run id (`U32` length + bytes).
|
||||||
|
- `0x0003` logs (`U32` count; per entry: `U32 kind`, encoded ref, `U32` sha256
|
||||||
|
length + bytes). Entries must be ordered by `(kind, ref)` byte order.
|
||||||
|
- `0x0004` limits (`U64` cpu_ms, `U64` wall_ms, `U64` max_rss_kib,
|
||||||
|
`U64` io_reads, `U64` io_writes).
|
||||||
|
- `0x0005` determinism (`U8` level, `U32` seed_len + seed bytes).
|
||||||
|
- `0x0006` signature (opaque bytes).
|
||||||
|
|
||||||
|
Helper usage:
|
||||||
|
- `amduat_fer1_receipt_from_pel_run_v1_1` emits v1.1 receipts and uses the
|
||||||
|
same output_ref fallback as v1: when no outputs exist, `output_ref` is the
|
||||||
|
stored PEL result reference.
|
||||||
|
|
||||||
|
References:
|
||||||
|
- `include/amduat/enc/fer1_receipt.h`
|
||||||
|
- `src/near_core/enc/fer1_receipt.c`
|
||||||
|
|
|
||||||
|
|
@ -748,6 +748,154 @@ cleanup:
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_receipt_helper_v1_1(void) {
|
||||||
|
amduat_pel_run_result_t pel_run;
|
||||||
|
amduat_artifact_t artifact;
|
||||||
|
amduat_fer1_receipt_t decoded;
|
||||||
|
amduat_fer1_log_entry_t log_entry;
|
||||||
|
amduat_fer1_limits_t limits;
|
||||||
|
uint8_t f0[32], i0[32], e0[32], o0[32], ex0[32], fp0[32], lr0[32];
|
||||||
|
uint8_t run_id[] = {0x01, 0x02, 0x03, 0x04};
|
||||||
|
uint8_t rng_seed[] = {0x09, 0x08, 0x07};
|
||||||
|
uint8_t signature[] = {0xde, 0xad, 0xbe, 0xef};
|
||||||
|
uint8_t digest0[] = {0xaa, 0xbb, 0xcc};
|
||||||
|
int exit_code = 1;
|
||||||
|
|
||||||
|
memset(&pel_run, 0, sizeof(pel_run));
|
||||||
|
pel_run.result_ref = make_ref(0x77, o0);
|
||||||
|
pel_run.output_refs = &pel_run.result_ref;
|
||||||
|
pel_run.output_refs_len = 1;
|
||||||
|
pel_run.has_result_value = true;
|
||||||
|
pel_run.result_value.pel1_version = 1;
|
||||||
|
pel_run.result_value.program_ref = make_ref(0x11, f0);
|
||||||
|
|
||||||
|
memset(&limits, 0, sizeof(limits));
|
||||||
|
limits.cpu_ms = 1;
|
||||||
|
limits.wall_ms = 2;
|
||||||
|
limits.max_rss_kib = 3;
|
||||||
|
limits.io_reads = 4;
|
||||||
|
limits.io_writes = 5;
|
||||||
|
|
||||||
|
memset(&log_entry, 0, sizeof(log_entry));
|
||||||
|
log_entry.kind = 1;
|
||||||
|
log_entry.log_ref = make_ref(0x70, lr0);
|
||||||
|
log_entry.sha256 = amduat_octets(digest0, sizeof(digest0));
|
||||||
|
|
||||||
|
if (!amduat_fer1_receipt_from_pel_run_v1_1(
|
||||||
|
&pel_run,
|
||||||
|
make_ref(0x22, i0),
|
||||||
|
make_ref(0x33, e0),
|
||||||
|
amduat_octets("tester", 6),
|
||||||
|
make_ref(0x50, ex0),
|
||||||
|
false,
|
||||||
|
amduat_reference(0, amduat_octets(NULL, 0)),
|
||||||
|
amduat_octets(NULL, 0),
|
||||||
|
10,
|
||||||
|
20,
|
||||||
|
true,
|
||||||
|
make_ref(0x66, fp0),
|
||||||
|
true,
|
||||||
|
amduat_octets(run_id, sizeof(run_id)),
|
||||||
|
true,
|
||||||
|
limits,
|
||||||
|
&log_entry,
|
||||||
|
1,
|
||||||
|
true,
|
||||||
|
2,
|
||||||
|
true,
|
||||||
|
amduat_octets(rng_seed, sizeof(rng_seed)),
|
||||||
|
true,
|
||||||
|
amduat_octets(signature, sizeof(signature)),
|
||||||
|
&artifact)) {
|
||||||
|
fprintf(stderr, "v1.1 helper failed\n");
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_enc_fer1_receipt_decode_v1_1(artifact.bytes, &decoded)) {
|
||||||
|
fprintf(stderr, "v1.1 helper decode failed\n");
|
||||||
|
amduat_artifact_free(&artifact);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decoded.has_run_id || !decoded.has_limits || !decoded.has_determinism ||
|
||||||
|
!decoded.has_signature ||
|
||||||
|
!amduat_reference_eq(decoded.output_ref, pel_run.result_ref)) {
|
||||||
|
fprintf(stderr, "v1.1 helper decoded fields mismatch\n");
|
||||||
|
goto cleanup_decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_code = 0;
|
||||||
|
|
||||||
|
cleanup_decoded:
|
||||||
|
amduat_enc_fer1_receipt_free(&decoded);
|
||||||
|
amduat_artifact_free(&artifact);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_receipt_helper_v1_1_failed_run(void) {
|
||||||
|
amduat_pel_run_result_t pel_run;
|
||||||
|
amduat_artifact_t artifact;
|
||||||
|
amduat_fer1_receipt_t decoded;
|
||||||
|
uint8_t f0[32], i0[32], e0[32], r0[32], ex0[32];
|
||||||
|
int exit_code = 1;
|
||||||
|
|
||||||
|
memset(&pel_run, 0, sizeof(pel_run));
|
||||||
|
pel_run.result_ref = make_ref(0x77, r0);
|
||||||
|
pel_run.output_refs = NULL;
|
||||||
|
pel_run.output_refs_len = 0;
|
||||||
|
pel_run.has_result_value = true;
|
||||||
|
pel_run.result_value.pel1_version = 1;
|
||||||
|
pel_run.result_value.program_ref = make_ref(0x11, f0);
|
||||||
|
|
||||||
|
if (!amduat_fer1_receipt_from_pel_run_v1_1(
|
||||||
|
&pel_run,
|
||||||
|
make_ref(0x22, i0),
|
||||||
|
make_ref(0x33, e0),
|
||||||
|
amduat_octets("tester", 6),
|
||||||
|
make_ref(0x50, ex0),
|
||||||
|
false,
|
||||||
|
amduat_reference(0, amduat_octets(NULL, 0)),
|
||||||
|
amduat_octets(NULL, 0),
|
||||||
|
10,
|
||||||
|
20,
|
||||||
|
false,
|
||||||
|
amduat_reference(0, amduat_octets(NULL, 0)),
|
||||||
|
false,
|
||||||
|
amduat_octets(NULL, 0),
|
||||||
|
false,
|
||||||
|
(amduat_fer1_limits_t){0},
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
amduat_octets(NULL, 0),
|
||||||
|
false,
|
||||||
|
amduat_octets(NULL, 0),
|
||||||
|
&artifact)) {
|
||||||
|
fprintf(stderr, "v1.1 failed run helper failed\n");
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_enc_fer1_receipt_decode_v1_1(artifact.bytes, &decoded)) {
|
||||||
|
fprintf(stderr, "v1.1 failed run helper decode failed\n");
|
||||||
|
amduat_artifact_free(&artifact);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_reference_eq(decoded.output_ref, pel_run.result_ref)) {
|
||||||
|
fprintf(stderr, "v1.1 failed run output_ref mismatch\n");
|
||||||
|
goto cleanup_decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_code = 0;
|
||||||
|
|
||||||
|
cleanup_decoded:
|
||||||
|
amduat_enc_fer1_receipt_free(&decoded);
|
||||||
|
amduat_artifact_free(&artifact);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
if (test_receipt_round_trip() != 0) {
|
if (test_receipt_round_trip() != 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -767,5 +915,11 @@ int main(void) {
|
||||||
if (test_receipt_v1_1_reject_duplicate_tag() != 0) {
|
if (test_receipt_v1_1_reject_duplicate_tag() != 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (test_receipt_helper_v1_1() != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (test_receipt_helper_v1_1_failed_run() != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue