diff --git a/src/hash.h b/src/hash.h index 485655a00..128680f0f 100644 --- a/src/hash.h +++ b/src/hash.h @@ -225,6 +225,55 @@ public: } }; +/** An optimized and dangerous writer stream (for serialization) that computes a 256-bit Verus hash without the normal + * safety checks. Do not try to write more than 1488 bytes to this hash writer. */ +class CVerusMiningHashWriter +{ +public: + union hwBuf { + unsigned char charBuf[1488]; + int32_t i32a[522]; + hwBuf() + { + memset(charBuf, 0, sizeof(charBuf)); + } + }; + hwBuf buf; + int nPos; + int nType; + int nVersion; + + CVerusMiningHashWriter(int nTypeIn, int nVersionIn, int pos = 0) : buf() + { + nPos = pos; + nType = nTypeIn; + nVersion = nVersionIn; + } + + CVerusMiningHashWriter& write(const char *pch, size_t size) { + if ((nPos + size) <= sizeof(buf.charBuf)) + { + memcpy(&(buf.charBuf[nPos]), pch, size); + nPos += size; + } + return (*this); + } + + // does not invalidate the object for modification and further hashing + uint256 GetHash() { + uint256 result; + CVerusHash::Hash((unsigned char*)&result, buf.charBuf, nPos); + return result; + } + + template + CVerusMiningHashWriter& operator<<(const T& obj) { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } +}; + /** Compute the 256-bit hash of an object's serialization. */ template uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) @@ -243,6 +292,15 @@ uint256 SerializeVerusHash(const T& obj, int nType=SER_GETHASH, int nVersion=PRO return ss.GetHash(); } +/** Compute the 256-bit Verus hash of an object's serialization. */ +template +uint256 SerializeVerusMiningHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) +{ + CVerusMiningHashWriter ss = CVerusMiningHashWriter(nType, nVersion); + ss << obj; + return ss.GetHash(); +} + unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector& vDataToHash); void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]); diff --git a/src/main.cpp b/src/main.cpp index 48d319f7f..bef0d296d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -910,7 +910,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight) { // if time locks are on, ensure that this coin base is time locked exactly as it should be - if ((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) + if (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) || (nHeight >= 31680) && komodo_ac_block_subsidy(nHeight) >= ASSETCHAINS_TIMELOCKGTE) { CScriptID scriptHash; diff --git a/src/miner.cpp b/src/miner.cpp index ef41e6db0..63b8a9b93 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1148,17 +1148,20 @@ void static BitcoinMiner_noeq() { arith_uint256 arNonce = UintToArith256(pblock->nNonce); + CVerusMiningHashWriter ss = CVerusMiningHashWriter(SER_GETHASH, PROTOCOL_VERSION); + ss << *((CBlockHeader *)pblock); + // for speed check 16 mega hash at a time for (int i = 0; i < 0x1000000; i++) { solutionTargetChecks.increment(); // Update nNonce - *((unsigned char *)&(pblock->nNonce)) = i & 0xff; - *(((unsigned char *)&(pblock->nNonce))+1) = (i >> 8) & 0xff; - *(((unsigned char *)&(pblock->nNonce))+2) = (i >> 16) & 0xff; + ss.buf.charBuf[108] = *((unsigned char *)&(pblock->nNonce)) = i & 0xff; + ss.buf.charBuf[109] = *(((unsigned char *)&(pblock->nNonce))+1) = (i >> 8) & 0xff; + ss.buf.charBuf[110] = *(((unsigned char *)&(pblock->nNonce))+2) = (i >> 16) & 0xff; - if ( UintToArith256(pblock->GetHash()) <= hashTarget ) + if ( UintToArith256(ss.GetHash()) <= hashTarget ) { SetThreadPriority(THREAD_PRIORITY_NORMAL); diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index fc937ec3d..3d8b080c0 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -27,6 +27,12 @@ uint256 CBlockHeader::GetVerusHash() const return SerializeVerusHash(*this); } +uint256 CBlockHeader::GetVerusMiningHash() const +{ + // no check for genesis block and use the optimized hash + return SerializeVerusMiningHash(*this); +} + void CBlockHeader::SetSHA256DHash() { CBlockHeader::hashFunction = &CBlockHeader::GetSHA256DHash; diff --git a/src/primitives/block.h b/src/primitives/block.h index 6a45648f3..97e9c1c07 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -84,6 +84,8 @@ public: uint256 GetVerusHash() const; static void SetVerusHash(); + uint256 GetVerusMiningHash() const; + int64_t GetBlockTime() const { return (int64_t)nTime; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8a8e30763..e1cca1878 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1053,7 +1053,7 @@ int32_t CWallet::VerusStakeTransaction(CMutableTransaction &txNew, uint32_t &bnT if (!VerusSelectStakeOutput(hashResult, stakeSource, voutNum, tipindex->nHeight + 1, target) || !Solver(stakeSource.vout[voutNum].scriptPubKey, whichType, vSolutions)) { - LogPrintf("No eligible staking transaction found"); + LogPrintf("No eligible staking transaction found\n"); return 0; }