diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 635121bdb..88f03fa47 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -62,11 +62,15 @@ const std::string CLIENT_NAME = GetArg("-clientname", "DragonX"); #endif //TODO: clean up this stuff -//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives. -#define GIT_ARCHIVE 1 +//! git archives get "#define GIT_ARCHIVE 1" substituted on the next line by export-subst. +//! Do NOT hardcode it: the BUILD_DESC chain below falls back to GIT_COMMIT_ID whenever +//! build.h carries no BUILD_DESC -- any build without git metadata, e.g. from a tarball -- +//! so a hardcoded id makes those binaries claim an identity that is not theirs. Until +//! 2026-08-21 this asserted Komodo commit a86845f3dc, dated Feb 2018, on every such build. +//! With it gone that case reports "-unk", which is honest and greppable. #ifdef GIT_ARCHIVE -#define GIT_COMMIT_ID "a86845f3dc" -#define GIT_COMMIT_DATE "Wed, 21 Feb 2018 16:15:11 +0200" +#define GIT_COMMIT_ID "$Format:%h$" +#define GIT_COMMIT_DATE "$Format:%cD$" #endif #define RENDER_BETA_STRING(num) "-beta" DO_STRINGIZE(num) diff --git a/src/main.cpp b/src/main.cpp index 1375ab064..c15049253 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5155,10 +5155,15 @@ int32_t hush_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height); // RAII: save+restore the thread-local RandomX-skip flag around the verify-once dedup in CheckBlock, // so it can never clobber the miner's own fSkipRandomXValidation (TestBlockValidity -> ConnectBlock // re-entry) nor leak TRUE on an exception thrown out of hush_checkPOW. +// `arm` is false on paths where CheckBlockHeader did NOT reach its own RandomX check, so the +// dedup can never suppress the only verification a block gets. struct ScopedRandomXSkip { bool prev; - ScopedRandomXSkip() : prev(GetSkipRandomXValidation()) { SetSkipRandomXValidation(true); } - ~ScopedRandomXSkip() { SetSkipRandomXValidation(prev); } + bool armed; + explicit ScopedRandomXSkip(bool arm) : prev(GetSkipRandomXValidation()), armed(arm) { + if (armed) SetSkipRandomXValidation(true); + } + ~ScopedRandomXSkip() { if (armed) SetSkipRandomXValidation(prev); } }; bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state, libzcash::ProofVerifier& verifier, @@ -5168,7 +5173,8 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C // These are checks that are independent of context. hash = block.GetHash(); // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader. - if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW)) + const bool fHeaderChecked = CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW); + if (!fHeaderChecked) { if ( *futureblockp == 0 ) { @@ -5196,7 +5202,11 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C // that dominates IBD). The scoped guard saves/restores the skip flag (never hardcodes false) // so the miner's own skip is preserved and nothing leaks on throw. Equihash + PoW-target in // hush_checkPOW still run. - ScopedRandomXSkip _rxskip; + // ARMED ONLY IF fHeaderChecked: CheckBlockHeader returns early -- BEFORE its RandomX + // check -- for a future-timestamped block (*futureblockp==1), and CheckBlock keeps + // going on that path. There hush_checkPOW is the ONLY RandomX verification, so + // arming unconditionally drops the check for that class of block. + ScopedRandomXSkip _rxskip(fHeaderChecked); if ( hush_checkPOW(1,(CBlock *)&block,height) < 0 ) return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW"); }