code wiki / _hdl_build / nx_gossip_gate.nx
nx_gossip_gate.nx source
↩ module page · 53 lines · 3709 B
1// nx_gossip_gate.nx -- proves epidemic anti-entropy convergence: peer A holds {X,Y}, peer B holds {Y,Z}. One
2// symmetric gossip round (digest -> select-the-delta -> merge) leaves BOTH holding the union {X,Y,Z}, and each
3// side ships ONLY the row the other lacked (efficient -- not the whole registry). Run pairwise across a mesh and
4// the who-has-what converges everywhere. Composes nx_dist_index + nx_gossip. expect_exit: 0 license_tier: ORIGINAL
5import "nx_dist_index.nx"
6import "nx_g_puts_lib.nx"
7import "nx_gossip.nx"
8import "nx_syscalls.nx"
9
10func 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 }
11func has3(reg: *u8, rlen: i64, a: *u8, b: *u8, c: *u8) -> i64 { var r: i64=1; if di_has_cid(reg,rlen,a)==0 {r=0} if di_has_cid(reg,rlen,b)==0 {r=0} if di_has_cid(reg,rlen,c)==0 {r=0} return r }
12
13func main() -> i64 {
14 g_puts("=== nx_gossip_gate: epidemic anti-entropy (two peers converge to the union) ===\n" as *u8)
15 let st: *i64 = sys_mmap(64) as *i64; st[0]=0; st[1]=0
16
17 let cX: *u8 = "aaaa1111" as *u8; let cY: *u8 = "bbbb2222" as *u8; let cZ: *u8 = "cccc3333" as *u8
18
19 let regA: *u8 = sys_mmap(65536); var alen: i64=0
20 let regB: *u8 = sys_mmap(65536); var blen: i64=0
21 // A holds X,Y ; B holds Y,Z (overlap = Y)
22 alen = di_publish(regA, alen, "fileX" as *u8, cX, 10, "magX" as *u8, "urlX" as *u8)
23 alen = di_publish(regA, alen, "fileY" as *u8, cY, 20, "magY" as *u8, "urlY" as *u8)
24 blen = di_publish(regB, blen, "fileY" as *u8, cY, 20, "magY" as *u8, "urlY" as *u8)
25 blen = di_publish(regB, blen, "fileZ" as *u8, cZ, 30, "magZ" as *u8, "urlZ" as *u8)
26 g_ck("T0 start: A={X,Y}=2 rows, B={Y,Z}=2 rows" as *u8, (di_count_rows(regA,alen)==2) & (di_count_rows(regB,blen)==2), st)
27
28 // round A -> B : B tells A its digest, A ships only what B lacks
29 let dgB: *u8 = sys_mmap(8192); let dgBlen: i64 = gossip_digest(regB, blen, dgB)
30 let selAB: *u8 = sys_mmap(65536); let selABlen: i64 = gossip_select(regA, alen, dgB, dgBlen, selAB)
31 g_ck("T1 A->B ships only the delta (1 row = X), not the whole registry" as *u8, di_count_rows(selAB, selABlen)==1, st)
32 blen = gossip_merge(regB, blen, selAB, selABlen)
33
34 // round B -> A : symmetric
35 let dgA: *u8 = sys_mmap(8192); let dgAlen: i64 = gossip_digest(regA, alen, dgA)
36 let selBA: *u8 = sys_mmap(65536); let selBAlen: i64 = gossip_select(regB, blen, dgA, dgAlen, selBA)
37 g_ck("T2 B->A ships only the delta (1 row = Z)" as *u8, di_count_rows(selBA, selBAlen)==1, st)
38 alen = gossip_merge(regA, alen, selBA, selBAlen)
39
40 g_ck("T3 A converged to the union (3 rows, no dup of Y)" as *u8, di_count_rows(regA, alen)==3, st)
41 g_ck("T4 B converged to the union (3 rows, no dup of Y)" as *u8, di_count_rows(regB, blen)==3, st)
42 g_ck("T5 A now holds X,Y,Z" as *u8, has3(regA, alen, cX, cY, cZ), st)
43 g_ck("T6 CONVERGENCE: B also holds X,Y,Z -> both nodes identical" as *u8, has3(regB, blen, cX, cY, cZ), st)
44
45 g_puts(" --- peer A registry after gossip ---\n" as *u8); sys_write(1, regA, alen)
46 g_puts(" --- peer B registry after gossip ---\n" as *u8); sys_write(1, regB, blen)
47
48 g_puts("\n PASS " as *u8); if st[0]==st[1] { g_puts("ALL" as *u8) } else { g_puts("PARTIAL" as *u8) }
49 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
50 g_puts(" ("); g_puts(p); g_puts(")\n" as *u8)
51 if st[0]==st[1] { g_puts("=== GREEN (epidemic gossip: the mesh converges, delta-only, idempotent) ===\n" as *u8); sys_exit(0); return 0 }
52 g_puts("=== RED ===\n" as *u8); sys_exit(1); return 1
53}