RPC scaninput: Add 8way implementation, but disable it for now.
[novacoin.git] / src / kernel.cpp
1 // Copyright (c) 2012-2013 The PPCoin developers
2 // Copyright (c) 2013-2015 The Novacoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 // Distributed under the MIT/X11 software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7
8 #include <boost/assign/list_of.hpp>
9
10 #include "kernel.h"
11 #include "txdb.h"
12
13 extern unsigned int nStakeMaxAge;
14 extern unsigned int nStakeTargetSpacing;
15
16 using namespace std;
17
18
19 // Protocol switch time for fixed kernel modifier interval
20 unsigned int nModifierSwitchTime  = 1413763200;    // Mon, 20 Oct 2014 00:00:00 GMT
21 unsigned int nModifierTestSwitchTime = 1397520000; // Tue, 15 Apr 2014 00:00:00 GMT
22
23 // Note: user must upgrade before the protocol switch deadline, otherwise it's required to
24 //   re-download the blockchain. The timestamp of upgrade is recorded in the blockchain 
25 //   database.
26 unsigned int nModifierUpgradeTime = 0;
27
28 typedef std::map<int, unsigned int> MapModifierCheckpoints;
29
30 // Hard checkpoints of stake modifiers to ensure they are deterministic
31 static std::map<int, unsigned int> mapStakeModifierCheckpoints =
32     boost::assign::map_list_of
33         ( 0, 0x0e00670bu )
34         ( 12661, 0x5d84115du )
35         (143990, 0x9c592c78u )
36         (149000, 0x48f2bdc4u )
37         (160000, 0x789df0f0u )
38         (200000, 0x01ec1503u )
39     ;
40
41 // Hard checkpoints of stake modifiers to ensure they are deterministic (testNet)
42 static std::map<int, unsigned int> mapStakeModifierCheckpointsTestNet =
43     boost::assign::map_list_of
44         ( 0, 0x0e00670bu )
45     ;
46
47 // Pregenerated entropy bits table (from genesis to #9689)
48 //
49 // Bits are packed into array of 256 bit integers:
50 //
51 // * array index calculated as nHeight / 256
52 // * position of bit is calculated as nHeight & 0xFF.
53 //
54 const uint256 entropyStore[] = {
55     uint256("0x4555b4dcc1d690ddd9b810c90c66e82b18bf4f43cc887246c418383ec120a5ab"),
56     uint256("0xaa6d1198412fa77608addf6549c9198a22155e8afd7a9ded6179f6b7cfc66b0c"),
57     uint256("0x9442fabfa4116fb14a9769c2eea003845a1f5c3a0260f36b497d68f3a3cd4078"),
58     uint256("0x0e769042a9a98e42388195d699574b822d06515f7053ad884c53d7ee059f05b1"),
59     uint256("0x7005aac20baf70251aebfe3f1b95987d83ef1e3e6963de8fed601d4dd07bf7cf"),
60     uint256("0x58952c5c3de188f2e33c38d3f53d7bf44f9bc545a4289d266696273fa821be66"),
61     uint256("0x50b6c2ed780c08aaec3f7665b1b6004206243e3866456fc910b83b52d07eeb63"),
62     uint256("0x563841eefca85ba3384986c58100408ae3f1ba2ac727e1ac910ce154a06c702f"),
63     uint256("0x79275b03938b3e27a9b01a7f7953c6c487c58355f5d4169accfbb800213ffd13"),
64     uint256("0xd783f2538b3ed18f135af90adc687c5646d93aeaeaabc6667be94f7aa0a2d366"),
65     uint256("0xb441d0c175c40c8e88b09d88ea008af79cbed2d28219427d2e72fda682974db8"),
66     uint256("0x3204c43bd41f2e19628af3b0c9aca3db15bca4c8705d51056e7b17a319c04715"),
67     uint256("0x7e80e6ab7857d8f2f261a0a49c783bd800b365b8c9b85cc0e13f73904b0dcaa9"),
68     uint256("0xefaaee60ed82d2ad145c0e347941fdb131eb8fd289a45eef07121a93f283c5f1"),
69     uint256("0x3efc86e4334da332c1fd4c12513c40cff689f3efdc7f9913230822adacdda4f9"),
70     uint256("0xf0d6b8f38599a017fa35d1fbbf9ef51eca5ebc5b286aadba40c4c3e1d9bace0c"),
71     uint256("0x286a67f27323486036a0a92d35382fc8963c0c00bad331723318b4b9fdb2b56e"),
72     uint256("0xecbfaaa6567c54f08c4d5bd0118a2d7b58740f42cbfc73aa1536c1f5f76de87c"),
73     uint256("0xf9a4de1c5c46520de5aaf10d3796cf0e27ddce98b3398357f5726a949664e308"),
74     uint256("0xd75e6c4dc4be08401e3478d2467d9ab96a62af4f255c04a82c41af0de0a487bb"),
75     uint256("0x1a82c3bc6ad6047294c16571b5e2b7316c97bf8813e7da15798b9820d67e39f2"),
76     uint256("0xb49be0080de564e01829ded7e7971979565a741c5975dc9978dcc020192d396c"),
77     uint256("0x0d8eed113be67663b5a15a0625a9b49792b5ea59c005c4f405914877acab7000"),
78     uint256("0x8f9d46e2bc05a218ffa942965b747056197d393b097085523640cd59e07fe7c7"),
79     uint256("0x7a63ab40bc7f40ac2ebe9ede438d97b45fa6ed6f8419016da8d5f7a670111dda"),
80     uint256("0x63fbcc080448c43d6cf915c958314feff7a95a52ba43a68c05fc281d3a522d25"),
81     uint256("0xf834cf824c326d3ea861ea1e85dc3289265e37045981e28208e7344a7f8081d7"),
82     uint256("0xb4edc22ec98cc49b2f5af5bae3f52f5e6058280f74f2c432c2dd89ae49acceb8"),
83     uint256("0x0fe596037dcf81bf5c64f39755261c404ed088af5c8c31dd7549b6657ee92365"),
84     uint256("0xbbad51a0aeba254b01d18c328de9e932b9b859b61e622c325d64e2211b5e413d"),
85     uint256("0xabf0194cc787be938bc51c7fdf1cae4ec79e65ebab8fa8b8f40541c44ef384b0"),
86     uint256("0x83bc12d6fdbd3e854cb91c4ca7dfba3c38e8714121af88c8a8abdb33e5002438"),
87     uint256("0x71a2513026cabaedcbe55aeb6dc8049e5b763a3f54f10c33dd333624f764b38c"),
88     uint256("0xee6725632ff5c025dff6a18cd059875dcae20f399b03bccba13d9d5fcf6d9d9a"),
89     uint256("0xa168a2741d1e7e50cc74b79f695c25ffd3576e6bd61353c2a20e569fd63b2dac"),
90     uint256("0x6e462d2a87bfde9398b6747f94a8ed6a01e4d96c5b4372df5c910c106c48bd13"),
91     uint256("0x8eeb696181957c4b22434028990f49cb30006827c73860e77e2eecf5c38be99d"),
92     uint256("0x3188aaa65877b166f05cdc48f55b1f77a7d6fb221c395596d990ae5647e9ba96")
93 };
94
95 // Whether the given block is subject to new modifier protocol
96 bool IsFixedModifierInterval(unsigned int nTimeBlock)
97 {
98     return (nTimeBlock >= (fTestNet? nModifierTestSwitchTime : nModifierSwitchTime));
99 }
100
101 // Get the last stake modifier and its generation time from a given block
102 static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64_t& nStakeModifier, int64_t& nModifierTime)
103 {
104     if (!pindex)
105         return error("GetLastStakeModifier: null pindex");
106     while (pindex && pindex->pprev && !pindex->GeneratedStakeModifier())
107         pindex = pindex->pprev;
108     if (!pindex->GeneratedStakeModifier())
109         return error("GetLastStakeModifier: no generation at genesis block");
110     nStakeModifier = pindex->nStakeModifier;
111     nModifierTime = pindex->GetBlockTime();
112     return true;
113 }
114
115 // Get selection interval section (in seconds)
116 static int64_t GetStakeModifierSelectionIntervalSection(int nSection)
117 {
118     assert (nSection >= 0 && nSection < 64);
119     return (nModifierInterval * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1))));
120 }
121
122 // Get stake modifier selection interval (in seconds)
123 static int64_t GetStakeModifierSelectionInterval()
124 {
125     int64_t nSelectionInterval = 0;
126     for (int nSection=0; nSection<64; nSection++)
127         nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection);
128     return nSelectionInterval;
129 }
130
131 // select a block from the candidate blocks in vSortedByTimestamp, excluding
132 // already selected blocks in vSelectedBlocks, and with timestamp up to
133 // nSelectionIntervalStop.
134 static bool SelectBlockFromCandidates(vector<pair<int64_t, uint256> >& vSortedByTimestamp, map<uint256, const CBlockIndex*>& mapSelectedBlocks,
135     int64_t nSelectionIntervalStop, uint64_t nStakeModifierPrev, const CBlockIndex** pindexSelected)
136 {
137     bool fSelected = false;
138     uint256 hashBest = 0;
139     *pindexSelected = (const CBlockIndex*) 0;
140     BOOST_FOREACH(const PAIRTYPE(int64_t, uint256)& item, vSortedByTimestamp)
141     {
142         if (!mapBlockIndex.count(item.second))
143             return error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString().c_str());
144         const CBlockIndex* pindex = mapBlockIndex[item.second];
145         if (fSelected && pindex->GetBlockTime() > nSelectionIntervalStop)
146             break;
147         if (mapSelectedBlocks.count(pindex->GetBlockHash()) > 0)
148             continue;
149         // compute the selection hash by hashing its proof-hash and the
150         // previous proof-of-stake modifier
151         uint256 hashProof = pindex->IsProofOfStake()? pindex->hashProofOfStake : pindex->GetBlockHash();
152         CDataStream ss(SER_GETHASH, 0);
153         ss << hashProof << nStakeModifierPrev;
154         uint256 hashSelection = Hash(ss.begin(), ss.end());
155         // the selection hash is divided by 2**32 so that proof-of-stake block
156         // is always favored over proof-of-work block. this is to preserve
157         // the energy efficiency property
158         if (pindex->IsProofOfStake())
159             hashSelection >>= 32;
160         if (fSelected && hashSelection < hashBest)
161         {
162             hashBest = hashSelection;
163             *pindexSelected = (const CBlockIndex*) pindex;
164         }
165         else if (!fSelected)
166         {
167             fSelected = true;
168             hashBest = hashSelection;
169             *pindexSelected = (const CBlockIndex*) pindex;
170         }
171     }
172     if (fDebug && GetBoolArg("-printstakemodifier"))
173         printf("SelectBlockFromCandidates: selection hash=%s\n", hashBest.ToString().c_str());
174     return fSelected;
175 }
176
177 // Stake Modifier (hash modifier of proof-of-stake):
178 // The purpose of stake modifier is to prevent a txout (coin) owner from
179 // computing future proof-of-stake generated by this txout at the time
180 // of transaction confirmation. To meet kernel protocol, the txout
181 // must hash with a future stake modifier to generate the proof.
182 // Stake modifier consists of bits each of which is contributed from a
183 // selected block of a given block group in the past.
184 // The selection of a block is based on a hash of the block's proof-hash and
185 // the previous stake modifier.
186 // Stake modifier is recomputed at a fixed time interval instead of every 
187 // block. This is to make it difficult for an attacker to gain control of
188 // additional bits in the stake modifier, even after generating a chain of
189 // blocks.
190 bool ComputeNextStakeModifier(const CBlockIndex* pindexCurrent, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier)
191 {
192     nStakeModifier = 0;
193     fGeneratedStakeModifier = false;
194     const CBlockIndex* pindexPrev = pindexCurrent->pprev;
195     if (!pindexPrev)
196     {
197         fGeneratedStakeModifier = true;
198         return true;  // genesis block's modifier is 0
199     }
200
201     // First find current stake modifier and its generation block time
202     // if it's not old enough, return the same stake modifier
203     int64_t nModifierTime = 0;
204     if (!GetLastStakeModifier(pindexPrev, nStakeModifier, nModifierTime))
205         return error("ComputeNextStakeModifier: unable to get last modifier");
206     if (fDebug)
207     {
208         printf("ComputeNextStakeModifier: prev modifier=0x%016" PRIx64 " time=%s epoch=%u\n", nStakeModifier, DateTimeStrFormat(nModifierTime).c_str(), (unsigned int)nModifierTime);
209     }
210     if (nModifierTime / nModifierInterval >= pindexPrev->GetBlockTime() / nModifierInterval)
211     {
212         if (fDebug)
213         {
214             printf("ComputeNextStakeModifier: no new interval keep current modifier: pindexPrev nHeight=%d nTime=%u\n", pindexPrev->nHeight, (unsigned int)pindexPrev->GetBlockTime());
215         }
216         return true;
217     }
218     if (nModifierTime / nModifierInterval >= pindexCurrent->GetBlockTime() / nModifierInterval)
219     {
220         // fixed interval protocol requires current block timestamp also be in a different modifier interval
221         if (IsFixedModifierInterval(pindexCurrent->nTime))
222         {
223             if (fDebug)
224             {
225                 printf("ComputeNextStakeModifier: no new interval keep current modifier: pindexCurrent nHeight=%d nTime=%u\n", pindexCurrent->nHeight, (unsigned int)pindexCurrent->GetBlockTime());
226             }
227             return true;
228         }
229         else
230         {
231             if (fDebug)
232             {
233                 printf("ComputeNextStakeModifier: old modifier at block %s not meeting fixed modifier interval: pindexCurrent nHeight=%d nTime=%u\n", pindexCurrent->GetBlockHash().ToString().c_str(), pindexCurrent->nHeight, (unsigned int)pindexCurrent->GetBlockTime());
234             }
235         }
236     }
237
238     // Sort candidate blocks by timestamp
239     vector<pair<int64_t, uint256> > vSortedByTimestamp;
240     vSortedByTimestamp.reserve(64 * nModifierInterval / nStakeTargetSpacing);
241     int64_t nSelectionInterval = GetStakeModifierSelectionInterval();
242     int64_t nSelectionIntervalStart = (pindexPrev->GetBlockTime() / nModifierInterval) * nModifierInterval - nSelectionInterval;
243     const CBlockIndex* pindex = pindexPrev;
244     while (pindex && pindex->GetBlockTime() >= nSelectionIntervalStart)
245     {
246         vSortedByTimestamp.push_back(make_pair(pindex->GetBlockTime(), pindex->GetBlockHash()));
247         pindex = pindex->pprev;
248     }
249     int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0;
250     reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end());
251     sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end());
252
253     // Select 64 blocks from candidate blocks to generate stake modifier
254     uint64_t nStakeModifierNew = 0;
255     int64_t nSelectionIntervalStop = nSelectionIntervalStart;
256     map<uint256, const CBlockIndex*> mapSelectedBlocks;
257     for (int nRound=0; nRound<min(64, (int)vSortedByTimestamp.size()); nRound++)
258     {
259         // add an interval section to the current selection round
260         nSelectionIntervalStop += GetStakeModifierSelectionIntervalSection(nRound);
261         // select a block from the candidates of current round
262         if (!SelectBlockFromCandidates(vSortedByTimestamp, mapSelectedBlocks, nSelectionIntervalStop, nStakeModifier, &pindex))
263             return error("ComputeNextStakeModifier: unable to select block at round %d", nRound);
264         // write the entropy bit of the selected block
265         nStakeModifierNew |= (((uint64_t)pindex->GetStakeEntropyBit()) << nRound);
266         // add the selected block from candidates to selected list
267         mapSelectedBlocks.insert(make_pair(pindex->GetBlockHash(), pindex));
268         if (fDebug && GetBoolArg("-printstakemodifier"))
269             printf("ComputeNextStakeModifier: selected round %d stop=%s height=%d bit=%d\n", nRound, DateTimeStrFormat(nSelectionIntervalStop).c_str(), pindex->nHeight, pindex->GetStakeEntropyBit());
270     }
271
272     // Print selection map for visualization of the selected blocks
273     if (fDebug && GetBoolArg("-printstakemodifier"))
274     {
275         string strSelectionMap = "";
276         // '-' indicates proof-of-work blocks not selected
277         strSelectionMap.insert(0, pindexPrev->nHeight - nHeightFirstCandidate + 1, '-');
278         pindex = pindexPrev;
279         while (pindex && pindex->nHeight >= nHeightFirstCandidate)
280         {
281             // '=' indicates proof-of-stake blocks not selected
282             if (pindex->IsProofOfStake())
283                 strSelectionMap.replace(pindex->nHeight - nHeightFirstCandidate, 1, "=");
284             pindex = pindex->pprev;
285         }
286         BOOST_FOREACH(const PAIRTYPE(uint256, const CBlockIndex*)& item, mapSelectedBlocks)
287         {
288             // 'S' indicates selected proof-of-stake blocks
289             // 'W' indicates selected proof-of-work blocks
290             strSelectionMap.replace(item.second->nHeight - nHeightFirstCandidate, 1, item.second->IsProofOfStake()? "S" : "W");
291         }
292         printf("ComputeNextStakeModifier: selection height [%d, %d] map %s\n", nHeightFirstCandidate, pindexPrev->nHeight, strSelectionMap.c_str());
293     }
294     if (fDebug)
295     {
296         printf("ComputeNextStakeModifier: new modifier=0x%016" PRIx64 " time=%s\n", nStakeModifierNew, DateTimeStrFormat(pindexPrev->GetBlockTime()).c_str());
297     }
298
299     nStakeModifier = nStakeModifierNew;
300     fGeneratedStakeModifier = true;
301     return true;
302 }
303
304 // The stake modifier used to hash for a stake kernel is chosen as the stake
305 // modifier about a selection interval later than the coin generating the kernel
306 static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake)
307 {
308     nStakeModifier = 0;
309     if (!mapBlockIndex.count(hashBlockFrom))
310         return error("GetKernelStakeModifier() : block not indexed");
311     const CBlockIndex* pindexFrom = mapBlockIndex[hashBlockFrom];
312     nStakeModifierHeight = pindexFrom->nHeight;
313     nStakeModifierTime = pindexFrom->GetBlockTime();
314     int64_t nStakeModifierSelectionInterval = GetStakeModifierSelectionInterval();
315     const CBlockIndex* pindex = pindexFrom;
316     // loop to find the stake modifier later by a selection interval
317     while (nStakeModifierTime < pindexFrom->GetBlockTime() + nStakeModifierSelectionInterval)
318     {
319         if (!pindex->pnext)
320         {   // reached best block; may happen if node is behind on block chain
321             if (fPrintProofOfStake || (pindex->GetBlockTime() + nStakeMinAge - nStakeModifierSelectionInterval > GetAdjustedTime()))
322                 return error("GetKernelStakeModifier() : reached best block %s at height %d from block %s",
323                     pindex->GetBlockHash().ToString().c_str(), pindex->nHeight, hashBlockFrom.ToString().c_str());
324             else
325                 return false;
326         }
327         pindex = pindex->pnext;
328         if (pindex->GeneratedStakeModifier())
329         {
330             nStakeModifierHeight = pindex->nHeight;
331             nStakeModifierTime = pindex->GetBlockTime();
332         }
333     }
334     nStakeModifier = pindex->nStakeModifier;
335     return true;
336 }
337
338 bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier)
339 {
340     int nStakeModifierHeight;
341     int64_t nStakeModifierTime;
342
343     return GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, false);
344 }
345
346
347 // ppcoin kernel protocol
348 // coinstake must meet hash target according to the protocol:
349 // kernel (input 0) must meet the formula
350 //     hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget * nCoinDayWeight
351 // this ensures that the chance of getting a coinstake is proportional to the
352 // amount of coin age one owns.
353 // The reason this hash is chosen is the following:
354 //   nStakeModifier: scrambles computation to make it very difficult to precompute
355 //                  future proof-of-stake at the time of the coin's confirmation
356 //   txPrev.block.nTime: prevent nodes from guessing a good timestamp to
357 //                       generate transaction for future advantage
358 //   txPrev.offset: offset of txPrev inside block, to reduce the chance of 
359 //                  nodes generating coinstake at the same time
360 //   txPrev.nTime: reduce the chance of nodes generating coinstake at the same
361 //                 time
362 //   txPrev.vout.n: output number of txPrev, to reduce the chance of nodes
363 //                  generating coinstake at the same time
364 //   block/tx hash should not be used here as they can be generated in vast
365 //   quantities so as to generate blocks faster, degrading the system back into
366 //   a proof-of-work situation.
367 //
368 bool CheckStakeKernelHash(uint32_t nBits, const CBlock& blockFrom, uint32_t nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, uint32_t nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake)
369 {
370     if (nTimeTx < txPrev.nTime)  // Transaction timestamp violation
371         return error("CheckStakeKernelHash() : nTime violation");
372
373     uint32_t nTimeBlockFrom = blockFrom.GetBlockTime();
374     if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement
375         return error("CheckStakeKernelHash() : min age violation");
376
377     CBigNum bnTargetPerCoinDay;
378     bnTargetPerCoinDay.SetCompact(nBits);
379     int64_t nValueIn = txPrev.vout[prevout.n].nValue;
380
381     uint256 hashBlockFrom = blockFrom.GetHash();
382
383     CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)txPrev.nTime, (int64_t)nTimeTx) / COIN / nOneDay;
384     targetProofOfStake = (bnCoinDayWeight * bnTargetPerCoinDay).getuint256();
385
386     // Calculate hash
387     CDataStream ss(SER_GETHASH, 0);
388     uint64_t nStakeModifier = 0;
389     int nStakeModifierHeight = 0;
390     int64_t nStakeModifierTime = 0;
391
392     if (!GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake))
393         return false;
394     ss << nStakeModifier;
395
396     ss << nTimeBlockFrom << nTxPrevOffset << txPrev.nTime << prevout.n << nTimeTx;
397     hashProofOfStake = Hash(ss.begin(), ss.end());
398     if (fPrintProofOfStake)
399     {
400         printf("CheckStakeKernelHash() : using modifier 0x%016" PRIx64 " at height=%d timestamp=%s for block from height=%d timestamp=%s\n",
401             nStakeModifier, nStakeModifierHeight,
402             DateTimeStrFormat(nStakeModifierTime).c_str(),
403             mapBlockIndex[hashBlockFrom]->nHeight,
404             DateTimeStrFormat(blockFrom.GetBlockTime()).c_str());
405         printf("CheckStakeKernelHash() : check modifier=0x%016" PRIx64 " nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashTarget=%s hashProof=%s\n",
406             nStakeModifier,
407             nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx,
408             targetProofOfStake.ToString().c_str(), hashProofOfStake.ToString().c_str());
409     }
410
411     // Now check if proof-of-stake hash meets target protocol
412     if (CBigNum(hashProofOfStake) > bnCoinDayWeight * bnTargetPerCoinDay)
413         return false;
414     if (fDebug && !fPrintProofOfStake)
415     {
416         printf("CheckStakeKernelHash() : using modifier 0x%016" PRIx64 " at height=%d timestamp=%s for block from height=%d timestamp=%s\n",
417             nStakeModifier, nStakeModifierHeight, 
418             DateTimeStrFormat(nStakeModifierTime).c_str(),
419             mapBlockIndex[hashBlockFrom]->nHeight,
420             DateTimeStrFormat(blockFrom.GetBlockTime()).c_str());
421         printf("CheckStakeKernelHash() : pass modifier=0x%016" PRIx64 " nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashTarget=%s hashProof=%s\n",
422             nStakeModifier,
423             nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx,
424             targetProofOfStake.ToString().c_str(), hashProofOfStake.ToString().c_str());
425     }
426     return true;
427 }
428
429
430 #ifdef USE_ASM
431
432 #ifndef __i386__
433 // kernel padding
434 static const uint32_t block1_suffix[9] = { 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0x000000e0 };
435 // hash padding
436 static const uint32_t block2_suffix[8] = { 0x80000000, 0, 0, 0, 0, 0, 0, 0x00000100 };
437 #endif
438
439 // 4-way kernel padding
440 static const uint32_t block1_suffix_4way[4 * 9] = {
441     0x80000000, 0x80000000, 0x80000000, 0x80000000,
442     0, 0, 0, 0,
443     0, 0, 0, 0,
444     0, 0, 0, 0,
445     0, 0, 0, 0,
446     0, 0, 0, 0,
447     0, 0, 0, 0,
448     0, 0, 0, 0,
449     0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0
450 };
451
452 // 4-way hash padding
453 static const uint32_t block2_suffix_4way[4 * 8] = {
454     0x80000000, 0x80000000, 0x80000000, 0x80000000,
455     0, 0, 0, 0,
456     0, 0, 0, 0,
457     0, 0, 0, 0,
458     0, 0, 0, 0,
459     0, 0, 0, 0,
460     0, 0, 0, 0,
461     0x00000100, 0x00000100, 0x00000100, 0x00000100
462 };
463
464 #ifdef __x86_64__
465 // 8-way kernel padding
466 static const uint32_t block1_suffix_8way[8 * 9] = {
467     0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
468     0, 0, 0, 0, 0, 0, 0, 0,
469     0, 0, 0, 0, 0, 0, 0, 0,
470     0, 0, 0, 0, 0, 0, 0, 0,
471     0, 0, 0, 0, 0, 0, 0, 0,
472     0, 0, 0, 0, 0, 0, 0, 0,
473     0, 0, 0, 0, 0, 0, 0, 0,
474     0, 0, 0, 0, 0, 0, 0, 0,
475     0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0
476 };
477
478 // 8-way hash padding
479 static const uint32_t block2_suffix_8way[8 * 8] = {
480     0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
481     0, 0, 0, 0, 0, 0, 0, 0,
482     0, 0, 0, 0, 0, 0, 0, 0,
483     0, 0, 0, 0, 0, 0, 0, 0,
484     0, 0, 0, 0, 0, 0, 0, 0,
485     0, 0, 0, 0, 0, 0, 0, 0,
486     0, 0, 0, 0, 0, 0, 0, 0,
487     0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0
488 };
489 #endif
490
491 // Sha256 initial state
492 static const uint32_t sha256_initial[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
493
494 #ifndef __i386__
495 extern "C" void sha256_transform(uint32_t *state, const uint32_t *block, int swap);
496 #endif
497
498 #if defined(__i386__) || defined(__x86_64__)
499 #include <immintrin.h>
500 extern "C" int sha256_use_ssse3();
501 bool fUseSSSE3 = sha256_use_ssse3() != 0;
502
503 inline void copyrow8_swap32(uint32_t *to, uint32_t *from)
504 {
505     __m128i mask = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
506     _mm_storeu_si128((__m128i *)&to[0], _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)&from[0]), mask));
507     _mm_storeu_si128((__m128i *)&to[4], _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)&from[4]), mask));
508 }
509
510 inline void copyrow4_swap32(uint32_t *to, uint32_t *from)
511 {
512     if (!fUseSSSE3)
513     {
514         for (int i = 0; i < 4; i++)
515             to[i] = __builtin_bswap32(from[i]);
516     }
517     else
518     {
519         __m128i mask = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
520         _mm_storeu_si128((__m128i *)&to[0], _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)&from[0]), mask));
521     }
522 }
523 #else
524 inline void copyrow4_swap32(uint32_t *to, uint32_t *from)
525 {
526     for (int i = 0; i < 4; i++)
527         to[i] = __builtin_bswap32(from[i]);
528 }
529 #endif
530
531 extern "C" int sha256_use_4way();
532 extern "C" void sha256_init_4way(uint32_t *state);
533 extern "C" void sha256_transform_4way(uint32_t *state, const uint32_t *block, int swap);
534
535 bool fUse4Way = sha256_use_4way() != 0;
536
537 #ifdef __x86_64__
538 extern "C" int sha256_use_8way();
539 extern "C" void sha256_init_8way(uint32_t *state);
540 extern "C" void sha256_transform_8way(uint32_t *state, const uint32_t *block, int swap);
541
542 bool fUse8Way = sha256_use_8way() != 0;
543 #endif
544
545
546 class ScanMidstateWorker
547 {
548 public:
549     ScanMidstateWorker()
550     { }
551     ScanMidstateWorker(unsigned char *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, uint32_t nIntervalBegin, uint32_t nIntervalEnd) 
552         : kernel(kernel), nBits(nBits), nInputTxTime(nInputTxTime), bnValueIn(nValueIn), nIntervalBegin(nIntervalBegin), nIntervalEnd(nIntervalEnd)
553     {
554         solutions = vector<std::pair<uint256,uint32_t> >();
555     }
556
557 #ifdef __x86_64__
558     void Do_8way()
559     {
560         SetThreadPriority(THREAD_PRIORITY_LOWEST);
561
562         // Compute maximum possible target to filter out majority of obviously insufficient hashes
563         CBigNum bnTargetPerCoinDay;
564         bnTargetPerCoinDay.SetCompact(nBits);
565         uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256();
566
567         uint32_t blocks1[8 * 16] __attribute__((aligned(16)));
568         uint32_t blocks2[8 * 16] __attribute__((aligned(16)));
569         uint32_t candidates[8 * 8] __attribute__((aligned(16)));
570
571         vector<uint32_t> vRow = vector<uint32_t>(8);
572         uint32_t *pnKernel = (uint32_t *) kernel;
573
574         for(int i = 0; i < 7; i++)
575         {
576             fill(vRow.begin(), vRow.end(), pnKernel[i]);
577             copyrow8_swap32(&blocks1[i*8], &vRow[0]);
578         }
579
580         memcpy(&blocks1[56], &block1_suffix_8way[0], 36*8);   // sha256 padding
581         memcpy(&blocks2[64], &block2_suffix_8way[0], 32*8);
582
583         uint32_t nHashes[8];
584         uint32_t nTimeStamps[8];
585
586         // Search forward in time from the given timestamp
587         // Stopping search in case of shutting down
588         for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx +=8)
589         {
590             sha256_init_8way(blocks2);
591             sha256_init_8way(candidates);
592
593             nTimeStamps[0] = nTimeTx;
594             nTimeStamps[1] = nTimeTx+1;
595             nTimeStamps[2] = nTimeTx+2;
596             nTimeStamps[3] = nTimeTx+3;
597             nTimeStamps[4] = nTimeTx+4;
598             nTimeStamps[5] = nTimeTx+5;
599             nTimeStamps[6] = nTimeTx+6;
600             nTimeStamps[7] = nTimeTx+7;
601
602             copyrow8_swap32(&blocks1[24], &nTimeStamps[0]); // Kernel timestamps
603             sha256_transform_8way(&blocks2[0], &blocks1[0], 0); // first hashing
604             sha256_transform_8way(&candidates[0], &blocks2[0], 0); // second hashing
605             copyrow8_swap32(&nHashes[0], &candidates[56]);
606
607             for(int nResult = 0; nResult < 8; nResult++)
608             {
609                 if (nHashes[nResult] <= nMaxTarget32) // Possible hit
610                 {
611                     uint256 nHashProofOfStake = 0;
612                     uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
613
614                     for (int i = 0; i < 7; i++)
615                         pnHashProofOfStake[i] = __builtin_bswap32(candidates[(i*8) + nResult]);
616                     pnHashProofOfStake[7] = nHashes[nResult];
617
618                     CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeStamps[nResult]) / COIN / nOneDay;
619                     CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
620
621                     if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
622                         solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeStamps[nResult]));
623                 }
624             }
625         }
626     }
627 #endif
628
629     void Do_4way()
630     {
631         SetThreadPriority(THREAD_PRIORITY_LOWEST);
632
633         // Compute maximum possible target to filter out majority of obviously insufficient hashes
634         CBigNum bnTargetPerCoinDay;
635         bnTargetPerCoinDay.SetCompact(nBits);
636         uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256();
637
638         uint32_t blocks1[4 * 16] __attribute__((aligned(16)));
639         uint32_t blocks2[4 * 16] __attribute__((aligned(16)));
640         uint32_t candidates[4 * 8] __attribute__((aligned(16)));
641
642         vector<uint32_t> vRow = vector<uint32_t>(4);
643         uint32_t *pnKernel = (uint32_t *) kernel;
644
645         for(int i = 0; i < 7; i++)
646         {
647             fill(vRow.begin(), vRow.end(), pnKernel[i]);
648             copyrow4_swap32(&blocks1[i*4], &vRow[0]);
649         }
650
651         memcpy(&blocks1[28], &block1_suffix_4way[0], 36*4);   // sha256 padding
652         memcpy(&blocks2[32], &block2_suffix_4way[0], 32*4);
653
654         uint32_t nHashes[4];
655         uint32_t nTimeStamps[4];
656
657         // Search forward in time from the given timestamp
658         // Stopping search in case of shutting down
659         for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx +=4)
660         {
661             sha256_init_4way(blocks2);
662             sha256_init_4way(candidates);
663
664             nTimeStamps[0] = nTimeTx;
665             nTimeStamps[1] = nTimeTx+1;
666             nTimeStamps[2] = nTimeTx+2;
667             nTimeStamps[3] = nTimeTx+3;
668
669             copyrow4_swap32(&blocks1[24], &nTimeStamps[0]); // Kernel timestamps
670             sha256_transform_4way(&blocks2[0], &blocks1[0], 0); // first hashing
671             sha256_transform_4way(&candidates[0], &blocks2[0], 0); // second hashing
672             copyrow4_swap32(&nHashes[0], &candidates[28]);
673
674             for(int nResult = 0; nResult < 4; nResult++)
675             {
676                 if (nHashes[nResult] <= nMaxTarget32) // Possible hit
677                 {
678                     uint256 nHashProofOfStake = 0;
679                     uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
680
681                     for (int i = 0; i < 7; i++)
682                         pnHashProofOfStake[i] = __builtin_bswap32(candidates[(i*4) + nResult]);
683                     pnHashProofOfStake[7] = nHashes[nResult];
684
685                     CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeStamps[nResult]) / COIN / nOneDay;
686                     CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
687
688                     if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
689                         solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeStamps[nResult]));
690                 }
691             }
692         }
693     }
694
695     void Do_oneway()
696     {
697         SetThreadPriority(THREAD_PRIORITY_LOWEST);
698
699         // Compute maximum possible target to filter out majority of obviously insufficient hashes
700         CBigNum bnTargetPerCoinDay;
701         bnTargetPerCoinDay.SetCompact(nBits);
702         uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256();
703
704 #ifdef __i386__
705         SHA256_CTX ctx, workerCtx;
706         // Init new sha256 context and update it
707         //   with first 24 bytes of kernel
708         SHA256_Init(&ctx);
709         SHA256_Update(&ctx, kernel, 8 + 16);
710         workerCtx = ctx; // save context
711
712         // Sha256 result buffer
713         uint32_t hashProofOfStake[8];
714         uint256 *pnHashProofOfStake = (uint256 *)&hashProofOfStake;
715
716         // Search forward in time from the given timestamp
717         // Stopping search in case of shutting down
718         for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx++)
719         {
720             // Complete first hashing iteration
721             uint256 hash1;
722             SHA256_Update(&ctx, (unsigned char*)&nTimeTx, 4);
723             SHA256_Final((unsigned char*)&hash1, &ctx);
724
725             // Restore context
726             ctx = workerCtx;
727
728             // Finally, calculate kernel hash
729             SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
730
731             // Skip if hash doesn't satisfy the maximum target
732             if (hashProofOfStake[7] > nMaxTarget32)
733                 continue;
734
735             CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
736             CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
737
738             if (bnTargetProofOfStake >= CBigNum(*pnHashProofOfStake))
739                 solutions.push_back(std::pair<uint256,uint32_t>(*pnHashProofOfStake, nTimeTx));
740         }
741 #else
742         uint32_t block1[16] __attribute__((aligned(16)));
743         uint32_t block2[16] __attribute__((aligned(16)));
744         uint32_t candidate[8] __attribute__((aligned(16)));
745
746         memcpy(&block1[7], &block1_suffix[0], 36);   // sha256 padding
747         memcpy(&block2[8], &block2_suffix[0], 32);
748
749         uint32_t *pnKernel = (uint32_t *) kernel;
750         copyrow4_swap32(&block1[0], pnKernel);
751         block1[4] = __builtin_bswap32(pnKernel[4]);
752         block1[5] = __builtin_bswap32(pnKernel[5]);
753
754         // Search forward in time from the given timestamp
755         // Stopping search in case of shutting down
756         for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx++)
757         {
758             memcpy(&block2[0], &sha256_initial[0], 32);
759             memcpy(&candidate[0], &sha256_initial[0], 32);
760
761             block1[6] = __builtin_bswap32(nTimeTx);
762
763             sha256_transform(&block2[0], &block1[0], 0); // first hashing
764             sha256_transform(&candidate[0], &block2[0], 0); // second hashing
765
766             uint32_t nHash7 = __builtin_bswap32(candidate[7]);
767
768             // Skip if hash doesn't satisfy the maximum target
769             if (nHash7 > nMaxTarget32)
770                 continue;
771
772             uint256 nHashProofOfStake;
773             uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
774
775             for (int i = 0; i < 7; i++)
776                 pnHashProofOfStake[i] = __builtin_bswap32(candidate[i]);
777             pnHashProofOfStake[7] = nHash7;
778
779             CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
780             CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
781
782             if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
783                 solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeTx));
784         }
785 #endif
786     }
787
788     void Do()
789     {
790 #ifdef __x86_64__
791         if (false && fUse8Way) // disable for now
792         {
793             Do_8way();
794             return;
795         }
796 #endif
797         if (fUse4Way)
798         {
799             Do_4way();
800             return;
801         }
802
803         Do_oneway();
804     }
805
806     vector<std::pair<uint256,uint32_t> >& GetSolutions()
807     {
808         return solutions;
809     }
810
811 private:
812     std::vector<std::pair<uint256,uint32_t> > solutions;
813
814     uint8_t *kernel;
815     uint32_t nBits;
816     uint32_t nInputTxTime;
817     CBigNum  bnValueIn;
818     uint32_t nIntervalBegin;
819     uint32_t nIntervalEnd;
820 };
821
822 #else
823 class ScanMidstateWorker
824 {
825 public:
826     ScanMidstateWorker()
827     { }
828     ScanMidstateWorker(unsigned char *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, uint32_t nIntervalBegin, uint32_t nIntervalEnd) 
829         : nBits(nBits), nInputTxTime(nInputTxTime), bnValueIn(nValueIn), nIntervalBegin(nIntervalBegin), nIntervalEnd(nIntervalEnd)
830     {
831         // Init new sha256 context and update it
832         //   with first 24 bytes of kernel
833         SHA256_Init(&workerCtx);
834         SHA256_Update(&workerCtx, kernel, 8 + 16);
835         solutions = vector<std::pair<uint256,uint32_t> >();
836     }
837
838     void Do()
839     {
840         SetThreadPriority(THREAD_PRIORITY_LOWEST);
841         SHA256_CTX ctx = workerCtx;
842
843         // Sha256 result buffer
844         uint32_t hashProofOfStake[8];
845
846         // Compute maximum possible target to filter out majority of obviously insufficient hashes
847         CBigNum bnTargetPerCoinDay;
848         bnTargetPerCoinDay.SetCompact(nBits);
849
850         uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256(),
851             *pnHashProofOfStake = (uint256 *)&hashProofOfStake;
852
853         // Search forward in time from the given timestamp
854         // Stopping search in case of shutting down
855         for (uint32_t nTimeTx=nIntervalBegin, nMaxTarget32 = nMaxTarget.Get32(7); nTimeTx<nIntervalEnd && !fShutdown; nTimeTx++)
856         {
857             // Complete first hashing iteration
858             uint256 hash1;
859             SHA256_Update(&ctx, (unsigned char*)&nTimeTx, 4);
860             SHA256_Final((unsigned char*)&hash1, &ctx);
861
862             // Restore context
863             ctx = workerCtx;
864
865             // Finally, calculate kernel hash
866             SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
867
868             // Skip if hash doesn't satisfy the maximum target
869             if (hashProofOfStake[7] > nMaxTarget32)
870                 continue;
871
872             CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
873             CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
874
875             if (bnTargetProofOfStake >= CBigNum(*pnHashProofOfStake))
876                 solutions.push_back(std::pair<uint256,uint32_t>(*pnHashProofOfStake, nTimeTx));
877         }
878     }
879
880     vector<std::pair<uint256,uint32_t> >& GetSolutions()
881     {
882         return solutions;
883     }
884
885 private:
886     SHA256_CTX workerCtx;
887     std::vector<std::pair<uint256,uint32_t> > solutions;
888
889     uint32_t nBits;
890     uint32_t nInputTxTime;
891     CBigNum  bnValueIn;
892     uint32_t nIntervalBegin;
893     uint32_t nIntervalEnd;
894 };
895
896 #endif
897 // Scan given kernel for solution
898 bool ScanKernelForward(unsigned char *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::vector<std::pair<uint256, uint32_t> > &solutions)
899 {
900     // TODO: custom threads amount
901
902     uint32_t nThreads = boost::thread::hardware_concurrency();
903     uint32_t nPart = (SearchInterval.second - SearchInterval.first) / nThreads;
904
905
906     ScanMidstateWorker *workers = new ScanMidstateWorker[nThreads];
907
908     boost::thread_group group;
909     for(size_t i = 0; i < nThreads; i++)
910     {
911         uint32_t nBegin = SearchInterval.first + nPart * i;
912         uint32_t nEnd = SearchInterval.first + nPart * (i + 1);
913         workers[i] = ScanMidstateWorker(kernel, nBits, nInputTxTime, nValueIn, nBegin, nEnd);
914         boost::function<void()> workerFnc = boost::bind(&ScanMidstateWorker::Do, &workers[i]);
915         group.create_thread(workerFnc);
916     }
917
918     group.join_all();
919     solutions.clear();
920
921     for(size_t i = 0; i < nThreads; i++)
922     {
923         std::vector<std::pair<uint256, uint32_t> > ws = workers[i].GetSolutions();
924         solutions.insert(solutions.end(), ws.begin(), ws.end());
925     }
926
927     delete [] workers;
928
929     if (solutions.size() == 0)
930     {
931         // no solutions
932         return false;
933     }
934
935     return true;
936 }
937
938 // Scan given midstate for solution
939 bool ScanContextBackward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::pair<uint256, uint32_t> &solution)
940 {
941     CBigNum bnTargetPerCoinDay;
942     bnTargetPerCoinDay.SetCompact(nBits);
943
944     // Get maximum possible target to filter out the majority of obviously insufficient hashes
945     CBigNum bnMaxTargetPerCoinDay = bnTargetPerCoinDay * CBigNum(nValueIn) * nStakeMaxAge / COIN / nOneDay;
946     uint256 maxTarget = bnMaxTargetPerCoinDay.getuint256();
947
948     SHA256_CTX ctxCopy = ctx;
949
950     // Search backward in time from the given timestamp
951     // Stopping search in case of shutting down
952     for (uint32_t nTimeTx=SearchInterval.first; nTimeTx>SearchInterval.second && !fShutdown; nTimeTx--)
953     {
954         // Complete first hashing iteration
955         uint256 hash1;
956         SHA256_Update(&ctxCopy, (unsigned char*)&nTimeTx, 4);
957         SHA256_Final((unsigned char*)&hash1, &ctxCopy);
958
959         // Restore context
960         ctxCopy = ctx;
961
962         // Finally, calculate kernel hash
963         uint256 hashProofOfStake;
964         SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
965
966         // Skip if hash doesn't satisfy the maximum target
967         if (hashProofOfStake > maxTarget)
968             continue;
969
970         CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
971         CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
972
973         if (bnTargetProofOfStake >= CBigNum(hashProofOfStake))
974         {
975             solution.first = hashProofOfStake;
976             solution.second = nTimeTx;
977
978             return true;
979         }
980     }
981
982     return false;
983 }
984
985 // Check kernel hash target and coinstake signature
986 bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake)
987 {
988     if (!tx.IsCoinStake())
989         return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString().c_str());
990
991     // Kernel (input 0) must match the stake hash target per coin age (nBits)
992     const CTxIn& txin = tx.vin[0];
993
994     // First try finding the previous transaction in database
995     CTxDB txdb("r");
996     CTransaction txPrev;
997     CTxIndex txindex;
998     if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
999         return tx.DoS(1, error("CheckProofOfStake() : INFO: read txPrev failed"));  // previous transaction not in main chain, may occur during initial download
1000
1001 #ifndef USE_LEVELDB
1002     txdb.Close();
1003 #endif
1004
1005     // Verify signature
1006     if (!VerifySignature(txPrev, tx, 0, MANDATORY_SCRIPT_VERIFY_FLAGS, 0))
1007         return tx.DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str()));
1008
1009     // Read block header
1010     CBlock block;
1011     if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
1012         return fDebug? error("CheckProofOfStake() : read block failed") : false; // unable to read block of previous transaction
1013
1014     if (!CheckStakeKernelHash(nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, txPrev, txin.prevout, tx.nTime, hashProofOfStake, targetProofOfStake, fDebug))
1015         return tx.DoS(1, error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s", tx.GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str())); // may occur during initial download or if behind on block chain sync
1016
1017     return true;
1018 }
1019
1020 // Get stake modifier checksum
1021 uint32_t GetStakeModifierChecksum(const CBlockIndex* pindex)
1022 {
1023     assert (pindex->pprev || pindex->GetBlockHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet));
1024     // Hash previous checksum with flags, hashProofOfStake and nStakeModifier
1025     CDataStream ss(SER_GETHASH, 0);
1026     if (pindex->pprev)
1027         ss << pindex->pprev->nStakeModifierChecksum;
1028     ss << pindex->nFlags << pindex->hashProofOfStake << pindex->nStakeModifier;
1029     uint256 hashChecksum = Hash(ss.begin(), ss.end());
1030     hashChecksum >>= (256 - 32);
1031     return static_cast<uint32_t>(hashChecksum.Get64());
1032 }
1033
1034 // Check stake modifier hard checkpoints
1035 bool CheckStakeModifierCheckpoints(int nHeight, uint32_t nStakeModifierChecksum)
1036 {
1037     MapModifierCheckpoints& checkpoints = (fTestNet ? mapStakeModifierCheckpointsTestNet : mapStakeModifierCheckpoints);
1038
1039     if (checkpoints.count(nHeight))
1040         return nStakeModifierChecksum == checkpoints[nHeight];
1041     return true;
1042 }