code wiki / _hdl_build / nx_hub_replicate_gate.nx
nx_hub_replicate_gate.nx source
↩ module page · 66 lines · 4137 B
1// nx_hub_replicate_gate.nx -- proves HUB-TO-HUB replication end to end: hub B (empty) learns hub A's index via
2// gossip, PULLS the bytes B lacks, VERIFIES each replica's SHA-256 against the advertised content-id (fail-closed),
3// adopts them, and becomes a new source. Also proves a content/cid MISMATCH is rejected (a hostile source cannot
4// poison the mesh). Composes nx_gossip + nx_hub_replicate + nx_dist_index + nx_dist_publish. expect_exit: 0
5// license_tier: ORIGINAL
6import "nx_hub_replicate.nx"
7import "nx_g_puts_lib.nx"
8import "nx_gossip.nx"
9import "nx_dist_index.nx"
10import "nx_dist_publish.nx"
11import "nx_syscalls.nx"
12
13func g_ck(name: *u8, cond: i64, st: *i64) -> i64 { st[1]=st[1]+1; if cond==1 { st[0]=st[0]+1; g_puts(" [OK] " as *u8) } else { g_puts(" [FAIL] " as *u8) } g_puts(name); g_puts("\n" as *u8); return 0 }
14func g_fix(path: *u8, content: *u8, n: i64) -> i64 { let fd: i64=sys_openat_wr(path, 0x1a4); if fd<0 { return 0-1 } sys_write(fd, content, n); sys_close(fd); return 0 }
15
16func main() -> i64 {
17 g_puts("=== nx_hub_replicate_gate: hub-to-hub content replication (fail-closed) ===\n" as *u8)
18 let st: *i64 = sys_mmap(64) as *i64; st[0]=0; st[1]=0
19
20 // hub A holds two files on disk (the source); the index row's url field points at the source.
21 g_fix("/tmp/hubA_X.bin" as *u8, "content-X-payload" as *u8, 17)
22 g_fix("/tmp/hubA_Y.bin" as *u8, "content-Y-payload" as *u8, 17)
23 let cidX: *u8 = sys_mmap(128); dp_content_id("/tmp/hubA_X.bin" as *u8, cidX)
24 let cidY: *u8 = sys_mmap(128); dp_content_id("/tmp/hubA_Y.bin" as *u8, cidY)
25
26 let regA: *u8 = sys_mmap(65536); var alen: i64=0
27 let regB: *u8 = sys_mmap(65536); var blen: i64=0
28 alen = di_publish(regA, alen, "fileX" as *u8, cidX, 17, "magX" as *u8, "/tmp/hubA_X.bin" as *u8)
29 alen = di_publish(regA, alen, "fileY" as *u8, cidY, 17, "magY" as *u8, "/tmp/hubA_Y.bin" as *u8)
30
31 // B learns A's index via gossip: what is B missing?
32 let dgB: *u8 = sys_mmap(8192); let dgBlen: i64 = gossip_digest(regB, blen, dgB)
33 let plan: *u8 = sys_mmap(65536); let planlen: i64 = gossip_select(regA, alen, dgB, dgBlen, plan)
34 g_ck("T1 gossip plan: B is missing 2 items (X,Y)" as *u8, di_count_rows(plan, planlen)==2, st)
35
36 // pull + verify each planned row (fail-closed)
37 var verified: i64=0; var total: i64=0; var ls: i64=0
38 while ls<planlen {
39 let le: i64 = di_eol(plan, ls, planlen)
40 if le>ls { total=total+1; if hr_replicate_row((plan as i64 + ls) as *u8, le-ls)==1 { verified=verified+1 } }
41 ls = le+1
42 }
43 g_ck("T2 both replicas verify (SHA-256 == advertised cid)" as *u8, (verified==2) & (total==2), st)
44
45 // adopt the verified rows
46 blen = gossip_merge(regB, blen, plan, planlen)
47 g_ck("T3 B adopted both -> now holds 2 items" as *u8, di_count_rows(regB, blen)==2, st)
48
49 // fail-closed: a row that advertises X's source but Y's cid must be REJECTED
50 let bad: *u8 = sys_mmap(4096); let badlen: i64 = di_publish(bad, 0, "fileX" as *u8, cidY, 17, "magX" as *u8, "/tmp/hubA_X.bin" as *u8)
51 g_ck("T4 fail-closed: content/cid MISMATCH rejected (no mesh poisoning)" as *u8, hr_replicate_row(bad, badlen-1)==0, st)
52
53 // B is now a SOURCE: it can serve X onward (A -> B -> C)
54 let out: *u8 = sys_mmap(512); let rl: i64 = di_lookup(regB, blen, cidX, out)
55 g_ck("T5 B is now a source (lookup cidX -> a servable row)" as *u8, rl>0, st)
56
57 g_ck("T6 HUB-TO-HUB: content flowed A->B, verified, B holds both" as *u8, (di_has_cid(regB, blen, cidX)==1) & (di_has_cid(regB, blen, cidY)==1), st)
58
59 g_puts(" --- hub B registry after replication (now a source) ---\n" as *u8); sys_write(1, regB, blen)
60
61 g_puts("\n PASS " as *u8); if st[0]==st[1] { g_puts("ALL" as *u8) } else { g_puts("PARTIAL" as *u8) }
62 let p: *u8=sys_mmap(8); p[0]=(48+st[0]) as u8; p[1]=47 as u8; p[2]=(48+st[1]) as u8; p[3]=0 as u8
63 g_puts(" ("); g_puts(p); g_puts(")\n" as *u8)
64 if st[0]==st[1] { g_puts("=== GREEN (hub-to-hub replication: pull, verify fail-closed, adopt, re-serve) ===\n" as *u8); sys_exit(0); return 0 }
65 g_puts("=== RED ===\n" as *u8); sys_exit(1); return 1
66}