7 #include "kernel_worker.h"
13 #if defined(__i386__) || defined(__x86_64__)
14 #include <immintrin.h>
19 static const uint32_t block1_suffix[9] = { 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0x000000e0 };
21 static const uint32_t block2_suffix[8] = { 0x80000000, 0, 0, 0, 0, 0, 0, 0x00000100 };
23 // Sha256 initial state
24 static const uint32_t sha256_initial[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
26 extern "C" void sha256_transform(uint32_t *state, const uint32_t *block, int swap);
29 // 4-way kernel padding
30 static const uint32_t block1_suffix_4way[4 * 9] = {
31 0x80000000, 0x80000000, 0x80000000, 0x80000000,
39 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0
43 static const uint32_t block2_suffix_4way[4 * 8] = {
44 0x80000000, 0x80000000, 0x80000000, 0x80000000,
51 0x00000100, 0x00000100, 0x00000100, 0x00000100
54 extern "C" int sha256_use_4way();
55 extern "C" void sha256_init_4way(uint32_t *state);
56 extern "C" void sha256_transform_4way(uint32_t *state, const uint32_t *block, int swap);
57 bool fUse4Way = sha256_use_4way() != 0;
60 // 8-way kernel padding
61 static const uint32_t block1_suffix_8way[8 * 9] = {
62 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
63 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 0,
67 0, 0, 0, 0, 0, 0, 0, 0,
68 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0,
70 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0
74 static const uint32_t block2_suffix_8way[8 * 8] = {
75 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
76 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0,
82 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0
85 extern "C" int sha256_use_8way();
86 extern "C" void sha256_init_8way(uint32_t *state);
87 extern "C" void sha256_transform_8way(uint32_t *state, const uint32_t *block, int swap);
88 bool fUse8Way = sha256_use_8way() != 0;
90 inline void copyrow8_swap32(uint32_t *to, uint32_t *from)
92 // There are no AVX2 CPUs without SSSE3 support, so we don't need any conditions here.
93 __m128i mask = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
94 _mm_storeu_si128((__m128i *)&to[0], _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)&from[0]), mask));
95 _mm_storeu_si128((__m128i *)&to[4], _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)&from[4]), mask));
99 #if defined(__i386__) || defined(__x86_64__)
100 extern "C" int sha256_use_ssse3();
101 bool fUseSSSE3 = sha256_use_ssse3() != 0;
103 inline void copyrow4_swap32(uint32_t *to, uint32_t *from)
107 for (int i = 0; i < 4; i++)
108 to[i] = __builtin_bswap32(from[i]);
112 __m128i mask = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
113 _mm_storeu_si128((__m128i *)&to[0], _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)&from[0]), mask));
117 inline void copyrow4_swap32(uint32_t *to, uint32_t *from)
119 for (int i = 0; i < 4; i++)
120 to[i] = __builtin_bswap32(from[i]);
125 KernelWorker::KernelWorker(unsigned char *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, uint32_t nIntervalBegin, uint32_t nIntervalEnd)
126 : kernel(kernel), nBits(nBits), nInputTxTime(nInputTxTime), bnValueIn(nValueIn), nIntervalBegin(nIntervalBegin), nIntervalEnd(nIntervalEnd)
128 solutions = vector<std::pair<uint256,uint32_t> >();
133 void KernelWorker::Do_8way()
135 SetThreadPriority(THREAD_PRIORITY_LOWEST);
137 // Compute maximum possible target to filter out majority of obviously insufficient hashes
138 CBigNum bnTargetPerCoinDay;
139 bnTargetPerCoinDay.SetCompact(nBits);
140 uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256();
142 uint32_t blocks1[8 * 16] __attribute__((aligned(16)));
143 uint32_t blocks2[8 * 16] __attribute__((aligned(16)));
144 uint32_t candidates[8 * 8] __attribute__((aligned(16)));
146 vector<uint32_t> vRow = vector<uint32_t>(8);
147 uint32_t *pnKernel = (uint32_t *) kernel;
149 for(int i = 0; i < 7; i++)
151 fill(vRow.begin(), vRow.end(), pnKernel[i]);
152 copyrow8_swap32(&blocks1[i*8], &vRow[0]);
155 memcpy(&blocks1[56], &block1_suffix_8way[0], 36*8); // sha256 padding
156 memcpy(&blocks2[64], &block2_suffix_8way[0], 32*8);
159 uint32_t nTimeStamps[8];
161 // Search forward in time from the given timestamp
162 // Stopping search in case of shutting down
163 for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx +=8)
165 sha256_init_8way(blocks2);
166 sha256_init_8way(candidates);
168 nTimeStamps[0] = nTimeTx;
169 nTimeStamps[1] = nTimeTx+1;
170 nTimeStamps[2] = nTimeTx+2;
171 nTimeStamps[3] = nTimeTx+3;
172 nTimeStamps[4] = nTimeTx+4;
173 nTimeStamps[5] = nTimeTx+5;
174 nTimeStamps[6] = nTimeTx+6;
175 nTimeStamps[7] = nTimeTx+7;
177 copyrow8_swap32(&blocks1[24], &nTimeStamps[0]); // Kernel timestamps
178 sha256_transform_8way(&blocks2[0], &blocks1[0], 0); // first hashing
179 sha256_transform_8way(&candidates[0], &blocks2[0], 0); // second hashing
180 copyrow8_swap32(&nHashes[0], &candidates[56]);
182 for(int nResult = 0; nResult < 8; nResult++)
184 if (nHashes[nResult] <= nMaxTarget32) // Possible hit
186 uint256 nHashProofOfStake = 0;
187 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
189 for (int i = 0; i < 7; i++)
190 pnHashProofOfStake[i] = __builtin_bswap32(candidates[(i*8) + nResult]);
191 pnHashProofOfStake[7] = nHashes[nResult];
193 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeStamps[nResult]) / COIN / nOneDay;
194 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
196 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
197 solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeStamps[nResult]));
204 void KernelWorker::Do_4way()
206 SetThreadPriority(THREAD_PRIORITY_LOWEST);
208 // Compute maximum possible target to filter out majority of obviously insufficient hashes
209 CBigNum bnTargetPerCoinDay;
210 bnTargetPerCoinDay.SetCompact(nBits);
211 uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256();
213 uint32_t blocks1[4 * 16] __attribute__((aligned(16)));
214 uint32_t blocks2[4 * 16] __attribute__((aligned(16)));
215 uint32_t candidates[4 * 8] __attribute__((aligned(16)));
217 vector<uint32_t> vRow = vector<uint32_t>(4);
218 uint32_t *pnKernel = (uint32_t *) kernel;
220 for(int i = 0; i < 7; i++)
222 fill(vRow.begin(), vRow.end(), pnKernel[i]);
223 copyrow4_swap32(&blocks1[i*4], &vRow[0]);
226 memcpy(&blocks1[28], &block1_suffix_4way[0], 36*4); // sha256 padding
227 memcpy(&blocks2[32], &block2_suffix_4way[0], 32*4);
230 uint32_t nTimeStamps[4];
232 // Search forward in time from the given timestamp
233 // Stopping search in case of shutting down
234 for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx +=4)
236 sha256_init_4way(blocks2);
237 sha256_init_4way(candidates);
239 nTimeStamps[0] = nTimeTx;
240 nTimeStamps[1] = nTimeTx+1;
241 nTimeStamps[2] = nTimeTx+2;
242 nTimeStamps[3] = nTimeTx+3;
244 copyrow4_swap32(&blocks1[24], &nTimeStamps[0]); // Kernel timestamps
245 sha256_transform_4way(&blocks2[0], &blocks1[0], 0); // first hashing
246 sha256_transform_4way(&candidates[0], &blocks2[0], 0); // second hashing
247 copyrow4_swap32(&nHashes[0], &candidates[28]);
249 for(int nResult = 0; nResult < 4; nResult++)
251 if (nHashes[nResult] <= nMaxTarget32) // Possible hit
253 uint256 nHashProofOfStake = 0;
254 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
256 for (int i = 0; i < 7; i++)
257 pnHashProofOfStake[i] = __builtin_bswap32(candidates[(i*4) + nResult]);
258 pnHashProofOfStake[7] = nHashes[nResult];
260 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeStamps[nResult]) / COIN / nOneDay;
261 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
263 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
264 solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeStamps[nResult]));
271 void KernelWorker::Do_generic()
273 SetThreadPriority(THREAD_PRIORITY_LOWEST);
275 // Compute maximum possible target to filter out majority of obviously insufficient hashes
276 CBigNum bnTargetPerCoinDay;
277 bnTargetPerCoinDay.SetCompact(nBits);
278 uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256();
280 #if !defined(USE_ASM) || defined(__i386__)
281 SHA256_CTX ctx, workerCtx;
282 // Init new sha256 context and update it
283 // with first 24 bytes of kernel
285 SHA256_Update(&ctx, kernel, 8 + 16);
286 workerCtx = ctx; // save context
288 // Sha256 result buffer
289 uint32_t hashProofOfStake[8];
290 uint256 *pnHashProofOfStake = (uint256 *)&hashProofOfStake;
292 // Search forward in time from the given timestamp
293 // Stopping search in case of shutting down
294 for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx++)
296 // Complete first hashing iteration
298 SHA256_Update(&ctx, (unsigned char*)&nTimeTx, 4);
299 SHA256_Final((unsigned char*)&hash1, &ctx);
304 // Finally, calculate kernel hash
305 SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
307 // Skip if hash doesn't satisfy the maximum target
308 if (hashProofOfStake[7] > nMaxTarget32)
311 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
312 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
314 if (bnTargetProofOfStake >= CBigNum(*pnHashProofOfStake))
315 solutions.push_back(std::pair<uint256,uint32_t>(*pnHashProofOfStake, nTimeTx));
318 uint32_t block1[16] __attribute__((aligned(16)));
319 uint32_t block2[16] __attribute__((aligned(16)));
320 uint32_t candidate[8] __attribute__((aligned(16)));
322 memcpy(&block1[7], &block1_suffix[0], 36); // sha256 padding
323 memcpy(&block2[8], &block2_suffix[0], 32);
325 uint32_t *pnKernel = (uint32_t *) kernel;
327 for (int i = 0; i < 6; i++)
328 block1[i] = __builtin_bswap32(pnKernel[i]);
330 // Search forward in time from the given timestamp
331 // Stopping search in case of shutting down
332 for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx++)
334 memcpy(&block2[0], &sha256_initial[0], 32);
335 memcpy(&candidate[0], &sha256_initial[0], 32);
337 block1[6] = __builtin_bswap32(nTimeTx);
339 sha256_transform(&block2[0], &block1[0], 0); // first hashing
340 sha256_transform(&candidate[0], &block2[0], 0); // second hashing
342 uint32_t nHash7 = __builtin_bswap32(candidate[7]);
344 // Skip if hash doesn't satisfy the maximum target
345 if (nHash7 > nMaxTarget32)
348 uint256 nHashProofOfStake;
349 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
351 for (int i = 0; i < 7; i++)
352 pnHashProofOfStake[i] = __builtin_bswap32(candidate[i]);
353 pnHashProofOfStake[7] = nHash7;
355 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
356 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
358 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
359 solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeTx));
364 void KernelWorker::Do()
368 if (false && fUse8Way) // disable for now
384 vector<pair<uint256,uint32_t> >& KernelWorker::GetSolutions()
389 // Scan given kernel for solutions
390 bool ScanKernelBackward(unsigned char *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::pair<uint256, uint32_t> &solution)
392 CBigNum bnTargetPerCoinDay;
393 bnTargetPerCoinDay.SetCompact(nBits);
395 CBigNum bnValueIn(nValueIn);
397 // Get maximum possible target to filter out the majority of obviously insufficient hashes
398 uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256();
403 if (false && fUse8Way) // AVX2 CPU
405 uint32_t blocks1[8 * 16] __attribute__((aligned(16)));
406 uint32_t blocks2[8 * 16] __attribute__((aligned(16)));
407 uint32_t candidates[8 * 8] __attribute__((aligned(16)));
409 vector<uint32_t> vRow = vector<uint32_t>(8);
410 uint32_t *pnKernel = (uint32_t *) kernel;
412 for(int i = 0; i < 7; i++)
414 fill(vRow.begin(), vRow.end(), pnKernel[i]);
415 copyrow8_swap32(&blocks1[i*8], &vRow[0]);
418 memcpy(&blocks1[56], &block1_suffix_8way[0], 36*8); // sha256 padding
419 memcpy(&blocks2[64], &block2_suffix_8way[0], 32*8);
422 uint32_t nTimeStamps[8];
424 // Search forward in time from the given timestamp
425 // Stopping search in case of shutting down
426 for (uint32_t nTimeTx=SearchInterval.first, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<SearchInterval.second && !fShutdown; nTimeTx -=8)
428 sha256_init_8way(blocks2);
429 sha256_init_8way(candidates);
431 nTimeStamps[0] = nTimeTx;
432 nTimeStamps[1] = nTimeTx-1;
433 nTimeStamps[2] = nTimeTx-2;
434 nTimeStamps[3] = nTimeTx-3;
435 nTimeStamps[4] = nTimeTx-4;
436 nTimeStamps[5] = nTimeTx-5;
437 nTimeStamps[6] = nTimeTx-6;
438 nTimeStamps[7] = nTimeTx-7;
440 copyrow8_swap32(&blocks1[24], &nTimeStamps[0]); // Kernel timestamps
441 sha256_transform_8way(&blocks2[0], &blocks1[0], 0); // first hashing
442 sha256_transform_8way(&candidates[0], &blocks2[0], 0); // second hashing
443 copyrow8_swap32(&nHashes[0], &candidates[56]);
445 for(int nResult = 0; nResult < 8; nResult++)
447 if (nHashes[nResult] <= nMaxTarget32) // Possible hit
449 uint256 nHashProofOfStake = 0;
450 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
452 for (int i = 0; i < 7; i++)
453 pnHashProofOfStake[i] = __builtin_bswap32(candidates[(i*8) + nResult]);
454 pnHashProofOfStake[7] = nHashes[nResult];
456 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeStamps[nResult]) / COIN / nOneDay;
457 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
459 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
461 solution.first = nHashProofOfStake;
462 solution.second = nTimeStamps[nResult];
472 if (fUse4Way) // SSE2 or Neon CPU
474 uint32_t blocks1[4 * 16] __attribute__((aligned(16)));
475 uint32_t blocks2[4 * 16] __attribute__((aligned(16)));
476 uint32_t candidates[4 * 8] __attribute__((aligned(16)));
478 vector<uint32_t> vRow = vector<uint32_t>(4);
479 uint32_t *pnKernel = (uint32_t *) kernel;
481 for(int i = 0; i < 7; i++)
483 fill(vRow.begin(), vRow.end(), pnKernel[i]);
484 copyrow4_swap32(&blocks1[i*4], &vRow[0]);
487 memcpy(&blocks1[28], &block1_suffix_4way[0], 36*4); // sha256 padding
488 memcpy(&blocks2[32], &block2_suffix_4way[0], 32*4);
491 uint32_t nTimeStamps[4];
493 // Search forward in time from the given timestamp
494 // Stopping search in case of shutting down
495 for (uint32_t nTimeTx=SearchInterval.first, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<SearchInterval.second && !fShutdown; nTimeTx -=4)
497 sha256_init_4way(blocks2);
498 sha256_init_4way(candidates);
500 nTimeStamps[0] = nTimeTx;
501 nTimeStamps[1] = nTimeTx-1;
502 nTimeStamps[2] = nTimeTx-2;
503 nTimeStamps[3] = nTimeTx-3;
505 copyrow4_swap32(&blocks1[24], &nTimeStamps[0]); // Kernel timestamps
506 sha256_transform_4way(&blocks2[0], &blocks1[0], 0); // first hashing
507 sha256_transform_4way(&candidates[0], &blocks2[0], 0); // second hashing
508 copyrow4_swap32(&nHashes[0], &candidates[28]);
510 for(int nResult = 0; nResult < 4; nResult++)
512 if (nHashes[nResult] <= nMaxTarget32) // Possible hit
514 uint256 nHashProofOfStake = 0;
515 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
517 for (int i = 0; i < 7; i++)
518 pnHashProofOfStake[i] = __builtin_bswap32(candidates[(i*4) + nResult]);
519 pnHashProofOfStake[7] = nHashes[nResult];
521 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeStamps[nResult]) / COIN / nOneDay;
522 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
524 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
526 solution.first = nHashProofOfStake;
527 solution.second = nTimeStamps[nResult];
539 #if !defined(USE_ASM) || defined(__i386__)
540 SHA256_CTX ctx, workerCtx;
541 // Init new sha256 context and update it
542 // with first 24 bytes of kernel
544 SHA256_Update(&ctx, kernel, 8 + 16);
545 workerCtx = ctx; // save context
547 // Search backward in time from the given timestamp
548 // Stopping search in case of shutting down
549 for (uint32_t nTimeTx=SearchInterval.first; nTimeTx>SearchInterval.second && !fShutdown; nTimeTx--)
551 // Complete first hashing iteration
553 SHA256_Update(&ctx, (unsigned char*)&nTimeTx, 4);
554 SHA256_Final((unsigned char*)&hash1, &ctx);
559 // Finally, calculate kernel hash
560 uint256 hashProofOfStake;
561 SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
563 // Skip if hash doesn't satisfy the maximum target
564 if (hashProofOfStake > nMaxTarget)
567 CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
568 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
570 if (bnTargetProofOfStake >= CBigNum(hashProofOfStake))
572 solution.first = hashProofOfStake;
573 solution.second = nTimeTx;
579 uint32_t block1[16] __attribute__((aligned(16)));
580 uint32_t block2[16] __attribute__((aligned(16)));
581 uint32_t candidate[8] __attribute__((aligned(16)));
583 memcpy(&block1[7], &block1_suffix[0], 36); // sha256 padding
584 memcpy(&block2[8], &block2_suffix[0], 32);
586 uint32_t *pnKernel = (uint32_t *) kernel;
588 for (int i = 0; i < 6; i++)
589 block1[i] = __builtin_bswap32(pnKernel[i]);
591 // Search forward in time from the given timestamp
592 // Stopping search in case of shutting down
593 for (uint32_t nTimeTx=SearchInterval.first, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<SearchInterval.second && !fShutdown; nTimeTx--)
595 memcpy(&block2[0], &sha256_initial[0], 32);
596 memcpy(&candidate[0], &sha256_initial[0], 32);
598 block1[6] = __builtin_bswap32(nTimeTx);
600 sha256_transform(&block2[0], &block1[0], 0); // first hashing
601 sha256_transform(&candidate[0], &block2[0], 0); // second hashing
603 uint32_t nHash7 = __builtin_bswap32(candidate[7]);
605 // Skip if hash doesn't satisfy the maximum target
606 if (nHash7 > nMaxTarget32)
609 uint256 nHashProofOfStake;
610 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
612 for (int i = 0; i < 7; i++)
613 pnHashProofOfStake[i] = __builtin_bswap32(candidate[i]);
614 pnHashProofOfStake[7] = nHash7;
616 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
617 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
619 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
621 solution.first = nHashProofOfStake;
622 solution.second = nTimeTx;