X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fkernel.cpp;h=79d8e58096fd0aeaac830ebc7037a615a6be023b;hb=144f5f66954f40fc37431916917a0f1d7d034533;hp=a7df10e58d989373fbceef86c0e04f7ff88e43e3;hpb=9417ff30cae6ffffd1c4fc4f4b1a81551f04dbc5;p=novacoin.git diff --git a/src/kernel.cpp b/src/kernel.cpp index a7df10e..79d8e58 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,121 @@ void GetKernelMidstate(uint64_t nStakeModifier, uint32_t nBlockTime, uint32_t nT SHA256_Update(&ctx, (unsigned char*)&it[0], 8 + 16); } -// 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) + +class ScanMidstateWorker { - CBigNum bnTargetPerCoinDay; - bnTargetPerCoinDay.SetCompact(nBits); +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; + } - // 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(); + void Do() + { + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); - SHA256_CTX ctxCopy = ctx; + // 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(); - // Search forward in time from the given timestamp - // Stopping search in case of shutting down - for (uint32_t nTimeTx=SearchInterval.first; nTimeTx maxTarget) - continue; + // Finally, calculate kernel hash + uint256 hashProofOfStake; + SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake); - CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / (24 * 60 * 60); - CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay; - if (bnTargetProofOfStake >= CBigNum(hashProofOfStake)) - { - solution.first = hashProofOfStake; - solution.second = nTimeTx; + // Skip if hash doesn't satisfy the maximum target + if (hashProofOfStake > maxTarget) + continue; - return true; + 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)); + } } } - return false; + 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::vector > &solutions) +{ + // TODO: custom threads amount + + uint32_t nBegin = SearchInterval.first; + uint32_t nEnd = SearchInterval.second; + uint32_t nPart = (nEnd - nBegin) / 4; + + ScanMidstateWorker workers[4]; + + boost::thread_group group; + for(int i = 0; i<4; i++) + { + uint32_t nIntervalBegin = nBegin + nPart * i; + uint32_t nIntervalEnd = nBegin + nPart * (i + 1); + + workers[i] = ScanMidstateWorker(ctx, nBits, nInputTxTime, nValueIn, nIntervalBegin, nIntervalEnd); + + boost::function workerFnc = boost::bind(&ScanMidstateWorker::Do, &workers[i]); + group.create_thread(workerFnc); + } + + group.join_all(); + solutions.clear(); + + for(int i = 0; i<4; i++) + { + std::vector > ws = workers[i].GetSolutions(); + solutions.insert(solutions.end(), ws.begin(), ws.end()); + } + + if (solutions.size() == 0) + { + // no solutions + return false; + } + + return true; } // Scan given midstate for solution