X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fkernel.cpp;h=7d8a66ad268f33ca4128af258ccc0ca468548a41;hb=a042ef41f2db5ec89154d82b5522dfb5dcad40d5;hp=4e653a440c995f5fff5a826ddaf183dcdd4d9c6a;hpb=126e51d5d96f8bc2c900df18af5827c279967dcc;p=novacoin.git diff --git a/src/kernel.cpp b/src/kernel.cpp index 4e653a4..7d8a66a 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -32,6 +32,7 @@ static std::map mapStakeModifierCheckpoints = (143990, 0x9c592c78u ) (149000, 0x48f2bdc4u ) (160000, 0x789df0f0u ) + (200000, 0x01ec1503u ) ; // Hard checkpoints of stake modifiers to ensure they are deterministic (testNet) @@ -437,51 +438,125 @@ void GetKernelMidstate(uint64_t nStakeModifier, uint32_t nBlockTime, uint32_t nT SHA256_Update(&ctx, (unsigned char*)&it[0], 8 + 16); } + +class ScanMidstateWorker +{ +public: + ScanMidstateWorker() + { } + ScanMidstateWorker(SHA256_CTX ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, uint32_t nIntervalBegin, uint32_t nIntervalEnd) + { + workerSolutions = vector >(); + + workerCtx = ctx; + this->nBits = nBits; + this->nInputTxTime = nInputTxTime; + this->nValueIn = nValueIn; + this->nIntervalBegin = nIntervalBegin; + this->nIntervalEnd = nIntervalEnd; + } + + void Do() + { + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); + + // Get maximum possible target to filter out the majority of obviously insufficient hashes + CBigNum bnMaxTargetPerCoinDay = bnTargetPerCoinDay * CBigNum(nValueIn) * nStakeMaxAge / COIN / (24 * 60 * 60); + uint256 maxTarget = bnMaxTargetPerCoinDay.getuint256(); + + SHA256_CTX ctx = workerCtx; + + // Search forward in time from the given timestamp + // Stopping search in case of shutting down + for (uint32_t nTimeTx=nIntervalBegin; nTimeTx maxTarget) + continue; + + CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / (24 * 60 * 60); + CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay; + + if (bnTargetProofOfStake >= CBigNum(hashProofOfStake)) + { + workerSolutions.push_back(std::pair(hashProofOfStake, nTimeTx)); + } + } + } + + vector > GetSolutions() + { + return workerSolutions; + } + +private: + SHA256_CTX workerCtx; + std::vector > workerSolutions; + + uint32_t nBits; + uint32_t nInputTxTime; + int64_t nValueIn; + uint32_t nIntervalBegin; + uint32_t nIntervalEnd; +}; + // Scan given midstate for solution -bool ScanMidstateForward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair &SearchInterval, std::pair &solution) +bool ScanMidstateForward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair &SearchInterval, std::vector > &solutions) { - CBigNum bnTargetPerCoinDay; - bnTargetPerCoinDay.SetCompact(nBits); + // TODO: custom threads amount - // Get maximum possible target to filter out the majority of obviously insufficient hashes - CBigNum bnMaxTargetPerCoinDay = bnTargetPerCoinDay * CBigNum(nValueIn) * nStakeMaxAge / COIN / (24 * 60 * 60); - uint256 maxTarget = bnMaxTargetPerCoinDay.getuint256(); + uint32_t nThreads = boost::thread::hardware_concurrency(); - SHA256_CTX ctxCopy = ctx; + uint32_t nBegin = SearchInterval.first; + uint32_t nEnd = SearchInterval.second; + uint32_t nPart = (nEnd - nBegin) / nThreads; - // Search forward in time from the given timestamp - // Stopping search in case of shutting down - for (uint32_t nTimeTx=SearchInterval.first; nTimeTx workerFnc = boost::bind(&ScanMidstateWorker::Do, &workers[i]); + group.create_thread(workerFnc); + } - // Skip if hash doesn't satisfy the maximum target - if (hashProofOfStake > maxTarget) - continue; + group.join_all(); + solutions.clear(); - CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / (24 * 60 * 60); - CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay; + for(size_t i = 0; i < nThreads; i++) + { + std::vector > ws = workers[i].GetSolutions(); + solutions.insert(solutions.end(), ws.begin(), ws.end()); + } - if (bnTargetProofOfStake >= CBigNum(hashProofOfStake)) - { - solution.first = hashProofOfStake; - solution.second = nTimeTx; + delete [] workers; - return true; - } + if (solutions.size() == 0) + { + // no solutions + return false; } - return false; + return true; } // Scan given midstate for solution @@ -577,7 +652,7 @@ uint32_t GetStakeModifierChecksum(const CBlockIndex* pindex) ss << pindex->nFlags << pindex->hashProofOfStake << pindex->nStakeModifier; uint256 hashChecksum = Hash(ss.begin(), ss.end()); hashChecksum >>= (256 - 32); - return hashChecksum.Get64(); + return static_cast(hashChecksum.Get64()); } // Check stake modifier hard checkpoints