code wiki / (root) / nx_avail_map_gate.nx

nx_avail_map_gate.nx source

↩ module page · 132 lines · 6230 B

1// nx_avail_map_gate.nx -- KAT + negative controls for the shared cross-peer availability map. 2// Native sovereign lane; exit 0 = all pass, N = assertion N failed. Prints every MEASURED value 3// (no self-grading -- the raw counts/picks are the evidence). 4// 5// T1 cross-peer count aggregation is exact 6// T2 rarest-first picks the globally-rarest piece the peer HAS 7// T3 rarest-first advances to the next-rarest once a piece is done 8// T4 NEG-CONTROL: a peer that LACKS the rarest pieces is never told to fetch them 9// T5 a HAVE message bumps a single piece's availability 10// T6 NEG-CONTROL: the lock is load-bearing -- 8 procs x 20 locked increments == exact, 11// the same UNLOCKED loses counts (torn read-modify-write) 12 13import "nx_avail_map.nx" 14import "nx_assert.nx" 15 16// set bit for piece p, MSB-first (bit 7 of byte 0 == piece 0), matching BEP-3 / nx_pw_bitfield_has. 17func gset(bits: *u8, p: i64) -> i64 { 18 let byte: i64 = p / 8 19 let bit: i64 = 7 - (p - byte * 8) 20 bits[byte] = ((bits[byte] as i64) | (1 << bit)) as u8 21 return 0 22} 23 24func main() -> i64 { 25 // ---- T1: cross-peer count aggregation ---- 26 // peer A has {0,1,2,3}; B has {1,2,3}; C has {2,3} -> counts = [1,2,3,3,0,0,0,0] 27 let pA: *u8 = sys_mmap(16); gset(pA,0); gset(pA,1); gset(pA,2); gset(pA,3) 28 let pB: *u8 = sys_mmap(16); gset(pB,1); gset(pB,2); gset(pB,3) 29 let pC: *u8 = sys_mmap(16); gset(pC,2); gset(pC,3) 30 let path: *u8 = "/tmp/_nx_avail_t1.bin" as *u8 31 let npc: i64 = 8 32 am_init(path, npc) 33 am_add_bitfield(path, pA, 16, npc) 34 am_add_bitfield(path, pB, 16, npc) 35 am_add_bitfield(path, pC, 16, npc) 36 let cnt: *i64 = sys_mmap(8*16) as *i64 37 am_load(path, cnt, npc) 38 nx_puts_err("T1 count[0]="); nx_puti_err(cnt[0]) 39 nx_puts_err("T1 count[1]="); nx_puti_err(cnt[1]) 40 nx_puts_err("T1 count[2]="); nx_puti_err(cnt[2]) 41 nx_puts_err("T1 count[3]="); nx_puti_err(cnt[3]) 42 nx_puts_err("T1 count[4]="); nx_puti_err(cnt[4]) 43 if cnt[0] != 1 { return 1 } 44 if cnt[1] != 2 { return 2 } 45 if cnt[2] != 3 { return 3 } 46 if cnt[3] != 3 { return 4 } 47 if cnt[4] != 0 { return 5 } 48 49 let done: *u8 = sys_mmap(64) // all 0 = nothing downloaded yet 50 let av: *i64 = sys_mmap(8*64) as *i64 51 let eff: *i64 = sys_mmap(8*64) as *i64 52 53 // ---- T2: peer A has {0,1,2,3}, nothing done -> rarest = piece 0 (count 1) ---- 54 let g2: i64 = am_pick_rarest(path, done, pA, 16, 1, npc, av, eff) 55 nx_puts_err("T2 pick(peer=ABCD, none done)="); nx_puti_err(g2) 56 if g2 != 0 { return 6 } 57 58 // ---- T3: mark piece 0 done -> rarest = piece 1 (count 2) ---- 59 done[0] = 1 as u8 60 let g3: i64 = am_pick_rarest(path, done, pA, 16, 1, npc, av, eff) 61 nx_puts_err("T3 pick(piece0 done)="); nx_puti_err(g3) 62 if g3 != 1 { return 7 } 63 64 // ---- T4 NEG-CONTROL: peer C has ONLY {2,3}; nothing done. The globally-rarest pieces are 65 // 0 (1) then 1 (2), but C LACKS both -> it must be told to fetch piece 2 (count 3, the 66 // rarest C actually has), NEVER 0 or 1. Proves the peer-has filter is real. ---- 67 done[0] = 0 as u8 68 let g4: i64 = am_pick_rarest(path, done, pC, 16, 1, npc, av, eff) 69 nx_puts_err("T4 pick(peer=only{2,3})="); nx_puti_err(g4) 70 if g4 != 2 { return 8 } 71 72 // ---- T5: a HAVE for piece 4 bumps its count 0->1; a peer with only {4} then picks 4 ---- 73 am_add_have(path, 4) 74 let pD: *u8 = sys_mmap(16); gset(pD,4) 75 let g5: i64 = am_pick_rarest(path, done, pD, 16, 1, npc, av, eff) 76 nx_puts_err("T5 pick(after HAVE piece4)="); nx_puti_err(g5) 77 if g5 != 4 { return 9 } 78 79 // ---- T6 NEG-CONTROL: the lock is load-bearing ---- 80 // K children x N increments of an ALL-SET bitfield over a fresh map. 81 // LOCKED -> every piece == K*N exactly (no lost RMW). 82 // UNLOCKED -> concurrent read-modify-write tears -> some piece < K*N (lost increments). 83 // K*N kept < 255 so loss shows as a deficit, not hidden behind the saturation ceiling. 84 let K: i64 = 8; let N: i64 = 20; let ncc: i64 = 32; let target: i64 = K * N // 160 85 let allb: *u8 = sys_mmap(16); var bz: i64 = 0; while bz < 4 { allb[bz] = 0xff as u8; bz = bz + 1 } // 32 pieces set 86 87 // -- LOCKED -- 88 let lpath: *u8 = "/tmp/_nx_avail_cc_locked.bin" as *u8 89 am_init(lpath, ncc) 90 var k1: i64 = 0 91 while k1 < K { 92 let pid: i64 = sys_fork() 93 if pid == 0 { 94 var j: i64 = 0; while j < N { am_add_bitfield(lpath, allb, 16, ncc); j = j + 1 } 95 sys_exit(0) 96 } 97 k1 = k1 + 1 98 } 99 var r1: i64 = 0; while r1 < K { let st: *i64 = sys_mmap(16) as *i64; sys_wait4(0-1, st, 0); r1 = r1 + 1 } 100 let lc: *i64 = sys_mmap(8*64) as *i64; am_load(lpath, lc, ncc) 101 var lmin: i64 = target + 1; var lmax: i64 = 0; var lp: i64 = 0 102 while lp < ncc { if lc[lp] < lmin { lmin = lc[lp] } if lc[lp] > lmax { lmax = lc[lp] } lp = lp + 1 } 103 nx_puts_err("T6 LOCKED target="); nx_puti_err(target) 104 nx_puts_err("T6 LOCKED min="); nx_puti_err(lmin) 105 nx_puts_err("T6 LOCKED max="); nx_puti_err(lmax) 106 if lmin != target { return 10 } 107 if lmax != target { return 11 } 108 109 // -- UNLOCKED (neg-control) -- 110 let upath: *u8 = "/tmp/_nx_avail_cc_unlocked.bin" as *u8 111 am_init(upath, ncc) 112 var k2: i64 = 0 113 while k2 < K { 114 let pid2: i64 = sys_fork() 115 if pid2 == 0 { 116 var j2: i64 = 0; while j2 < N { am_add_bitfield_unlocked(upath, allb, 16, ncc); j2 = j2 + 1 } 117 sys_exit(0) 118 } 119 k2 = k2 + 1 120 } 121 var r2: i64 = 0; while r2 < K { let st2: *i64 = sys_mmap(16) as *i64; sys_wait4(0-1, st2, 0); r2 = r2 + 1 } 122 let uc: *i64 = sys_mmap(8*64) as *i64; am_load(upath, uc, ncc) 123 var umin: i64 = target + 1; var lost: i64 = 0; var up: i64 = 0 124 while up < ncc { if uc[up] < umin { umin = uc[up] } lost = lost + (target - uc[up]); up = up + 1 } 125 nx_puts_err("T6 UNLOCKED target="); nx_puti_err(target) 126 nx_puts_err("T6 UNLOCKED min="); nx_puti_err(umin) 127 nx_puts_err("T6 UNLOCKED total_lost="); nx_puti_err(lost) 128 if lost <= 0 { return 12 } // the neg-control MUST exhibit loss, else the lock proof is vacuous 129 130 nx_puts_err("nx_avail_map_gate verdict=GREEN pass="); nx_puti_err(12) 131 return 0 132}