code wiki / _hdl_build / nx_mp_relay_gate.nx

nx_mp_relay_gate.nx source

↩ module page · 86 lines · 4462 B

1// nx_mp_relay_gate.nx -- proves the sovereign daemon roster serializer (nx_mp_relay) over nx_room_relay. 2// NO JS, NO curl: a pure-nx gate. The daemon serializes OTHER live players into [len][frame] records that 3// the wasm parses with gi_net_ingest_roster. This is the /roster GET body, proven sovereignly. 4// 1) serialize 2 peers in a room -> 2 records, frame bytes byte-EXACT, in slot order 5// 2) room isolation (neg): a peer in another room is not in the body 6// 3) self excluded (neg): the requesting player never sees itself 7// 4) staleness (neg): a peer past TTL is dropped from the body 8// Built nx_cc_sovereign -> nxasm_x86 (no gcc, no .sh). license_tier: ORIGINAL 9import "nx_syscalls.nx" 10import "nx_gate_emit_lib.nx" 11import "nx_mp_relay.nx" // brings nx_room_relay (rr_*) transitively -- do NOT also import it directly (double-import -> expand_imports fail) 12import "nx_gate_verdict.nx" 13 14func rec_eq(body: *u8, o: i64, expect: *u8, n: i64) -> i64 { 15 if (body[o] as i64) != n { return 0 } 16 var k: i64 = 0 17 while k < n { if body[o + 1 + k] != expect[k] { return 0 } k = k + 1 } 18 return 1 19} 20 21func main() -> i64 { 22 g_puts("nx_mp_relay gate (sovereign daemon /roster serializer, NO js/curl)\n" as *u8) 23 var pass: i64 = 0; var total: i64 = 0 24 25 let N: i64 = 8 26 let SB: i64 = 64 27 let st: *i64 = sys_mmap((2 + 5*N) * 8) as *i64 28 let arena: *u8 = sys_mmap(N * SB) 29 rr_init(st, N, SB) 30 31 let FL: i64 = 11 32 let fa: *u8 = sys_mmap(64); var i: i64=0; while i<FL { fa[i]=(100+i) as u8; i=i+1 } 33 let fb: *u8 = sys_mmap(64); i=0; while i<FL { fb[i]=(40+i) as u8; i=i+1 } 34 let fd: *u8 = sys_mmap(64); i=0; while i<FL { fd[i]=(7+i) as u8; i=i+1 } 35 36 let ROOM_A: i64 = 0x7E70 37 let ROOM_B: i64 = 0x9999 38 rr_post(st, arena, ROOM_A, 100, 1000, 1, fa, FL) 39 rr_post(st, arena, ROOM_A, 101, 1000, 1, fb, FL) 40 rr_post(st, arena, ROOM_B, 200, 1000, 1, fd, FL) 41 42 let body: *u8 = sys_mmap(1024) 43 let tb: i64 = mp_roster_body(st, arena, SB, ROOM_A, 999, 1000, 8000, body) 44 let nrec: i64 = mp_roster_count(body, tb) 45 g_puts(" [measure] roster body = " as *u8); g_pn(tb); g_puts(" bytes, " as *u8); g_pn(nrec); g_puts(" records\n" as *u8) 46 47 // 1) two records, frame bytes exact, slot order (100 -> fa at offset 0, 101 -> fb at offset 12) 48 var r1: i64 = 1 49 if nrec != 2 { r1 = 0 } 50 if rec_eq(body, 0, fa, FL) != 1 { r1 = 0 } 51 if rec_eq(body, 1 + FL, fb, FL) != 1 { r1 = 0 } // second record starts after [len:1][11 bytes] 52 pass = pass + g_check("serialize: 2 records, frames byte-exact, slot order" as *u8, r1); total=total+1 53 54 // 2) room isolation -- room B's peer 200 never appears (its frame fd is absent) 55 var r2: i64 = 1 56 var found_b: i64 = 0 57 var o: i64 = 0 58 while o < tb { let fl: i64 = body[o] as i64; if rec_eq(body, o, fd, FL) == 1 { found_b = 1 } o = o + 1 + fl } 59 if found_b != 0 { r2 = 0 } 60 pass = pass + g_check("room isolation: other-room peer absent from body (neg)" as *u8, r2); total=total+1 61 62 // 3) self excluded -- request as peer 100, must not contain fa 63 let tb2: i64 = mp_roster_body(st, arena, SB, ROOM_A, 100, 1000, 8000, body) 64 var r3: i64 = 1 65 var found_self: i64 = 0 66 o = 0 67 while o < tb2 { let fl: i64 = body[o] as i64; if rec_eq(body, o, fa, FL) == 1 { found_self = 1 } o = o + 1 + fl } 68 if found_self != 0 { r3 = 0 } 69 if mp_roster_count(body, tb2) != 1 { r3 = 0 } // only peer 101 remains 70 pass = pass + g_check("self excluded from own roster (neg)" as *u8, r3); total=total+1 71 72 // 4) staleness -- advance now past TTL; body empties 73 let tb3: i64 = mp_roster_body(st, arena, SB, ROOM_A, 999, 20000, 8000, body) 74 pass = pass + g_check("stale peers dropped from body (neg)" as *u8, tb3 == 0); total=total+1 75 76 g_puts("---- mp-relay gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 77 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 78 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 79 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 80 let ctr__dry: *i64 = gv_ctr() 81 ctr__dry[0] = pass 82 ctr__dry[1] = total 83 let rc__dry: i64 = gv_verdict("MP-RELAY-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 84 sys_exit(rc__dry) 85 return rc__dry 86}