- One-time difficulty reset to minimum for 17 blocks at activation height - Separate RandomX build dirs for linux/win64 cross-compilation - Add build target tracking to auto-clean on target switch - Automated win64 release packaging to release-win64/ - Add build artifacts to .gitignore - Miner memory diagnostics and large-page dataset fallback
4.8 KiB
4.8 KiB
Changelog: RandomX Validation Bug Fix
Summary
Fixes a critical exploit allowing miners on RandomX-based Hush Arrakis Chains (HACs) to bypass RandomX proof-of-work validation entirely. Adds proper RandomX solution verification to the block validation pipeline, fixes the miner's RandomX input construction, and introduces per-chain activation heights.
Bug Description
Three issues combined to allow the bypass:
CheckEquihashSolution()returnedtrueimmediately for non-Equihash chains, never verifying the RandomX solution stored innSolution.CheckProofOfWork()checked the standard SHA-256dGetHash()against the difficulty target instead of a RandomX hash, allowing miners to brute-force the cheap hash.- The miner passed
&randomxInput, sizeof randomxInput(the address and size of aCDataStreamstruct) torandomx_calculate_hash()instead of the actual serialized data, producing non-deterministic hashes.
A malicious miner could put arbitrary bytes in nSolution, iterate nonces until the standard header hash met the target, and the block would pass all validation — completely bypassing RandomX CPU-hardness.
Changes
src/primitives/block.h
- Added
CRandomXInputclass (modeled afterCEquihashInput) that serializes the block header includingnNoncebut excludingnSolution, providing deterministic and reproducible input for RandomX hashing.
src/hush_globals.h
- Added
int32_t ASSETCHAINS_RANDOMX_VALIDATION = -1global variable to hold the per-chain activation height (-1= disabled).
src/hush_defs.h
- Added
extern int32_t ASSETCHAINS_RANDOMX_VALIDATIONdeclaration.
src/pow.h
- Added declaration for
bool CheckRandomXSolution(const CBlockHeader *pblock, int32_t height). - Added declarations for
int GetRandomXInterval()andint GetRandomXBlockLag()(moved fromminer.cpp).
src/pow.cpp
- Added
#include "RandomX/src/randomx.h"and#include <mutex>. - Moved
GetRandomXInterval()andGetRandomXBlockLag()definitions here fromminer.cppso they are accessible from both the miner and the validator. - Implemented
CheckRandomXSolution():- Returns
trueimmediately for non-RandomX chains, pre-activation heights, and whenHUSH_LOADINGBLOCKS != 0. - Validates
nSolutionis exactlyRANDOMX_HASH_SIZE(32) bytes. - Derives the correct RandomX key for the given height (initial key from chain params, or block-hash key after rotation interval).
- Serializes the block header via
CRandomXInputinto aCDataStream. - Calls
randomx_calculate_hash()with the correct data pointer (&ss[0]) and size (ss.size()). - Compares the computed hash against
pblock->nSolution. - Caches the RandomX VM and cache between calls (protected by mutex), re-initializing only when the key changes.
- Returns
src/main.cpp
- In
CheckBlockHeader(): addedCheckRandomXSolution()call inside thefCheckPOWblock, after the existingCheckEquihashSolution()call. Invalid RandomX solutions are rejected withDoS(100).
src/hush_bitcoind.h
- Added
#include "pow.h". - In
hush_checkPOW(): addedCheckRandomXSolution()call after the existingCheckEquihashSolution()call.
src/miner.cpp
- Changed
GetRandomXInterval()andGetRandomXBlockLag()from inline definitions to forward declarations (definitions moved topow.cpp). - Fixed RandomX input construction in
RandomXMiner():- Uses
CRandomXInputto serialize the block header withoutnSolution(instead of serializing the entire block). - Passes
&randomxInput[0], randomxInput.size()torandomx_calculate_hash()(instead of&randomxInput, sizeof randomxInput).
- Uses
- Added
SetSkipRandomXValidation(true/false)aroundTestBlockValidity()to avoid double-validation OOM. - Added null-checks before
randomx_destroy_vm()to prevent double-free crashes.
src/hush_utils.h
- After
ASSETCHAINS_ALGOandSMART_CHAIN_SYMBOLare set during chain initialization, setsASSETCHAINS_RANDOMX_VALIDATIONper chain:DRAGONX:1(TBD: set to coordinated upgrade height)TUMIN:1(TBD: set to coordinated upgrade height)- All other RandomX HACs:
1(enforced from height 1) - Non-RandomX chains: remains
-1(disabled)
Activation Heights
| Chain | Height | Notes |
|---|---|---|
| DRAGONX | TBD | Existing chain, needs coordinated upgrade |
| TUMIN | TBD | Existing chain, needs coordinated upgrade |
| All other RandomX HACs | 1 | Enforced from genesis+1 |
Files Modified
| File | Lines Added | Lines Removed |
|---|---|---|
src/primitives/block.h |
~20 | 0 |
src/hush_globals.h |
1 | 0 |
src/hush_defs.h |
1 | 0 |
src/pow.h |
9 | 0 |
src/pow.cpp |
~105 | 0 |
src/main.cpp |
2 | 0 |
src/hush_bitcoind.h |
6 | 0 |
src/miner.cpp |
5 | 5 |
src/hush_utils.h |
10 | 0 |