code wiki / (root) / nx_etg_byzantine_test.nx

nx_etg_byzantine_test.nx source

↩ module page · 124 lines · 5478 B

1// nx_etg_byzantine_test.nx -- KAT for E2.5 Byzantine M-of-N agreement. 2// 3// Verifies: 4// T1 Unanimous: 5 replicas all CONFIRMED, m=5 -> CONFIRMED. 5// T2 Majority: 3 CONFIRMED + 2 FALSIFIED, m=3 -> CONFIRMED. 6// T3 Bare-majority: 3 CONFIRMED + 2 FALSIFIED, m=2 -> CONFIRMED 7// (lowest-id tie-break since FALSIFIED also has count >= 2). 8// T4 Below threshold: 2 CONFIRMED + 3 different outcomes, m=3 9// -> NO_AGREEMENT. 10// T5 All different: 5 distinct outcomes, m=2 -> NO_AGREEMENT. 11// T6 Tie-break determinism: 2 CONFIRMED + 2 FALSIFIED, m=2 -> 12// CONFIRMED (lower outcome id) -- proves walk order. 13// T7 N=0 -> NO_AGREEMENT. 14// T8 m_required <= 0 -> NO_AGREEMENT. 15// T9 m_required > n -> NO_AGREEMENT. 16// T10 Counting helper exposes audit confidence: a 3-CONFIRMED- 17// majority should report exactly count==3 when queried. 18 19import "nx_syscalls.nx" 20import "nx_etg.nx" 21import "nx_etg_byzantine.nx" 22 23func main() -> i64 { 24 let buf: *u8 = sys_mmap(128) 25 let outcomes: *i64 = buf as *i64 26 27 // ----- T1 Unanimous agreement ----- 28 outcomes[0] = NX_ETG_OUTCOME_CONFIRMED 29 outcomes[1] = NX_ETG_OUTCOME_CONFIRMED 30 outcomes[2] = NX_ETG_OUTCOME_CONFIRMED 31 outcomes[3] = NX_ETG_OUTCOME_CONFIRMED 32 outcomes[4] = NX_ETG_OUTCOME_CONFIRMED 33 let r1: i64 = nx_etg_byzantine_outcome_agree(outcomes, 5, 5) 34 if r1 != NX_ETG_OUTCOME_CONFIRMED { return 1 } 35 36 // ----- T2 Majority agreement ----- 37 outcomes[0] = NX_ETG_OUTCOME_CONFIRMED 38 outcomes[1] = NX_ETG_OUTCOME_CONFIRMED 39 outcomes[2] = NX_ETG_OUTCOME_CONFIRMED 40 outcomes[3] = NX_ETG_OUTCOME_FALSIFIED 41 outcomes[4] = NX_ETG_OUTCOME_FALSIFIED 42 let r2: i64 = nx_etg_byzantine_outcome_agree(outcomes, 5, 3) 43 if r2 != NX_ETG_OUTCOME_CONFIRMED { return 2 } 44 45 // ----- T3 Bare-majority + tie-break by lowest id ----- 46 // CONFIRMED (id 1) has 3, FALSIFIED (id 4) has 2; m=2 means both 47 // reach threshold. Walk order returns CONFIRMED (lower id) first. 48 let r3: i64 = nx_etg_byzantine_outcome_agree(outcomes, 5, 2) 49 if r3 != NX_ETG_OUTCOME_CONFIRMED { return 3 } 50 51 // ----- T4 Below threshold ----- 52 outcomes[0] = NX_ETG_OUTCOME_CONFIRMED 53 outcomes[1] = NX_ETG_OUTCOME_CONFIRMED 54 outcomes[2] = NX_ETG_OUTCOME_FALSIFIED 55 outcomes[3] = NX_ETG_OUTCOME_INCONCLUSIVE 56 outcomes[4] = NX_ETG_OUTCOME_THROTTLED 57 let r4: i64 = nx_etg_byzantine_outcome_agree(outcomes, 5, 3) 58 if r4 != NX_ETG_BYZ_NO_AGREEMENT { return 4 } 59 60 // ----- T5 All different ----- 61 outcomes[0] = NX_ETG_OUTCOME_CONFIRMED 62 outcomes[1] = NX_ETG_OUTCOME_VENDOR_LIED_OMISSION 63 outcomes[2] = NX_ETG_OUTCOME_FALSIFIED 64 outcomes[3] = NX_ETG_OUTCOME_PAYWALLED_BUT_RESPONSIVE 65 outcomes[4] = NX_ETG_OUTCOME_RECLAIMED 66 let r5: i64 = nx_etg_byzantine_outcome_agree(outcomes, 5, 2) 67 if r5 != NX_ETG_BYZ_NO_AGREEMENT { return 5 } 68 69 // ----- T6 Tie-break: 2 CONFIRMED (id 1) + 2 FALSIFIED (id 4) ----- 70 // Both reach m=2. Walk returns CONFIRMED (lower id) first. 71 outcomes[0] = NX_ETG_OUTCOME_CONFIRMED 72 outcomes[1] = NX_ETG_OUTCOME_CONFIRMED 73 outcomes[2] = NX_ETG_OUTCOME_FALSIFIED 74 outcomes[3] = NX_ETG_OUTCOME_FALSIFIED 75 let r6: i64 = nx_etg_byzantine_outcome_agree(outcomes, 4, 2) 76 if r6 != NX_ETG_OUTCOME_CONFIRMED { return 6 } 77 78 // Inverse: 2 FALSIFIED + 2 CONFIRMED. Result still CONFIRMED 79 // because walk order is by outcome id, not by input position. 80 outcomes[0] = NX_ETG_OUTCOME_FALSIFIED 81 outcomes[1] = NX_ETG_OUTCOME_FALSIFIED 82 outcomes[2] = NX_ETG_OUTCOME_CONFIRMED 83 outcomes[3] = NX_ETG_OUTCOME_CONFIRMED 84 let r6b: i64 = nx_etg_byzantine_outcome_agree(outcomes, 4, 2) 85 if r6b != NX_ETG_OUTCOME_CONFIRMED { return 7 } 86 87 // ----- T7 N=0 ----- 88 let r7: i64 = nx_etg_byzantine_outcome_agree(outcomes, 0, 1) 89 if r7 != NX_ETG_BYZ_NO_AGREEMENT { return 8 } 90 // N negative: still NO_AGREEMENT (no underflow). 91 let r7b: i64 = nx_etg_byzantine_outcome_agree(outcomes, 0 - 1, 1) 92 if r7b != NX_ETG_BYZ_NO_AGREEMENT { return 9 } 93 94 // ----- T8 m_required <= 0 ----- 95 let r8: i64 = nx_etg_byzantine_outcome_agree(outcomes, 4, 0) 96 if r8 != NX_ETG_BYZ_NO_AGREEMENT { return 10 } 97 let r8b: i64 = nx_etg_byzantine_outcome_agree(outcomes, 4, 0 - 1) 98 if r8b != NX_ETG_BYZ_NO_AGREEMENT { return 11 } 99 100 // ----- T9 m_required > n ----- 101 let r9: i64 = nx_etg_byzantine_outcome_agree(outcomes, 4, 5) 102 if r9 != NX_ETG_BYZ_NO_AGREEMENT { return 12 } 103 104 // ----- T10 Counting helper audit confidence ----- 105 outcomes[0] = NX_ETG_OUTCOME_CONFIRMED 106 outcomes[1] = NX_ETG_OUTCOME_CONFIRMED 107 outcomes[2] = NX_ETG_OUTCOME_CONFIRMED 108 outcomes[3] = NX_ETG_OUTCOME_FALSIFIED 109 outcomes[4] = NX_ETG_OUTCOME_INCONCLUSIVE 110 let c_conf: i64 = nx_etg_byzantine_count_outcome(outcomes, 5, NX_ETG_OUTCOME_CONFIRMED) 111 if c_conf != 3 { return 20 } 112 let c_fal: i64 = nx_etg_byzantine_count_outcome(outcomes, 5, NX_ETG_OUTCOME_FALSIFIED) 113 if c_fal != 1 { return 21 } 114 let c_inc: i64 = nx_etg_byzantine_count_outcome(outcomes, 5, NX_ETG_OUTCOME_INCONCLUSIVE) 115 if c_inc != 1 { return 22 } 116 // Outcomes never voted for return 0. 117 let c_rec: i64 = nx_etg_byzantine_count_outcome(outcomes, 5, NX_ETG_OUTCOME_RECLAIMED) 118 if c_rec != 0 { return 23 } 119 // Count with n=0 returns 0 (no underflow). 120 let c_zero: i64 = nx_etg_byzantine_count_outcome(outcomes, 0, NX_ETG_OUTCOME_CONFIRMED) 121 if c_zero != 0 { return 24 } 122 123 return 0 124}