You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Crosslink's PoW block hash is computed as sha256d(header ‖ solution_varint ‖ solution ‖ fat_pointer_to_bft_block) — the BFT fat pointer is inside the hash preimage. Standard Equihash stratum miners (Antminer Z11/Z15 etc.) compute sha256d(header ‖ solution) in firmware and cannot be taught about the fat pointer. The hash an ASIC checks against the target is therefore a different number than the hash the node validates, so every ASIC "block find" is effectively a random 256-bit value vs. the real target → ~100% rejection with DifficultyFilter.
The submitted blocks deserialize fine (fat pointer serialization is correct); they fail purely on the difficulty check because the true hash was never the thing the miner was grinding against the target.
Related
This same property explains part of the internal miner's stale-submit rejections (Miner: reject stale internal solver submissions #39 territory): the fat pointer changes with BFT state between template and submit, which changes the block hash and thus whether it still meets the target.
Suggested protocol-level fix
Commit the fat pointer inside the hashed 140-byte header instead of appending it to the hash preimage — e.g. fold a hash of fat_pointer_to_bft_block into hashBlockCommitments. Then standard stratum firmware grinds over a header that already commits to the BFT data, and off-the-shelf Equihash ASICs work unmodified.
Workaround we're running (pool-side)
Patched s-nomp to recompute the TRUE hash (sha256d(header‖sol‖fp)) for every share and only submitblock when that clears the network target ("lottery mode"). This stops the invalid submissions and does produce genuinely valid blocks at low network difficulty, but wastes almost all of the ASIC's hashrate — it's a stopgap, not a fix. Happy to share the patch and the hash-verification test script.
Summary
Crosslink's PoW block hash is computed as
sha256d(header ‖ solution_varint ‖ solution ‖ fat_pointer_to_bft_block)— the BFT fat pointer is inside the hash preimage. Standard Equihash stratum miners (Antminer Z11/Z15 etc.) computesha256d(header ‖ solution)in firmware and cannot be taught about the fat pointer. The hash an ASIC checks against the target is therefore a different number than the hash the node validates, so every ASIC "block find" is effectively a random 256-bit value vs. the real target → ~100% rejection withDifficultyFilter.Reproduction (byte-exact, any accepted block)
Using accepted block 235728 (
getblock "235728" 0, testnet CLT0, s2v9 + PR29/42):0d56cb86...007befd4cf9fc519acda09bc09813b072f610761a0dcbea6dee99ed75aa705a9(fat pointer parsed as: 44-byte vote prefix ‖ u16 LE sig count ‖ N × (32-byte pub_key ‖ 64-byte vote_signature))
Observed failure
Z11 → patched s-nomp (fat-pointer-aware block serialization) →
submitblock. Shares that clear the stratum target are submitted and all rejected:The submitted blocks deserialize fine (fat pointer serialization is correct); they fail purely on the difficulty check because the true hash was never the thing the miner was grinding against the target.
Related
Suggested protocol-level fix
Commit the fat pointer inside the hashed 140-byte header instead of appending it to the hash preimage — e.g. fold a hash of
fat_pointer_to_bft_blockintohashBlockCommitments. Then standard stratum firmware grinds over a header that already commits to the BFT data, and off-the-shelf Equihash ASICs work unmodified.Workaround we're running (pool-side)
Patched s-nomp to recompute the TRUE hash (
sha256d(header‖sol‖fp)) for every share and onlysubmitblockwhen that clears the network target ("lottery mode"). This stops the invalid submissions and does produce genuinely valid blocks at low network difficulty, but wastes almost all of the ASIC's hashrate — it's a stopgap, not a fix. Happy to share the patch and the hash-verification test script.