7 #include "kernel_worker.h"
11 KernelWorker::KernelWorker(uint8_t *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, uint32_t nIntervalBegin, uint32_t nIntervalEnd)
12 : kernel(kernel), nBits(nBits), nInputTxTime(nInputTxTime), bnValueIn(nValueIn), nIntervalBegin(nIntervalBegin), nIntervalEnd(nIntervalEnd)
14 solutions = vector<pair<uint256,uint32_t> >();
17 void KernelWorker::Do_generic()
19 SetThreadPriority(THREAD_PRIORITY_LOWEST);
21 // Compute maximum possible target to filter out majority of obviously insufficient hashes
22 CBigNum bnTargetPerCoinDay;
23 bnTargetPerCoinDay.SetCompact(nBits);
24 auto nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256();
26 SHA256_CTX ctx, workerCtx;
27 // Init new sha256 context and update it
28 // with first 24 bytes of kernel
30 SHA256_Update(&ctx, kernel, 8 + 16);
31 workerCtx = ctx; // save context
33 // Sha256 result buffer
34 uint32_t hashProofOfStake[8];
35 auto pnHashProofOfStake = (uint256 *)&hashProofOfStake;
37 // Search forward in time from the given timestamp
38 // Stopping search in case of shutting down
39 for (auto nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx++)
41 // Complete first hashing iteration
43 SHA256_Update(&ctx, (unsigned char*)&nTimeTx, 4);
44 SHA256_Final(hash1.begin(), &ctx);
49 // Finally, calculate kernel hash
50 SHA256(hash1.begin(), sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
52 // Skip if hash doesn't satisfy the maximum target
53 if (hashProofOfStake[7] > nMaxTarget32)
56 auto bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
57 auto bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
59 if (bnTargetProofOfStake >= CBigNum(*pnHashProofOfStake))
60 solutions.push_back(make_pair(*pnHashProofOfStake, nTimeTx));
64 void KernelWorker::Do()
69 vector<pair<uint256,uint32_t> >& KernelWorker::GetSolutions()
74 // Scan given kernel for solutions
76 bool ScanKernelBackward(uint8_t *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, pair<uint32_t, uint32_t> &SearchInterval, pair<uint256, uint32_t> &solution)
78 uint256 nTargetPerCoinDay;
79 nTargetPerCoinDay.SetCompact(nBits);
81 // Get maximum possible target to filter out the majority of obviously insufficient hashes
82 auto nMaxTarget = nTargetPerCoinDay * (uint64_t)nValueIn * (uint64_t)nStakeMaxAge / (uint64_t)COIN / (uint64_t)nOneDay;
84 SHA256_CTX ctx, workerCtx;
85 // Init new sha256 context and update it
86 // with first 24 bytes of kernel
88 SHA256_Update(&ctx, kernel, 8 + 16);
89 workerCtx = ctx; // save context
91 // Search backward in time from the given timestamp
92 // Stopping search in case of shutting down
93 for (auto nTimeTx=SearchInterval.first; nTimeTx>SearchInterval.second && !fShutdown; nTimeTx--)
95 // Complete first hashing iteration
97 SHA256_Update(&ctx, (unsigned char*)&nTimeTx, 4);
98 SHA256_Final(hash1.begin(), &ctx);
103 // Finally, calculate kernel hash
104 uint256 hashProofOfStake;
105 SHA256(hash1.begin(), hashProofOfStake.size(), hashProofOfStake.begin());
107 // Skip if hash doesn't satisfy the maximum target
108 if (hashProofOfStake > nMaxTarget)
111 auto nCoinDayWeight = uint256(nValueIn) * (uint64_t)GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / (uint64_t)COIN / (uint64_t)nOneDay; // TODO: Stop using signed types for value, time, weight and so on, because all these casts are really stupid.
112 auto nTargetProofOfStake = nCoinDayWeight * nTargetPerCoinDay;
114 if (nTargetProofOfStake >= hashProofOfStake)
116 solution = { hashProofOfStake, nTimeTx };