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()