| Item | ||
|---|---|---|
| ✅ | 1.1 — CXMSSSigner class XMSS key management: Generate, Sign, HaveKey, GetLeafIndex, GetXMSSKeys wallet/xmss_signer.h, wallet/xmss_signer.cpp | |
| ✅ | 1.2 — Wallet Signing Integration SignXMSS(), HaveXMSSKey(), GetXMSSPubKey() di SigningProvider. CreateXMSSSig() di sign.cpp script/signingprovider.h, script/sign.h, script/sign.cpp, wallet/wallet.h, wallet/wallet.cpp | |
| ✅ | 1.3 — Transaction Verification CheckXMSSSignature() di BaseSignatureChecker. SignTransactionXMSS() di wallet.cpp script/script.h, script/script.cpp, wallet/wallet.cpp | |
| ✅ | 1.4 — Makefile.am Updated xmss_signer.cpp/h, xmss_address.cpp, xmss_keystore.cpp, rpc/xmss.cpp ditambahkan ke build src/Makefile.am | |
| ✅ | 1.5 — Integration Tests 6/6 tests passed: keygen, sign/verify, wrong key, stateful signing, sig size test_xmss_core.c |
| Item | ||
|---|---|---|
| ✅ | 2.1 — Genesis XMSS Key Generated XMSS-SHA2_10_256 key pair. Private key disimpan di qnt_genesis_key.txt | |
| ✅ | 2.2 — Genesis Block Mined Hash: 5322eeb6160377b16f97e65fd0f67e06db246fe8072e8429215ad16644a6a7bb | |
| ✅ | 2.3 — Regtest Running 10+ blocks mined. Address prefix: qnr. Port: 29333 |
| Sub-phase | ||
|---|---|---|
| ✅ | 3a — Address Encoding Base58Check(0x60 || RIPEMD160(SHA256(xmss_pubkey64))). Mainnet prefix 'q' wallet/xmss_address.h, wallet/xmss_address.cpp | |
| ✅ | 3b — Keystore Persistence CXMSSKeyStore: import, export, sign, serialization wallet/xmss_keystore.h, wallet/xmss_keystore.cpp | |
| ✅ | 3c — RPC Commands getnewxmssaddress, listxmsskeys, getxmssaddressinfo, sendtoxmssaddress wallet/rpc/xmss.h, wallet/rpc/xmss.cpp commit: fe3d605 | |
| ✅ | 3d — PoUW Mining Integration XMSS key per block, pubkey di coinbase OP_RETURN, signature di scriptSig, re-verify PoW setelah sig insertion consensus/params.h, kernel/chainparams.cpp, validation.cpp, rpc/mining.cpp commit: b666498 | |
| ✅ | 3e — XMSS State Management Integration SaveState/LoadState/HasExhaustedKeys di CXMSSSigner. WriteXmssState/ReadXmssState di WalletBatch. State di-load saat wallet open, di-save setelah commit transaction. Anti-reuse protection untuk XMSS stateful signatures. wallet/xmss_state.h, wallet/xmss_signer.h, wallet/xmss_signer.cpp, wallet/wallet.cpp, wallet/walletdb.h, wallet/walletdb.cpp commit: e672298 |
| Item | ||
|---|---|---|
| ✅ | 4.1 — Self-Audit Checklist Review key generation, state persistence, signing flow, script engine, wallet keystore, transaction validation | |
| ✅ | 4.2 — Fix LOW issues Key exhausted check di Sign(), minimum sig length di interpreter | |
| ✅ | 4.3 — Audit Report AUDIT.md written. 2 MEDIUM + 3 LOW findings. No CRITICAL/HIGH. Overall PASS. |
| Item | ||
|---|---|---|
| ✅ | 5.1 — README.md Project overview, build guide, quick start, architecture diagram | |
| ✅ | 5.2 — Developer Docs RPC API reference, XMSS wallet guide, mining guide, testnet guide |
| Item | ||
|---|---|---|
| ⬜ | 6.1 — Public Testnet Launch Bitcointalk ANN, Reddit, Twitter/X, Discord, Telegram | |
| ✅ | 6.1b — Stratum Mining Server Multi-miner stratum proxy (stratum_server.py). Port 3333 (stratum), port 3334 (HTTP stats). Share tracking (accepted/rejected). Connects to bitcoind regtest RPC. Auto block generation on share threshold. Multiple simultaneous miner connections supported. stratum_server.py | |
| ✅ | 6.1c — XMSS Wallet: Send from XMSS Address sendfromxmssaddress RPC: send SNTI from XMSS address to any destination (legacy or XMSS). Supports fee subtraction and wallet comments. Register XMSS RPC methods in CRPCTable. Fixed fee estimation with -fallbackfee flag. wallet/rpc/xmss.cpp, wallet/rpc/xmss.h, wallet/rpc/wallet.cpp | |
| ✅ | 6.1d — P2XMSS Script Type (Native XMSS Output) Native P2XMSS script output: OP_XMSS_CHECKSIG with 64-byte pubkey. Added XMSSHash to CTxDestination variant. Updated Solver(), ExtractDestination(), GetScriptForDestination(), IsMine(). Wallet generates P2XMSS outputs for XMSS addresses. Tested: P2XMSS→Legacy, P2XMSS→P2XMSS ✅ addresstype.h, addresstype.cpp, script/solver.h, script/solver.cpp, key_io.cpp, wallet/rpc/xmss.cpp, wallet/scriptpubkeyman.cpp, wallet/xmss_signer.cpp | |
| 🔄 | 6.1e — Multi-Node Test (2 nodes, block propagation) Setup 2 nodes on same VPS (ports 29332/29333 and 29334/29335). Both nodes connected as peers. ISSUE: PoUW blocks cause 'mutated block' reject (bad-witness-nonce-size) because PoUW modifies coinbase after PoW. Both nodes need identical XMSS wallet state to validate. Known limitation — requires bypassing witness malleation check for regtest multi-node. Nodes connect and share headers but block bodies rejected. kernel/chainparams.cpp, bitcoin.conf | |
| 🔄 | 6.1f — DNS Seed / Hardcoded Seeds (Peer Discovery) Added hardcoded seed nodes for mainnet (port 9333), testnet (port 19333), regtest (port 29333). Seed: 104.234.26.7 (primary SNTI node). BIP155 serialized format. DNS seed names reserved: seed.qnt.io, testnet-seed.qnt.io. Build in progress. qnt_seeds.h, kernel/chainparams.cpp | |
| ⬜ | 6.2 — Team Page Founder, core contributors, advisors | |
| ⬜ | 6.3 — Exchange Listing Prep Target: Gate.io, MEXC, Bitget (Phase 1) |
| Item | ||
|---|---|---|
| ✅ | 6.5.1 — Official Genesis Block Mined Timestamp 1781545300 (15/Jun/2026). Message: "Assentian-PQE Genesis 15/Jun/2026 - NIST SP 800-208 XMSS - Quantum Era Begins" kernel/chainparams.cpp | |
| ✅ | 6.5.2 — Build System Fixes Resolved duplicate seed definitions (chainparamsseeds.h vs qnt_seeds.h), UniValue API mismatch (push_kv → pushKV), RescanFromTime signature, missing CWallet::AddXMSSKeyToKeystore / GetXMSSPubKey implementations kernel/chainparams.cpp, wallet/rpc/xmss.cpp, wallet/wallet.cpp | |
| ✅ | 6.5.3 — PQ-PoW End-to-End Validation 6 consecutive blocks mined on regtest, all with valid XMSS signature in coinbase witness + 64-byte pubkey in OP_RETURN. CheckPoUW() consensus enforcement confirmed — pouw_enabled: true throughout, zero rejected blocks | |
| ✅ | 6.5.4 — License & Documentation Consistency BSL-1.1 license added (→ GPL-2.0 in 2030). Whitepaper fixed: license MIT→BSL-1.1, P2P port 8333→9333, magic bytes QNTF→QUAN, halving 2,100,000→210,000 blocks LICENSE, WHITEPAPER.md | |
| ✅ | 6.5.5 — Public Infrastructure Live Dashboard, mining page, explorer, whitepaper.html, and /api/status all verified returning HTTP 200 via nginx reverse proxy. bitcoind + explorer running as systemd services with auto-restart |
| Item | ||
|---|---|---|
| ✅ | 6.6.1 — Testnet Launched on Official Genesis Migrated from regtest to testnet using the official 15/Jun/2026 genesis block. 6 consecutive PoUW blocks mined, ~2.5-3s per block (XMSS keygen + sign) | |
| ✅ | 6.6.2 — Key Lifecycle Documented Confirmed each block generates a fresh, single-use XMSS key (not reused across the 1024-signature capacity). Noted as a known design tradeoff: simpler and avoids index-reuse risk, but discards 1023 of 1024 available signatures per key and adds ~2-3s per block for keygen | |
| ✅ | 6.6.3 — Fixed CXMSSSigner::GetSecKeyForPubkey Method was referenced by exportxmsskey RPC but never declared or implemented, causing a linker error. Implemented as a lookup into the in-memory xmss_keys map, returning the serialized secret key wallet/xmss_signer.h, wallet/xmss_signer.cpp | |
| ✅ | 6.6.4 — Registered Missing RPC Commands importxmsskey and exportxmsskey were implemented but never added to the wallet RPC command table, so they returned "Method not found" despite compiling successfully wallet/rpc/wallet.cpp | |
| ✅ | 6.6.5 — End-to-End RPC Verification getnewxmssaddress and exportxmsskey tested live on testnet: address generated, key exported with full XMSS secret key structure (OID, index, seed, WOTS chains) returned correctly |
| Item | ||
|---|---|---|
| ✅ | 6.7.1 — Discovered PoUW was never actually enforced CheckPoUW() returned true unconditionally whenever nPoUWStartHeight > 0 (the production setting). The promised height-gated check in ContextualCheckBlock did not exist. Every prior block had a valid signature only because our own miner attached one out of habit — consensus never required it. | |
| ✅ | 6.7.2 — Implemented real height-gated PoUW enforcement Added nHeight and fCheckPOW parameters through CheckPoUW → ContextualCheckBlock, so the signature check now genuinely runs against the chain's actual height on every block submission validation.cpp | |
| ✅ | 6.7.3 — Fixed corrupted OP_RETURN pubkey format std::vector<uint8_t>(0x40) was misread as "push byte 0x40" but actually constructs a 64-element zero-filled vector, producing a 131-byte malformed script instead of the intended 66-byte OP_RETURN. Every block's embedded XMSS public key was corrupted as a result. rpc/mining.cpp | |
| ✅ | 6.7.4 — Found and fixed critical heap buffer overflow in XMSS Verify() The reference xmssmt_core_sign_open() writes into its output buffer at offset params.sig_bytes before copying the message to the front, but our wrapper allocated the buffer at only 32 bytes. Every single verification call overflowed the heap, corrupting the allocator and crashing the node intermittently a few allocations later. Root-caused with gdb + Valgrind (not guessed), confirmed via "Invalid read ... inside an unallocated block" trace pointing directly at the call site. xmss_bridge.cpp, xmss_state.h, pouw.h | |
| ✅ | 6.7.5 — Stress-tested fix with 30 consecutive blocks 20 blocks mined back-to-back with no crash (manual binary), followed by 10 more via the production systemd service — zero failures, zero restarts, confirming the fix holds under repeated real mining load |
| Item | ||
|---|---|---|
| ✅ | 6.8.1 — Audited all other XMSS sign/verify call sites Cross-checked every Sign() and Verify() implementation across xmss_bridge.cpp, xmss_state.h, wallet/xmss_state.h and the dead-code pouw.h for the same buffer-sizing pattern that caused Phase 6.7's heap overflow. Sign() output buffers were confirmed safe (generous fixed margins); Verify() in xmss_state.h and pouw.h were found to have the identical undersized output buffer bug and were fixed for consistency, even though pouw.h is not compiled into the build xmss_state.h, wallet/xmss_state.h, pouw.h | |
| ✅ | 6.8.2 — Stress test: 50 corrupted block resubmissions Took a valid block, corrupted random bytes inside the witness signature, and resubmitted it 50 times via submitblock. All were correctly handled as duplicates (SegWit witness data does not affect the legacy block hash used for header identity) — zero crashes, chain state unaffected. This confirmed network-input robustness but also revealed that witness malleation means a corrupted resubmission of an existing block never reaches CheckPoUW at all | |
| ✅ | 6.8.3 — Adversarial test: genuinely invalid signature on a fresh block Added a temporary, environment-variable-gated code path to deliberately flip one byte of a real XMSS signature before broadcast, producing a freshly-mined block (new hash, not a duplicate). Result: AcceptBlock rejected it with pouw-invalid-sig, the node did not crash, and the chain tip did not advance — direct proof that consensus genuinely rejects an invalid PoUW signature, not just a missing one. Test code was removed immediately after confirmation Log: "ERROR: AcceptBlock: pouw-invalid-sig, PoUW: XMSS signature verification failed" |
| Item | ||
|---|---|---|
| ✅ | 6.9.1 — Discovered every SNTI block violated BIP141 Stood up a second, fully independent node (separate process, separate datadir, separate ports) for the first time. Direct submitblock testing showed every block ever mined was rejected with bad-witness-nonce-size — the coinbase witness must be exactly one 32-byte reserved value per BIP141, but the 2500-byte XMSS signature was overwriting that slot entirely. Confirmed the mining node only accepted its own blocks due to its own validation path, not because the blocks were actually valid. | |
| ✅ | 6.9.2 — First fix attempt exposed a second, deeper problem Moving the signature to a coinbase OP_RETURN output fixed the BIP141 violation but reintroduced a circular hash dependency: adding the output changes the merkle root, which changes block.GetHash() — the very hash the signature was computed against. Diagnosed via targeted debug logging showing correct extraction but failed verification. | |
| ✅ | 6.9.3 — Redesigned PoUW signing around a stable preimage The signature now commits to a dedicated preimage hash (version, prevhash, time, bits, coinbase-without-signature txid, pubkey) computed and signed before the signature is attached anywhere. CheckPoUW() reconstructs the identical preimage by removing the signature output and rehashing, avoiding any dependency on the final block hash. rpc/mining.cpp, validation.cpp | |
| ✅ | 6.9.4 — Verified via direct submitblock between independent nodes Submitted 3 newly-mined blocks one at a time to a completely separate node process. All accepted. Resulting chain tip hash matched the mining node's tip exactly. | |
| ✅ | 6.9.5 — Verified via genuine automatic P2P relay Connected the two independent nodes via addnode, then mined 2 new blocks on node 1 with zero further manual intervention. Node 2's height and best-block-hash advanced automatically and matched exactly — the first time SNTI blocks have ever propagated across a real peer-to-peer connection rather than being validated by the node that mined them. |
| Item | ||
|---|---|---|
| ✅ | 6.10.1 — Chain reorganization verified Created a genuine fork: 2 blocks mined independently on node 1, 3 blocks mined independently on node 2. On connecting the nodes, node 1 automatically reorganized to node 2's longer (more-work) chain — old blocks correctly marked orphaned (confirmations: -1), both nodes remained stable with no crashes. | |
| ✅ | 6.10.2 — sendtoxmssaddress verified end-to-end Sent SNTI from a regular address to a freshly generated XMSS address, confirmed in a block, and verified the wallet correctly recognizes ownership (ismine: true) of the resulting XMSS output. | |
| ✅ | 6.10.3 — Discovered and fixed XMSS address encoding inconsistency The address shown by getnewxmssaddress did not match the address shown for the same funds in gettransaction after sendtoxmssaddress — same pubkey, two different address strings. Root cause: 8 XMSS wallet RPC commands hardcoded testnet=false when calling XMSSAddr::Encode/Decode regardless of the actual active chain, while the standard EncodeDestination() path correctly checked Params().IsTestChain(). Funds were never at risk (the wallet still recognized ownership via the underlying pubkey), but this kind of address mismatch is exactly the sort of thing that could make a user believe they sent funds to the wrong place. Fixed all 8 occurrences. wallet/rpc/xmss.cpp | |
| ✅ | 6.10.4 — Verified the fix directly Generated a new XMSS address, sent funds to it, and confirmed the address shown in the resulting transaction's details now matches the originally generated address exactly. |
| Item | ||
|---|---|---|
| ✅ | 6.11.1 — Fixed AddXMSSKeyToKeystore and getnewxmssaddress AddXMSSKeyToKeystore was a no-op stub from an earlier session (added only to satisfy a linker reference), and getnewxmssaddress never called it at all. Keys generated via getnewxmssaddress were therefore never registered with the ScriptPubKeyMan-level IsMine() check, so funds sent to them never appeared in listunspent. Funds were never at risk — a separate CXMSSSigner-based check still correctly reported ismine:true — but spending through the normal wallet flow was effectively blocked. Implemented the bridge and wired it into getnewxmssaddress. wallet/wallet.cpp, wallet/rpc/xmss.cpp | |
| ⚠ | 6.11.2 — Discovered a deeper architectural gap: XMSS only wired into the deprecated legacy wallet backend The fix above only takes effect for legacy (BDB) wallets via LegacyScriptPubKeyMan. The current binary is compiled without BDB support at all (legacy wallets cannot even be created), and the default/only wallet backend available — descriptor wallets (DescriptorScriptPubKeyMan) — has no XMSS integration whatsoever. Practical result: XMSS addresses can receive funds (confirmed on-chain, confirmed via getxmssaddressinfo), but spending those funds back out through the standard wallet flow does not work in the current build. sendfromxmssaddress does not fail loudly — it silently falls back to spending unrelated wallet UTXOs instead of the requested XMSS funds. This is a genuine architecture gap, not a quick fix: properly supporting spending requires integrating XMSS into DescriptorScriptPubKeyMan, which is a substantially different data model (descriptors + HD derivation vs. a simple per-script map). Flagged here as a hard blocker for any mainnet claim that XMSS wallet round-trips work end-to-end. | |
| ✅ | 6.11.3 — Difficulty retarget algorithm verified pow.cpp confirmed completely unmodified from upstream Bitcoin Core — no QNT-specific changes at all. DifficultyAdjustmentInterval() correctly computes 20,160 blocks (14 days) from nPowTargetTimespan/nPowTargetSpacing, independent of any other SNTI parameter. Numerically simulated CalculateNextWorkRequired's core formula across five scenarios (on-time, 2x fast, 2x slow, 10x fast, 10x slow) — difficulty scaled exactly as expected and the 4x adjustment-bound safety clamp engaged correctly at the extremes. | |
| ✅ | 6.11.4 — Found and fixed a 10x error in the halving schedule While verifying retarget math, discovered nSubsidyHalvingInterval = 210,000 blocks at 60s/block produces a halving every ~146 days (0.4 years), not the "~4 years" the whitepaper explicitly promises — and not even the "~2 years" an in-code comment separately and also-incorrectly claimed. Root cause: Bitcoin's 210,000-block interval assumes 600s/block; SNTI blocks are 10x faster (60s) but the block count was never scaled up to compensate. Fixed nSubsidyHalvingInterval to 2,100,000 for mainnet, testnet, and signet (10x), restoring the intended ~4-year halving cadence. Regtest's separate 150-block interval (intentionally fast for testing) was left untouched. kernel/chainparams.cpp |
| Item | ||
|---|---|---|
| ⬜ | 7.1 — Final Security Review All audit findings fixed, re-audit if needed | |
| ⬜ | 7.2 — Seed Nodes Deployed Minimum 3 seed nodes on different regions | |
| ⬜ | 7.3 — Genesis Block Final Real genesis timestamp, real XMSS key, difficulty calibrated | |
| ⬜ | 7.4 — Public Launch Mining opens, exchanges list, community activated |