code wiki / (root) / nx_transport.nx

nx_transport.nx source

↩ module page · 68 lines · 3903 B

1// nx_transport.nx -- SOVEREIGN transport CONTRACT + loopback reference impl (operator 2026-07-04: "we 2// wont have websocket ... built from the hardware rung up"). A TRANSPORT moves opaque wire FRAMES between 3// endpoints. The core PRODUCES/CONSUMES frames (vc_wire_pack/parse, FEC, sequencing); the transport only 4// MOVES bytes. The browser adapter satisfies this contract with WebSocket; the NishiOS adapter satisfies 5// it with the sovereign datagram/QUIC leg (task #15). Nothing above the transport names WebSocket -> swap 6// the impl, everything else is unchanged. Reliability/ordering VARY by impl (WS = reliable-ordered, 7// datagram = best-effort); the core's jitter-buffer / NACK / FEC rungs provide the reliability layer ABOVE 8// this best-effort mover -- so the CONTRACT is only "move a frame, in order, intact, or drop it". 9// 10// This reference impl is a bounded FIFO ring in a FLAT memory region (WAT-safe: no struct -> compiles to 11// wasm for the browser adapter's buffer AND native for the NishiOS queue, from one source). Layout: 12// header i64[4] @ byte 0 : [0]=closed [1]=head [2]=tail [3]=count 13// frame slots @ byte TP_HDR : slot i = [len:i64][bytes:TP_FRAME_CAP], stride TP_SLOT 14// license_tier: ORIGINAL 15 16const TP_MAX_FRAMES: i64 = 64 17const TP_FRAME_CAP: i64 = 2048 18const TP_HDR: i64 = 32 // 4 i64 header 19const TP_SLOT: i64 = 2056 // 8 (len) + TP_FRAME_CAP 20// total region bytes a caller must provide = TP_HDR + TP_MAX_FRAMES*TP_SLOT = 131616 21const TP_REGION: i64 = 131616 22 23func tp_h(mem: *u8, i: i64) -> i64 { let p: *i64 = ((mem as i64) + i * 8) as *i64; return p[0] } 24func tp_hset(mem: *u8, i: i64, v: i64) -> i64 { let p: *i64 = ((mem as i64) + i * 8) as *i64; p[0] = v; return 0 } 25func tp_slot_len(mem: *u8, slot: i64) -> *i64 { return ((mem as i64) + TP_HDR + slot * TP_SLOT) as *i64 } 26func tp_slot_bytes(mem: *u8, slot: i64) -> *u8 { return ((mem as i64) + TP_HDR + slot * TP_SLOT + 8) as *u8 } 27 28// open a transport in `mem` (>= TP_REGION bytes). returns the handle (= mem). idempotent init. 29func tp_open(mem: *u8) -> i64 { 30 tp_hset(mem, 0, 0); tp_hset(mem, 1, 0); tp_hset(mem, 2, 0); tp_hset(mem, 3, 0) 31 return mem as i64 32} 33 34// send ONE frame (enqueue a COPY). returns len sent, or -1 (closed / full / oversized -> a real drop, 35// honestly signalled, never silent). Best-effort by contract: a full ring drops (the core re-sends via FEC). 36func tp_send(h: *u8, frame: *u8, len: i64) -> i64 { 37 if tp_h(h, 0) == 1 { return 0 - 1 } // closed 38 if len < 0 { return 0 - 1 } 39 if len > TP_FRAME_CAP { return 0 - 1 } // oversized -> honest drop 40 if tp_h(h, 3) >= TP_MAX_FRAMES { return 0 - 1 } // full -> honest drop 41 let tail: i64 = tp_h(h, 2) 42 let ln: *i64 = tp_slot_len(h, tail); ln[0] = len 43 let dst: *u8 = tp_slot_bytes(h, tail) 44 var i: i64 = 0; while i < len { dst[i] = frame[i]; i = i + 1 } 45 tp_hset(h, 2, (tail + 1) % TP_MAX_FRAMES) 46 tp_hset(h, 3, tp_h(h, 3) + 1) 47 return len 48} 49 50// recv ONE frame into out (<= cap). returns len, 0 (empty), or -1 (closed AND empty). FIFO order. 51func tp_recv(h: *u8, out: *u8, cap: i64) -> i64 { 52 if tp_h(h, 3) == 0 { if tp_h(h, 0) == 1 { return 0 - 1 } return 0 } 53 let head: i64 = tp_h(h, 1) 54 let ln: *i64 = tp_slot_len(h, head) 55 var len: i64 = ln[0] 56 if len > cap { len = cap } // truncate to caller's buffer (honest) 57 let src: *u8 = tp_slot_bytes(h, head) 58 var i: i64 = 0; while i < len { out[i] = src[i]; i = i + 1 } 59 tp_hset(h, 1, (head + 1) % TP_MAX_FRAMES) 60 tp_hset(h, 3, tp_h(h, 3) - 1) 61 return len 62} 63 64// pending frame count (adapters use this to drain). 65func tp_pending(h: *u8) -> i64 { return tp_h(h, 3) } 66 67// close: further sends are dropped; recv drains remaining then returns -1. 68func tp_close(h: *u8) -> i64 { tp_hset(h, 0, 1); return 0 }