Skip to content

Commit e0e29bb

Browse files
AIQnetLabclaude
andcommitted
fix: weak-subjectivity cold-join - genesis/pin-rooted lineage walk, QC-only macroblocks
- verify the snapshot anchor via an ascending N-2 macroblock lineage walk rooted in the embedded genesis keys / a binary WS pin (hash + previous_hash chain); closes the circular-committee cold-join trust hole - reject None-QC macroblocks so "stored => QC-verified" holds (closes the lineage forge); remove the dead loose commit/reveal validation path - snapshot completeness: reject Format-B snapshots for consensus joiners, add a vrf_pk completeness contract, and rebuild derived indices fail-closed BEFORE finality adoption - fork-recovery keeps the in-memory state reset (reconcile); drop the harmful WS prune clamp - spread anchor/macroblock fetch across the VRF committee + node-global serve ceiling - warm and 5-node genesis paths are inert at WS pin=(0,zeros) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3a2d0eb commit e0e29bb

4 files changed

Lines changed: 376 additions & 616 deletions

File tree

development/qnet-integration/src/genesis_constants.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,21 @@ pub const GENESIS_CONSENSUS_PKS: &[(&str, &str)] = &[
3737
("genesis_node_005", "906bcfc96772992169471746a317a3006ba20c839b5b3f9c8ae18b0acdfd7a6e8a0133cc19c9c608e61c9a99caba2750afa86e2159d0d4de54eea609d9aee8e4373d5add14d2727afd49ac4e46f12b748bcf746b5f73b07ae064542b76722dbce1da10a3cebc97d30fe99fe929c568f0af4652587d2a32f52f13530754daebb810c70c7881191532cc77c3117b33aa2a6e33791f836bed74b6d8666ba65692838e7ed79e9aabf75c151f363cd4b8785743aa82c36a2831ac82b20828a29b5ecad16b39003d0309aee7cf451ee54f23d7285262d6a28570b19b68fb984bfbf1b9e6d5dae6c232ff0f19321aa1fcf3edbe7e84033b00604c4324f3615e2719203e0ce3cb5b17c80faa67bc3bd217d5c26962f75541bfcf18ffee1fa8944013992949a27d3eb508533a0c2068bf4bfd7d7fa95805ace4dad52ad84b574a19f5a91a7de5238cb72668714156017348bb673768ddd2ce634e7f019ba865f1b52346bc572eeee3a96fb36132e7d37082cba9a3f7eb001401be216dddad56fb8a0bf449a912378b564d3123806ddbbbdda80119fdb8223873f6fcfc7a864e008153abea2cad57a2bff011a058ea2fcd74976fa8aade5e9736a328acb163d077b633cf96d97130fedc806b44f2de0233cf5571c975abea5bb0993d909afbc0392aaf2a691e27fb23dc550a36bb4619a5326a0970c3c50534a33832a576490f60faaa1082aabfb8079def5793852f985f41fa65e8991562bfd615075a437054ed238a79570cdd5149564ddfa492e3f852c826162712b6e863edf38cfc218e3a978c0bb5f4ac5b1ae361b1e5f02f32c0be5809fc450f270ab0559de0f1130210d0ee9fb314c83a0b84837160dcf64fe49b82950a5c55ca9977a93b7c835b18c27ff5c8eb453c99aaa5fc498c45bb8237b7a2241bb9d48b0e3642924f40474dcd5d5ab2bb9cb7326165001edcdab59e234ee60e32be4f469cb625844f8028db638ba9a9fc58b4c3347095016d0e63d7dc35306ab37be45460160f34c2bed5cda73997fc80e0902580606a4c536b5e085e6017f623960b30066272c5370ad3ebec393ca9b038bbb3b8159feded8ed01c27d669d513c9a899beb4d2265ee4ac00c3e529fb004431dd221b4274bfbe56059e73f6f3901bfcd57352b60f0f7a838b8413c45a72fc1c9369ae03a95dc37e5e36297bed91c7ad20bc0be7b59b727ffa046cc57aadd2e7da0ec304b512e73d1b707b6a60edf3d3db4222a7265cdab6d071fbd7b012fd4d45ef59771f7dab7f4d178a2b6e05110408cf93e0ee57db4693c29ebd3d2ba27a2b52075106c4996f9bd9993b836cd227a098a1a11552ae7db3a4d40a9c090e4c0c2841baa816c53deebdd6a901018425dfb14b0e07f428b07f38ffd55828a621e4525a930d6bd74e64d594b85bcabaf6abfada1734b36c7acfa7c477eb2314617d19f51e345466aaa382c52b3f1d72b029ecfef62f6d6e487ed6ce7915cf9f767d12044147152ad81236bcb0ae3887e6856b2c954f2692252f927e5c6eadb1862ee79c07ff95fc9cf539a8bece9583bf138ba22e12a8edb8731f522728b718cb0e52b4ba3bc684e59260d98810b6fcc6ccaacf60ce321c8e42f7b3e5b1092bd842de1493309cbf54d8881bee8629365f7cd8524ed89121d27343e1908f3ca517628be4352376216af3cf6b5a3af8c9d977fa4af9baf8cd2b95e37f66349fa3298b84c101afbc2c8d87db159e1a9347e36faee9520756f4b033c0c6a2a4307743883f7f608d4584294dde8926533c147affa0e2a620b5a3e5c716d6cfe0345763d6311f2089136abfe8dc1b812571a5eecd176958da06b117e133b93873709d66a9fb00e83576610e65e721022096790922fcb01702fee7d93d743fa7ec41f78daacaa174312354f22c3cdbef2938f7b9a59a268a4dbdb42de7285084d617f4b26e1c1e7ed373af35f270b6e04eabc5f6ac8702011ab551801c901a94ea6f7a2ae97d666bd056296ce7ec70f8f40699e559f91d6db3ad77502437b4e724628edb0c6eae30ef7a85cd3204e5cb612430691889bb49a96a6d95993815b3c320bf5c0054e0821bda4e2df4a06db0dfe753ccd10a55c49dcc772ea01f2110b7989f403451ceef5b97d2152f0e0e8a542032fa0bce2cd4b120aab4d2cf58d12b20f5ee3ba1fada05cebe880ae839e927a13f15a708b7cfe4557c70899d008720801826281cfed56c338e64dd9f43a93071b7b38cec2be00cd6d2b32923a21aab82958c39bfe56650e899bfb7ab033bbfeb3821da0ab09bcfda83f3760512bb24d9f0908130ccb2f97faa84f9bf77dd50e38eac2d18f25a049b1a3b21d06e252f2952b26a7a5d0b99dce73035c99dade288ebb719503ec9b0c6f3857471099102660958254d5dcd0c64efe90df19a4ae49f14c2c5991d551b146ee6b604467c9b196832382be398cae8d9bd994fc9f7393232ea75fa3d009ed17cdcb1706284806bf716aff72777cc6dd1835bb11e22f46e5f110714e5456e9ccc905d7943bb7e8f4fbc44ef4bfa642aabf33d603f8e36ea2ac77040e9597154429e29aad769b6cd06d763b53d403d655e6f5cbfdd318b2550d42ec212625819380a39e476f945a6c6b991911b021b420acc411bbb903d700fcd5ee5525de6dbc99f2905875d0a23bd5e71602edb939670734d96865f589d5a89d33da61827e8df71bec84db8a750ffb35545065c6769d50dbd8b2e32b189c0980485e0276beeace1a418bcb4674503"),
3838
];
3939

40-
/// Weak-subjectivity checkpoint (macroblock index, MacroBlock::hash()) — same binary-embedded
41-
/// trust model as GENESIS_CONSENSUS_PKS: pinned per release, rotated only by a new binary.
42-
/// verify_v2_macroblock re-verifies QCs only for index >= WS index; the anchor lineage walk only
43-
/// needs to reach back to WS, not all the way to genesis (keeps cold-join fast on a mature chain
44-
/// where each macroblock QC verify is up to 1000 post-quantum opens). FRESH genesis launch:
45-
/// (0, [0u8;32]) → INERT: the lineage already starts at genesis (index 0, no checkpoint_qc), so the
46-
/// `index < ws`/`index == ws` branches never fire and behaviour is identical to no checkpoint.
40+
/// Weak-subjectivity checkpoint = (macroblock index, MacroBlock::hash()) — same binary-embedded trust
41+
/// model as GENESIS_CONSENSUS_PKS: the cold-join inductive ROOT, pinned per release, rotated only by a
42+
/// new binary (NEVER an operator env flag — consensus-safety param). FORMAT: index = height/90; the
43+
/// hash is MacroBlock::hash() (SHA3-256 of height‖timestamp‖previous_hash‖state_root‖micro_blocks),
44+
/// which EXCLUDES consensus_data ⇒ byte-stable across nodes, independent of QC bytes. HOW IT IS USED
45+
/// (verify_snapshot_consensus_binding + verify_v2_macroblock): a cold-joiner re-verifies the macroblock
46+
/// lineage UP from this pin — the pinned macroblock is trusted by hash, its predecessor by the
47+
/// previous_hash chain (the two N-2 committee sources), then each higher macroblock's 2f+1 QC verifies
48+
/// against the committee from its already-verified N-2. The walk reaches back only to WS, not genesis,
49+
/// so cold-join stays fast on a mature chain (each QC verify is up to 1000 post-quantum opens). BUMP
50+
/// DISCIPLINE: rotate to a recently-finalized macroblock every release so (tip - WS) stays under the
51+
/// MAX_WS_WALK_MB bound (storage.rs) — beyond it cold-join is refused, forcing a binary upgrade (this
52+
/// is the weak-subjectivity period; a stale pin must NOT silently widen the trust window). FRESH genesis
53+
/// launch: (0, [0u8;32]) → INERT: the walk starts at genesis (index 1, genesis static committee) and the
54+
/// pin branches (gated on index>0) never fire, so behaviour is identical to no checkpoint.
4755
pub const WS_CHECKPOINT: (u64, [u8; 32]) = (0, [0u8; 32]);
4856

4957
/// Trusted weak-subjectivity macroblock index (lower bound of QC re-verification). 0 on fresh genesis.

0 commit comments

Comments
 (0)