Fix RandomX validation exploit: verify nSolution contains valid RandomX hash

- Add CheckRandomXSolution() to validate RandomX PoW in nSolution field
- Add ASSETCHAINS_RANDOMX_VALIDATION activation height per chain
  (DRAGONX: 2838976, TUMIN: 1200, others: height 1)
- Add CRandomXInput serializer for deterministic RandomX hash input
- Fix CheckProofOfWork() to properly reject invalid PoW (was missing
  SMART_CHAIN_SYMBOL check, allowing bypass)
- Call CheckRandomXSolution() in hush_checkPOW and CheckBlockHeader

Without this fix, attackers could submit blocks with invalid RandomX
hashes that passed validation, as CheckProofOfWork returned early
during block loading and the nSolution field was never verified.
This commit is contained in:
2026-03-03 17:28:49 -06:00
parent 7e1b5701a6
commit d6ba1aed4e
9 changed files with 197 additions and 0 deletions
+12
View File
@@ -1902,6 +1902,18 @@ void hush_args(char *argv0)
strncpy(SMART_CHAIN_SYMBOL,name.c_str(),sizeof(SMART_CHAIN_SYMBOL)-1);
const bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false;
// Set RandomX validation activation height per chain
if (ASSETCHAINS_ALGO == ASSETCHAINS_RANDOMX) {
if (strncmp(SMART_CHAIN_SYMBOL, "DRAGONX", 7) == 0) {
ASSETCHAINS_RANDOMX_VALIDATION = 2838976; // TBD: set to coordinated upgrade height
} else if (strncmp(SMART_CHAIN_SYMBOL, "TUMIN", 5) == 0) {
ASSETCHAINS_RANDOMX_VALIDATION = 1200; // TBD: set to coordinated upgrade height
} else {
ASSETCHAINS_RANDOMX_VALIDATION = 1; // all other RandomX HACs: enforce from height 1
}
printf("ASSETCHAINS_RANDOMX_VALIDATION set to %d for %s\n", ASSETCHAINS_RANDOMX_VALIDATION, SMART_CHAIN_SYMBOL);
}
ASSETCHAINS_LASTERA = GetArg("-ac_eras", 1);
if(ishush3) {
ASSETCHAINS_LASTERA = 3;