/* SPDX-License-Identifier: Apache-2.0 */ /* Host harness: replays a day of demand through the kernel with a modelled meter and writes an OER/2 vector file. The meter is a model of constants (a cycle count, standby and shared draws, a link energy), none measured on the node, so every figure is graded projected (oer-receipts ยง2: an Estimator figure), from a simulation, by a modelled method: the receipts never present the model as a reading. */ #include "settle.h" #include #include #include static uint32_t rng_s = 42; static double urand(void){ rng_s = rng_s * 1664525u + 1013904223u; return (rng_s >> 8) / 16777216.0; } int main(int argc, char **argv){ const char *path = argc > 1 ? argv[1] : "firmware_vectors.json"; int n_events = argc > 2 ? atoi(argv[2]) : 400; static settle_ctx_t ctx; uint8_t seed[32]; int i; for (i = 0; i < 32; i++) seed[i] = (uint8_t)(i * 7 + 3); settle_init(&ctx, seed, 300.0, 86400.0); FILE *f = fopen(path, "w"); if (!f) return 1; char pk[65]; settle_pk_hex(&ctx, pk); fprintf(f, "{\"oer\":\"2.0\",\"draft\":\"0.1\",\"source\":\"settle kernel host harness, %d events\",\"keys\":{\"ed25519:bench-node-01\":\"%s\"},\"vectors\":[{\"name\":\"v10 firmware chain from the C kernel\",\"receipts\":[", n_events, pk); static char buf[4096]; double now = 0, last = 0, meter = 0; const double standby_w = 1.8e-3, shared_w = 0.06; for (i = 0; i < n_events; i++) { now += 20 + 80 * urand(); char cls = urand() < 0.34 ? 'A' : 'B'; double z = urand(); uint32_t id = (uint32_t)(cls == 'A' ? 1 + 2999 * z * z * z : 1 + 399 * z * z * z); settle_meter_t m; m.compute_j = 120000.0 * ctx.cycle_j; m.movement_j = cls == 'A' ? 2.3e-6 : 0; m.idle_alloc_j = standby_w * (now - last); m.shared_alloc_j = shared_w * (now - last); m.upstream_j = 0; m.latency_s = cls == 'A' ? 0.019 : 0.0017; m.method = "model_estimated"; m.how = "projected"; m.device = "simulation"; m.weakest_how = "projected"; m.weakest_input = "wire_w"; settle_result_t res; if (settle_decide(&ctx, cls, id, now, &m, buf, sizeof buf, &res)) { fprintf(stderr, "decide failed\n"); return 2; } meter += res.joules_total; last = now; fprintf(f, "%s%s", i ? "," : "", buf); } static char recbuf[1 << 20]; fprintf(f, "],\"records\":"); if (settle_records_json(&ctx, recbuf, sizeof recbuf)) { fprintf(stderr, "records overflow\n"); return 3; } fputs(recbuf, f); fprintf(f, ",\"ledger\":{\"meter_joules\":\"%.12e\",\"unallocated_joules\":\"0.000000e+00\",\"carried_forward_joules\":\"0.000000e+00\"},\"expected\":[]}]}\n", meter); fclose(f); fprintf(stderr, "wrote %s: %d receipts, modelled meter %.6f J (projected, not a reading)\n", path, n_events, meter); return 0; }