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.
8 #include <boost/assign/list_of.hpp>
13 extern unsigned int nStakeMaxAge;
14 extern unsigned int nStakeTargetSpacing;
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
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
26 unsigned int nModifierUpgradeTime = 0;
28 typedef std::map<int, unsigned int> MapModifierCheckpoints;
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
34 ( 12661, 0x5d84115du )
35 (143990, 0x9c592c78u )
36 (149000, 0x48f2bdc4u )
37 (160000, 0x789df0f0u )
38 (200000, 0x01ec1503u )
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
47 // Pregenerated entropy bits table (from genesis to #9689)
49 // Bits are packed into array of 256 bit integers:
51 // * array index calculated as nHeight / 256
52 // * position of bit is calculated as nHeight & 0xFF.
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")
95 // Whether the given block is subject to new modifier protocol
96 bool IsFixedModifierInterval(unsigned int nTimeBlock)
98 return (nTimeBlock >= (fTestNet? nModifierTestSwitchTime : nModifierSwitchTime));
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)
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();
115 // Get selection interval section (in seconds)
116 static int64_t GetStakeModifierSelectionIntervalSection(int nSection)
118 assert (nSection >= 0 && nSection < 64);
119 return (nModifierInterval * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1))));
122 // Get stake modifier selection interval (in seconds)
123 static int64_t GetStakeModifierSelectionInterval()
125 int64_t nSelectionInterval = 0;
126 for (int nSection=0; nSection<64; nSection++)
127 nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection);
128 return nSelectionInterval;
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)
137 bool fSelected = false;
138 uint256 hashBest = 0;
139 *pindexSelected = (const CBlockIndex*) 0;
140 BOOST_FOREACH(const PAIRTYPE(int64_t, uint256)& item, vSortedByTimestamp)
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)
147 if (mapSelectedBlocks.count(pindex->GetBlockHash()) > 0)
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)
162 hashBest = hashSelection;
163 *pindexSelected = (const CBlockIndex*) pindex;
168 hashBest = hashSelection;
169 *pindexSelected = (const CBlockIndex*) pindex;
172 if (fDebug && GetBoolArg("-printstakemodifier"))
173 printf("SelectBlockFromCandidates: selection hash=%s\n", hashBest.ToString().c_str());
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
190 bool ComputeNextStakeModifier(const CBlockIndex* pindexCurrent, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier)
193 fGeneratedStakeModifier = false;
194 const CBlockIndex* pindexPrev = pindexCurrent->pprev;
197 fGeneratedStakeModifier = true;
198 return true; // genesis block's modifier is 0
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");
208 printf("ComputeNextStakeModifier: prev modifier=0x%016" PRIx64 " time=%s epoch=%u\n", nStakeModifier, DateTimeStrFormat(nModifierTime).c_str(), (unsigned int)nModifierTime);
210 if (nModifierTime / nModifierInterval >= pindexPrev->GetBlockTime() / nModifierInterval)
214 printf("ComputeNextStakeModifier: no new interval keep current modifier: pindexPrev nHeight=%d nTime=%u\n", pindexPrev->nHeight, (unsigned int)pindexPrev->GetBlockTime());
218 if (nModifierTime / nModifierInterval >= pindexCurrent->GetBlockTime() / nModifierInterval)
220 // fixed interval protocol requires current block timestamp also be in a different modifier interval
221 if (IsFixedModifierInterval(pindexCurrent->nTime))
225 printf("ComputeNextStakeModifier: no new interval keep current modifier: pindexCurrent nHeight=%d nTime=%u\n", pindexCurrent->nHeight, (unsigned int)pindexCurrent->GetBlockTime());
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());
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)
246 vSortedByTimestamp.push_back(make_pair(pindex->GetBlockTime(), pindex->GetBlockHash()));
247 pindex = pindex->pprev;
249 int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0;
250 reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end());
251 sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end());
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++)
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());
272 // Print selection map for visualization of the selected blocks
273 if (fDebug && GetBoolArg("-printstakemodifier"))
275 string strSelectionMap = "";
276 // '-' indicates proof-of-work blocks not selected
277 strSelectionMap.insert(0, pindexPrev->nHeight - nHeightFirstCandidate + 1, '-');
279 while (pindex && pindex->nHeight >= nHeightFirstCandidate)
281 // '=' indicates proof-of-stake blocks not selected
282 if (pindex->IsProofOfStake())
283 strSelectionMap.replace(pindex->nHeight - nHeightFirstCandidate, 1, "=");
284 pindex = pindex->pprev;
286 BOOST_FOREACH(const PAIRTYPE(uint256, const CBlockIndex*)& item, mapSelectedBlocks)
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");
292 printf("ComputeNextStakeModifier: selection height [%d, %d] map %s\n", nHeightFirstCandidate, pindexPrev->nHeight, strSelectionMap.c_str());
296 printf("ComputeNextStakeModifier: new modifier=0x%016" PRIx64 " time=%s\n", nStakeModifierNew, DateTimeStrFormat(pindexPrev->GetBlockTime()).c_str());
299 nStakeModifier = nStakeModifierNew;
300 fGeneratedStakeModifier = true;
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)
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)
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());
327 pindex = pindex->pnext;
328 if (pindex->GeneratedStakeModifier())
330 nStakeModifierHeight = pindex->nHeight;
331 nStakeModifierTime = pindex->GetBlockTime();
334 nStakeModifier = pindex->nStakeModifier;
338 bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier)
340 int nStakeModifierHeight;
341 int64_t nStakeModifierTime;
343 return GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, false);
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
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.
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)
370 if (nTimeTx < txPrev.nTime) // Transaction timestamp violation
371 return error("CheckStakeKernelHash() : nTime violation");
373 uint32_t nTimeBlockFrom = blockFrom.GetBlockTime();
374 if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement
375 return error("CheckStakeKernelHash() : min age violation");
377 CBigNum bnTargetPerCoinDay;
378 bnTargetPerCoinDay.SetCompact(nBits);
379 int64_t nValueIn = txPrev.vout[prevout.n].nValue;
381 uint256 hashBlockFrom = blockFrom.GetHash();
383 CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)txPrev.nTime, (int64_t)nTimeTx) / COIN / nOneDay;
384 targetProofOfStake = (bnCoinDayWeight * bnTargetPerCoinDay).getuint256();
387 CDataStream ss(SER_GETHASH, 0);
388 uint64_t nStakeModifier = 0;
389 int nStakeModifierHeight = 0;
390 int64_t nStakeModifierTime = 0;
392 if (!GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake))
394 ss << nStakeModifier;
396 ss << nTimeBlockFrom << nTxPrevOffset << txPrev.nTime << prevout.n << nTimeTx;
397 hashProofOfStake = Hash(ss.begin(), ss.end());
398 if (fPrintProofOfStake)
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",
407 nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx,
408 targetProofOfStake.ToString().c_str(), hashProofOfStake.ToString().c_str());
411 // Now check if proof-of-stake hash meets target protocol
412 if (CBigNum(hashProofOfStake) > bnCoinDayWeight * bnTargetPerCoinDay)
414 if (fDebug && !fPrintProofOfStake)
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",
423 nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx,
424 targetProofOfStake.ToString().c_str(), hashProofOfStake.ToString().c_str());
434 static const uint32_t block1_suffix[9] = { 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0x000000e0 };
436 static const uint32_t block2_suffix[8] = { 0x80000000, 0, 0, 0, 0, 0, 0, 0x00000100 };
439 // 4-way kernel padding
440 static const uint32_t block1_suffix_4way[4 * 9] = {
441 0x80000000, 0x80000000, 0x80000000, 0x80000000,
449 0x000000e0, 0x000000e0, 0x000000e0, 0x000000e0
452 // 4-way hash padding
453 static const uint32_t block2_suffix_4way[4 * 8] = {
454 0x80000000, 0x80000000, 0x80000000, 0x80000000,
461 0x00000100, 0x00000100, 0x00000100, 0x00000100
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
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
491 // Sha256 initial state
492 static const uint32_t sha256_initial[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
495 extern "C" void sha256_transform(uint32_t *state, const uint32_t *block, int swap);
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;
503 inline void copyrow8_swap32(uint32_t *to, uint32_t *from)
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));
510 inline void copyrow4_swap32(uint32_t *to, uint32_t *from)
514 for (int i = 0; i < 4; i++)
515 to[i] = __builtin_bswap32(from[i]);
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));
524 inline void copyrow4_swap32(uint32_t *to, uint32_t *from)
526 for (int i = 0; i < 4; i++)
527 to[i] = __builtin_bswap32(from[i]);
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);
535 bool fUse4Way = sha256_use_4way() != 0;
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);
542 bool fUse8Way = sha256_use_8way() != 0;
546 class ScanMidstateWorker
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)
554 solutions = vector<std::pair<uint256,uint32_t> >();
560 SetThreadPriority(THREAD_PRIORITY_LOWEST);
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();
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)));
571 vector<uint32_t> vRow = vector<uint32_t>(8);
572 uint32_t *pnKernel = (uint32_t *) kernel;
574 for(int i = 0; i < 7; i++)
576 fill(vRow.begin(), vRow.end(), pnKernel[i]);
577 copyrow8_swap32(&blocks1[i*8], &vRow[0]);
580 memcpy(&blocks1[56], &block1_suffix_8way[0], 36*8); // sha256 padding
581 memcpy(&blocks2[64], &block2_suffix_8way[0], 32*8);
584 uint32_t nTimeStamps[8];
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)
590 sha256_init_8way(blocks2);
591 sha256_init_8way(candidates);
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;
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]);
607 for(int nResult = 0; nResult < 8; nResult++)
609 if (nHashes[nResult] <= nMaxTarget32) // Possible hit
611 uint256 nHashProofOfStake = 0;
612 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
614 for (int i = 0; i < 7; i++)
615 pnHashProofOfStake[i] = __builtin_bswap32(candidates[(i*8) + nResult]);
616 pnHashProofOfStake[7] = nHashes[nResult];
618 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeStamps[nResult]) / COIN / nOneDay;
619 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
621 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
622 solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeStamps[nResult]));
631 SetThreadPriority(THREAD_PRIORITY_LOWEST);
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();
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)));
642 vector<uint32_t> vRow = vector<uint32_t>(4);
643 uint32_t *pnKernel = (uint32_t *) kernel;
645 for(int i = 0; i < 7; i++)
647 fill(vRow.begin(), vRow.end(), pnKernel[i]);
648 copyrow4_swap32(&blocks1[i*4], &vRow[0]);
651 memcpy(&blocks1[28], &block1_suffix_4way[0], 36*4); // sha256 padding
652 memcpy(&blocks2[32], &block2_suffix_4way[0], 32*4);
655 uint32_t nTimeStamps[4];
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)
661 sha256_init_4way(blocks2);
662 sha256_init_4way(candidates);
664 nTimeStamps[0] = nTimeTx;
665 nTimeStamps[1] = nTimeTx+1;
666 nTimeStamps[2] = nTimeTx+2;
667 nTimeStamps[3] = nTimeTx+3;
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]);
674 for(int nResult = 0; nResult < 4; nResult++)
676 if (nHashes[nResult] <= nMaxTarget32) // Possible hit
678 uint256 nHashProofOfStake = 0;
679 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
681 for (int i = 0; i < 7; i++)
682 pnHashProofOfStake[i] = __builtin_bswap32(candidates[(i*4) + nResult]);
683 pnHashProofOfStake[7] = nHashes[nResult];
685 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeStamps[nResult]) / COIN / nOneDay;
686 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
688 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
689 solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeStamps[nResult]));
697 SetThreadPriority(THREAD_PRIORITY_LOWEST);
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();
705 SHA256_CTX ctx, workerCtx;
706 // Init new sha256 context and update it
707 // with first 24 bytes of kernel
709 SHA256_Update(&ctx, kernel, 8 + 16);
710 workerCtx = ctx; // save context
712 // Sha256 result buffer
713 uint32_t hashProofOfStake[8];
714 uint256 *pnHashProofOfStake = (uint256 *)&hashProofOfStake;
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++)
720 // Complete first hashing iteration
722 SHA256_Update(&ctx, (unsigned char*)&nTimeTx, 4);
723 SHA256_Final((unsigned char*)&hash1, &ctx);
728 // Finally, calculate kernel hash
729 SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
731 // Skip if hash doesn't satisfy the maximum target
732 if (hashProofOfStake[7] > nMaxTarget32)
735 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
736 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
738 if (bnTargetProofOfStake >= CBigNum(*pnHashProofOfStake))
739 solutions.push_back(std::pair<uint256,uint32_t>(*pnHashProofOfStake, nTimeTx));
742 uint32_t block1[16] __attribute__((aligned(16)));
743 uint32_t block2[16] __attribute__((aligned(16)));
744 uint32_t candidate[8] __attribute__((aligned(16)));
746 memcpy(&block1[7], &block1_suffix[0], 36); // sha256 padding
747 memcpy(&block2[8], &block2_suffix[0], 32);
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]);
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++)
758 memcpy(&block2[0], &sha256_initial[0], 32);
759 memcpy(&candidate[0], &sha256_initial[0], 32);
761 block1[6] = __builtin_bswap32(nTimeTx);
763 sha256_transform(&block2[0], &block1[0], 0); // first hashing
764 sha256_transform(&candidate[0], &block2[0], 0); // second hashing
766 uint32_t nHash7 = __builtin_bswap32(candidate[7]);
768 // Skip if hash doesn't satisfy the maximum target
769 if (nHash7 > nMaxTarget32)
772 uint256 nHashProofOfStake;
773 uint32_t *pnHashProofOfStake = (uint32_t *) &nHashProofOfStake;
775 for (int i = 0; i < 7; i++)
776 pnHashProofOfStake[i] = __builtin_bswap32(candidate[i]);
777 pnHashProofOfStake[7] = nHash7;
779 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
780 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
782 if (bnTargetProofOfStake >= CBigNum(nHashProofOfStake))
783 solutions.push_back(std::pair<uint256,uint32_t>(nHashProofOfStake, nTimeTx));
791 if (false && fUse8Way) // disable for now
806 vector<std::pair<uint256,uint32_t> >& GetSolutions()
812 std::vector<std::pair<uint256,uint32_t> > solutions;
816 uint32_t nInputTxTime;
818 uint32_t nIntervalBegin;
819 uint32_t nIntervalEnd;
823 class ScanMidstateWorker
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)
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> >();
840 SetThreadPriority(THREAD_PRIORITY_LOWEST);
841 SHA256_CTX ctx = workerCtx;
843 // Sha256 result buffer
844 uint32_t hashProofOfStake[8];
846 // Compute maximum possible target to filter out majority of obviously insufficient hashes
847 CBigNum bnTargetPerCoinDay;
848 bnTargetPerCoinDay.SetCompact(nBits);
850 uint256 nMaxTarget = (bnTargetPerCoinDay * bnValueIn * nStakeMaxAge / COIN / nOneDay).getuint256(),
851 *pnHashProofOfStake = (uint256 *)&hashProofOfStake;
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++)
857 // Complete first hashing iteration
859 SHA256_Update(&ctx, (unsigned char*)&nTimeTx, 4);
860 SHA256_Final((unsigned char*)&hash1, &ctx);
865 // Finally, calculate kernel hash
866 SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
868 // Skip if hash doesn't satisfy the maximum target
869 if (hashProofOfStake[7] > nMaxTarget32)
872 CBigNum bnCoinDayWeight = bnValueIn * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
873 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
875 if (bnTargetProofOfStake >= CBigNum(*pnHashProofOfStake))
876 solutions.push_back(std::pair<uint256,uint32_t>(*pnHashProofOfStake, nTimeTx));
880 vector<std::pair<uint256,uint32_t> >& GetSolutions()
886 SHA256_CTX workerCtx;
887 std::vector<std::pair<uint256,uint32_t> > solutions;
890 uint32_t nInputTxTime;
892 uint32_t nIntervalBegin;
893 uint32_t nIntervalEnd;
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)
900 // TODO: custom threads amount
902 uint32_t nThreads = boost::thread::hardware_concurrency();
903 uint32_t nPart = (SearchInterval.second - SearchInterval.first) / nThreads;
906 ScanMidstateWorker *workers = new ScanMidstateWorker[nThreads];
908 boost::thread_group group;
909 for(size_t i = 0; i < nThreads; i++)
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);
921 for(size_t i = 0; i < nThreads; i++)
923 std::vector<std::pair<uint256, uint32_t> > ws = workers[i].GetSolutions();
924 solutions.insert(solutions.end(), ws.begin(), ws.end());
929 if (solutions.size() == 0)
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)
941 CBigNum bnTargetPerCoinDay;
942 bnTargetPerCoinDay.SetCompact(nBits);
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();
948 SHA256_CTX ctxCopy = ctx;
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--)
954 // Complete first hashing iteration
956 SHA256_Update(&ctxCopy, (unsigned char*)&nTimeTx, 4);
957 SHA256_Final((unsigned char*)&hash1, &ctxCopy);
962 // Finally, calculate kernel hash
963 uint256 hashProofOfStake;
964 SHA256((unsigned char*)&hash1, sizeof(hashProofOfStake), (unsigned char*)&hashProofOfStake);
966 // Skip if hash doesn't satisfy the maximum target
967 if (hashProofOfStake > maxTarget)
970 CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)nInputTxTime, (int64_t)nTimeTx) / COIN / nOneDay;
971 CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay;
973 if (bnTargetProofOfStake >= CBigNum(hashProofOfStake))
975 solution.first = hashProofOfStake;
976 solution.second = nTimeTx;
985 // Check kernel hash target and coinstake signature
986 bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake)
988 if (!tx.IsCoinStake())
989 return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString().c_str());
991 // Kernel (input 0) must match the stake hash target per coin age (nBits)
992 const CTxIn& txin = tx.vin[0];
994 // First try finding the previous transaction in database
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
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()));
1009 // Read block header
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
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
1020 // Get stake modifier checksum
1021 uint32_t GetStakeModifierChecksum(const CBlockIndex* pindex)
1023 assert (pindex->pprev || pindex->GetBlockHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet));
1024 // Hash previous checksum with flags, hashProofOfStake and nStakeModifier
1025 CDataStream ss(SER_GETHASH, 0);
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());
1034 // Check stake modifier hard checkpoints
1035 bool CheckStakeModifierCheckpoints(int nHeight, uint32_t nStakeModifierChecksum)
1037 MapModifierCheckpoints& checkpoints = (fTestNet ? mapStakeModifierCheckpointsTestNet : mapStakeModifierCheckpoints);
1039 if (checkpoints.count(nHeight))
1040 return nStakeModifierChecksum == checkpoints[nHeight];