diff --git a/src/main.cpp b/src/main.cpp index ea0045589..a045afce3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5140,6 +5140,26 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta } } + // Check Proof-of-Work difficulty for smart chains (HACs) + // Without this check, an attacker can submit blocks with arbitrary nBits + // (e.g., powLimit / diff=1) and they will be accepted, allowing the chain + // to be flooded with minimum-difficulty blocks. + // Only enforce above daaForkHeight to avoid consensus mismatch with early + // chain blocks that were mined by a different binary version. + if (!ishush3 && SMART_CHAIN_SYMBOL[0] != 0 && nHeight > daaForkHeight) { + unsigned int nNextWork = GetNextWorkRequired(pindexPrev, &block, consensusParams); + if (fDebug) { + LogPrintf("%s: HAC nbits height=%d expected=%lu actual=%lu\n", + __func__, nHeight, (unsigned long)nNextWork, (unsigned long)block.nBits); + } + if (block.nBits != nNextWork) { + return state.DoS(100, + error("%s: Incorrect diffbits for %s at height %d: expected %lu got %lu", + __func__, SMART_CHAIN_SYMBOL, nHeight, (unsigned long)nNextWork, (unsigned long)block.nBits), + REJECT_INVALID, "bad-diffbits"); + } + } + // Check timestamp against prev if (ASSETCHAINS_ADAPTIVEPOW <= 0 || nHeight < 30) { if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast() ) diff --git a/src/pow.cpp b/src/pow.cpp index eef5d4ff6..309a0831a 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -863,10 +863,17 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t // Check proof of work matches claimed amount if ( UintToArith256(hash = blkHeader.GetHash()) > bnTarget ) { - if ( HUSH_LOADINGBLOCKS != 0 ) - return true; + // During initial block loading/sync, skip PoW validation for blocks + // before RandomX validation height. After activation, always validate + // to prevent injection of blocks with fake PoW. + if ( HUSH_LOADINGBLOCKS != 0 ) { + if (ASSETCHAINS_ALGO == ASSETCHAINS_RANDOMX && ASSETCHAINS_RANDOMX_VALIDATION > 0 && height >= ASSETCHAINS_RANDOMX_VALIDATION) { + // Fall through to reject the block — do NOT skip validation after activation + } else { + return true; + } + } - /* if ( SMART_CHAIN_SYMBOL[0] != 0 || height > 792000 ) { if ( Params().NetworkIDString() != "regtest" ) @@ -886,7 +893,6 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t } return false; } - */ } /*for (i=31; i>=0; i--) fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);