c47a80f639fb834e4731a0459a03fd0cfebd7022
[novacoin.git] / src / main.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin 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
6 #include <regex>
7
8 #include "alert.h"
9 #include "checkpoints.h"
10 #include "db.h"
11 #include "txdb.h"
12 #include "init.h"
13 #include "ui_interface.h"
14 #include "checkqueue.h"
15 #include "kernel.h"
16 #include <boost/filesystem.hpp>
17 #include <boost/filesystem/fstream.hpp>
18
19 #include "main.h"
20
21 using namespace std;
22 using namespace boost;
23
24
25
26 CCriticalSection cs_setpwalletRegistered;
27 set<CWallet*> setpwalletRegistered;
28
29 CCriticalSection cs_main;
30
31 CTxMemPool mempool;
32 unsigned int nTransactionsUpdated = 0;
33
34 map<uint256, CBlockIndex*> mapBlockIndex;
35 set<pair<COutPoint, unsigned int> > setStakeSeen;
36
37 CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); // "standard" scrypt target limit for proof of work, results with 0,000244140625 proof-of-work difficulty
38 CBigNum bnProofOfStakeLegacyLimit(~uint256(0) >> 24); // proof of stake target limit from block #15000 and until 20 June 2013, results with 0,00390625 proof of stake difficulty
39 CBigNum bnProofOfStakeLimit(~uint256(0) >> 27); // proof of stake target limit since 20 June 2013, equal to 0.03125  proof of stake difficulty
40 CBigNum bnProofOfStakeHardLimit(~uint256(0) >> 30); // disabled temporarily, will be used in the future to fix minimal proof of stake difficulty at 0.25
41 uint256 nPoWBase = uint256("0x00000000ffff0000000000000000000000000000000000000000000000000000"); // difficulty-1 target
42
43 CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16);
44
45 unsigned int nStakeTargetSpacing = 10 * 60; // 10-minute stakes spacing
46 unsigned int nModifierInterval = 6 * nOneHour; // time to elapse before new modifier is computed
47
48 int nCoinbaseMaturity = 500;
49
50 CBlockIndex* pindexGenesisBlock = NULL;
51 int nBestHeight = -1;
52
53 uint256 nBestChainTrust = 0;
54 uint256 nBestInvalidTrust = 0;
55
56 uint256 hashBestChain = 0;
57 CBlockIndex* pindexBest = NULL;
58 int64_t nTimeBestReceived = 0;
59 int nScriptCheckThreads = 0;
60
61 CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have
62
63 map<uint256, CBlock*> mapOrphanBlocks;
64 multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
65 set<pair<COutPoint, unsigned int> > setStakeSeenOrphan;
66 map<uint256, uint256> mapProofOfStake;
67
68 map<uint256, CTransaction> mapOrphanTransactions;
69 map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
70
71 // Constant stuff for coinbase transactions we create:
72 CScript COINBASE_FLAGS;
73
74 const string strMessageMagic = "NovaCoin Signed Message:\n";
75
76 // Settings
77 int64_t nTransactionFee = MIN_TX_FEE;
78 int64_t nMinimumInputValue = MIN_TXOUT_AMOUNT;
79
80 // Ping and address broadcast intervals
81 int64_t nPingInterval = 30 * 60;
82
83 extern enum Checkpoints::CPMode CheckpointsMode;
84
85 //////////////////////////////////////////////////////////////////////////////
86 //
87 // dispatching functions
88 //
89
90 // These functions dispatch to one or all registered wallets
91
92
93 void RegisterWallet(CWallet* pwalletIn)
94 {
95     {
96         LOCK(cs_setpwalletRegistered);
97         setpwalletRegistered.insert(pwalletIn);
98     }
99 }
100
101 void UnregisterWallet(CWallet* pwalletIn)
102 {
103     {
104         LOCK(cs_setpwalletRegistered);
105         setpwalletRegistered.erase(pwalletIn);
106     }
107 }
108
109 // check whether the passed transaction is from us
110 bool static IsFromMe(CTransaction& tx)
111 {
112     for(CWallet* pwallet :  setpwalletRegistered)
113         if (pwallet->IsFromMe(tx))
114             return true;
115     return false;
116 }
117
118 // make sure all wallets know about the given transaction, in the given block
119 void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fConnect)
120 {
121     if (!fConnect)
122     {
123         // wallets need to refund inputs when disconnecting coinstake
124         if (tx.IsCoinStake())
125         {
126             for(CWallet* pwallet :  setpwalletRegistered)
127                 if (pwallet->IsFromMe(tx))
128                     pwallet->DisableTransaction(tx);
129         }
130         return;
131     }
132
133     for(CWallet* pwallet :  setpwalletRegistered)
134         pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate);
135 }
136
137 // notify wallets about a new best chain
138 void static SetBestChain(const CBlockLocator& loc)
139 {
140     for(CWallet* pwallet :  setpwalletRegistered)
141         pwallet->SetBestChain(loc);
142 }
143
144 // notify wallets about an updated transaction
145 void static UpdatedTransaction(const uint256& hashTx)
146 {
147     for(CWallet* pwallet :  setpwalletRegistered)
148         pwallet->UpdatedTransaction(hashTx);
149 }
150
151 // dump all wallets
152 void static PrintWallets(const CBlock& block)
153 {
154     for(CWallet* pwallet :  setpwalletRegistered)
155         pwallet->PrintWallet(block);
156 }
157
158 // notify wallets about an incoming inventory (for request counts)
159 void static Inventory(const uint256& hash)
160 {
161     for(CWallet* pwallet :  setpwalletRegistered)
162         pwallet->Inventory(hash);
163 }
164
165 // ask wallets to resend their transactions
166 void ResendWalletTransactions(bool fForceResend)
167 {
168     for(CWallet* pwallet :  setpwalletRegistered)
169         pwallet->ResendWalletTransactions(fForceResend);
170 }
171
172
173
174
175
176
177
178 //////////////////////////////////////////////////////////////////////////////
179 //
180 // mapOrphanTransactions
181 //
182
183 bool AddOrphanTx(const CTransaction& tx)
184 {
185     auto hash = tx.GetHash();
186     if (mapOrphanTransactions.count(hash))
187         return false;
188
189     // Ignore big transactions, to avoid a
190     // send-big-orphans memory exhaustion attack. If a peer has a legitimate
191     // large transaction with a missing parent then we assume
192     // it will rebroadcast it later, after the parent transaction(s)
193     // have been mined or received.
194     // 10,000 orphans, each of which is at most 5,000 bytes big is
195     // at most 500 megabytes of orphans:
196
197     size_t nSize = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
198
199     if (nSize > 5000)
200     {
201         printf("ignoring large orphan tx (size: %" PRIszu ", hash: %s)\n", nSize, hash.ToString().substr(0,10).c_str());
202         return false;
203     }
204
205     mapOrphanTransactions[hash] = tx;
206     for(const CTxIn& txin :  tx.vin)
207         mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
208
209     printf("stored orphan tx %s (mapsz %" PRIszu ")\n", hash.ToString().substr(0,10).c_str(),
210         mapOrphanTransactions.size());
211     return true;
212 }
213
214 void static EraseOrphanTx(uint256 hash)
215 {
216     if (!mapOrphanTransactions.count(hash))
217         return;
218     const auto& tx = mapOrphanTransactions[hash];
219     for(const auto& txin :  tx.vin)
220     {
221         mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash);
222         if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty())
223             mapOrphanTransactionsByPrev.erase(txin.prevout.hash);
224     }
225     mapOrphanTransactions.erase(hash);
226 }
227
228 unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
229 {
230     unsigned int nEvicted = 0;
231     while (mapOrphanTransactions.size() > nMaxOrphans)
232     {
233         // Evict a random orphan:
234         auto randomhash = GetRandHash();
235         auto it = mapOrphanTransactions.lower_bound(randomhash);
236         if (it == mapOrphanTransactions.end())
237             it = mapOrphanTransactions.begin();
238         EraseOrphanTx(it->first);
239         ++nEvicted;
240     }
241     return nEvicted;
242 }
243
244
245
246
247
248
249
250 //////////////////////////////////////////////////////////////////////////////
251 //
252 // CTransaction and CTxIndex
253 //
254
255 bool CTransaction::IsFinal(int nBlockHeight, int64_t nBlockTime) const
256 {
257     // Time based nLockTime implemented in 0.1.6
258     if (nLockTime == 0)
259         return true;
260     if (nBlockHeight == 0)
261         nBlockHeight = nBestHeight;
262     if (nBlockTime == 0)
263         nBlockTime = GetAdjustedTime();
264     if ((int64_t)nLockTime < ((int64_t)nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
265         return true;
266     for(const CTxIn& txin : vin)
267         if (!txin.IsFinal())
268             return false;
269     return true;
270 }
271
272 bool CTransaction::ReadFromDisk(CDiskTxPos pos, FILE** pfileRet)
273 {
274     auto filein = CAutoFile(OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION);
275     if (!filein)
276         return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
277
278     // Read transaction
279     if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
280         return error("CTransaction::ReadFromDisk() : fseek failed");
281
282     try {
283         filein >> *this;
284     }
285     catch (const std::exception&) {
286         return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION);
287     }
288
289     // Return file pointer
290     if (pfileRet)
291     {
292         if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
293             return error("CTransaction::ReadFromDisk() : second fseek failed");
294         *pfileRet = filein.release();
295     }
296     return true;
297 }
298
299 bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet)
300 {
301     SetNull();
302     if (!txdb.ReadTxIndex(prevout.hash, txindexRet))
303         return false;
304     if (!ReadFromDisk(txindexRet.pos))
305         return false;
306     if (prevout.n >= vout.size())
307     {
308         SetNull();
309         return false;
310     }
311     return true;
312 }
313
314 bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout)
315 {
316     CTxIndex txindex;
317     return ReadFromDisk(txdb, prevout, txindex);
318 }
319
320 bool CTransaction::ReadFromDisk(COutPoint prevout)
321 {
322     CTxDB txdb("r");
323     CTxIndex txindex;
324     return ReadFromDisk(txdb, prevout, txindex);
325 }
326
327 bool CTransaction::IsStandard(string& strReason) const
328 {
329     if (nVersion > CTransaction::CURRENT_VERSION)
330     {
331         strReason = "version";
332         return false;
333     }
334
335     unsigned int nDataOut = 0;
336     txnouttype whichType;
337     for(const CTxIn& txin :  vin)
338     {
339         // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
340         // keys. (remember the 520 byte limit on redeemScript size) That works
341         // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)=1624
342         // bytes of scriptSig, which we round off to 1650 bytes for some minor
343         // future-proofing. That's also enough to spend a 20-of-20
344         // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
345         // considered standard)
346         if (txin.scriptSig.size() > 1650)
347         {
348             strReason = "scriptsig-size";
349             return false;
350         }
351         if (!txin.scriptSig.IsPushOnly())
352         {
353             strReason = "scriptsig-not-pushonly";
354             return false;
355         }
356         if (!txin.scriptSig.HasCanonicalPushes()) {
357             strReason = "txin-scriptsig-not-canonicalpushes";
358             return false;
359         }
360     }
361     for(const CTxOut& txout :  vout) {
362         if (!::IsStandard(txout.scriptPubKey, whichType)) {
363             strReason = "scriptpubkey";
364             return false;
365         }
366         if (whichType == TX_NULL_DATA)
367             nDataOut++;
368         else {
369             if (txout.nValue == 0) {
370                 strReason = "txout-value=0";
371                 return false;
372             }
373             if (!txout.scriptPubKey.HasCanonicalPushes()) {
374                 strReason = "txout-scriptsig-not-canonicalpushes";
375                 return false;
376             }
377         }
378     }
379
380     // only one OP_RETURN txout is permitted
381     if (nDataOut > 1) {
382         strReason = "multi-op-return";
383         return false;
384     }
385
386     return true;
387 }
388
389 //
390 // Check transaction inputs, and make sure any
391 // pay-to-script-hash transactions are evaluating IsStandard scripts
392 //
393 // Why bother? To avoid denial-of-service attacks; an attacker
394 // can submit a standard HASH... OP_EQUAL transaction,
395 // which will get accepted into blocks. The redemption
396 // script can be anything; an attacker could use a very
397 // expensive-to-check-upon-redemption script like:
398 //   DUP CHECKSIG DROP ... repeated 100 times... OP_1
399 //
400 bool CTransaction::AreInputsStandard(const MapPrevTx& mapInputs) const
401 {
402     if (IsCoinBase())
403         return true; // Coinbases don't use vin normally
404
405     for (uint32_t i = 0; i < vin.size(); i++)
406     {
407         const CTxOut& prev = GetOutputFor(vin[i], mapInputs);
408
409         vector<vector<unsigned char> > vSolutions;
410         txnouttype whichType;
411         // get the scriptPubKey corresponding to this input:
412         const CScript& prevScript = prev.scriptPubKey;
413         if (!Solver(prevScript, whichType, vSolutions))
414             return false;
415         int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
416         if (nArgsExpected < 0)
417             return false;
418
419         // Transactions with extra stuff in their scriptSigs are
420         // non-standard. Note that this EvalScript() call will
421         // be quick, because if there are any operations
422         // beside "push data" in the scriptSig the
423         // IsStandard() call returns false
424         vector<vector<unsigned char> > stack;
425         if (!EvalScript(stack, vin[i].scriptSig, *this, i, false, 0))
426             return false;
427
428         if (whichType == TX_SCRIPTHASH)
429         {
430             if (stack.empty())
431                 return false;
432             CScript subscript(stack.back().begin(), stack.back().end());
433             vector<vector<unsigned char> > vSolutions2;
434             txnouttype whichType2;
435             if (!Solver(subscript, whichType2, vSolutions2))
436                 return false;
437             if (whichType2 == TX_SCRIPTHASH)
438                 return false;
439
440             int tmpExpected;
441             tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
442             if (tmpExpected < 0)
443                 return false;
444             nArgsExpected += tmpExpected;
445         }
446
447         if (stack.size() != (unsigned int)nArgsExpected)
448             return false;
449     }
450
451     return true;
452 }
453
454 unsigned int CTransaction::GetLegacySigOpCount() const
455 {
456     unsigned int nSigOps = 0;
457     if (!IsCoinBase())
458     {
459         // Coinbase scriptsigs are never executed, so there is 
460         //    no sense in calculation of sigops.
461         for(const CTxIn& txin :  vin)
462         {
463             nSigOps += txin.scriptSig.GetSigOpCount(false);
464         }
465     }
466     for(const CTxOut& txout :  vout)
467     {
468         nSigOps += txout.scriptPubKey.GetSigOpCount(false);
469     }
470     return nSigOps;
471 }
472
473 int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
474 {
475     if (fClient)
476     {
477         if (hashBlock == 0)
478             return 0;
479     }
480     else
481     {
482         CBlock blockTmp;
483
484         if (pblock == NULL)
485         {
486             // Load the block this tx is in
487             CTxIndex txindex;
488             if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))
489                 return 0;
490             if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos))
491                 return 0;
492             pblock = &blockTmp;
493         }
494
495         // Update the tx's hashBlock
496         hashBlock = pblock->GetHash();
497
498         // Locate the transaction
499         for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++)
500             if (pblock->vtx[nIndex] == *(CTransaction*)this)
501                 break;
502         if (nIndex == (int)pblock->vtx.size())
503         {
504             vMerkleBranch.clear();
505             nIndex = -1;
506             printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
507             return 0;
508         }
509
510         // Fill in merkle branch
511         vMerkleBranch = pblock->GetMerkleBranch(nIndex);
512     }
513
514     // Is the tx in a block that's in the main chain
515     auto mi = mapBlockIndex.find(hashBlock);
516     if (mi == mapBlockIndex.end())
517         return 0;
518     const CBlockIndex* pindex = (*mi).second;
519     if (!pindex || !pindex->IsInMainChain())
520         return 0;
521
522     return pindexBest->nHeight - pindex->nHeight + 1;
523 }
524
525 bool CTransaction::CheckTransaction() const
526 {
527     // Basic checks that don't depend on any context
528     if (vin.empty())
529         return DoS(10, error("CTransaction::CheckTransaction() : vin empty"));
530     if (vout.empty())
531         return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
532     // Size limits
533     if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
534         return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));
535
536     // Check for negative or overflow output values
537     CBigNum nValueOut = 0;
538     for (uint32_t i = 0; i < vout.size(); i++)
539     {
540         const auto& txout = vout[i];
541         if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake())
542             return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction"));
543         if (!MoneyRange(txout.nValue))
544             return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue is out of range"));
545         nValueOut += txout.nValue;
546         if (!MoneyRange(nValueOut))
547             return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range"));
548     }
549
550     // Check for duplicate inputs
551     set<COutPoint> vInOutPoints;
552     for(const CTxIn& txin :  vin)
553     {
554         if (vInOutPoints.count(txin.prevout))
555             return false;
556         vInOutPoints.insert(txin.prevout);
557     }
558
559     if (IsCoinBase())
560     {
561         if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
562             return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size is invalid"));
563     }
564     else
565     {
566         for(const CTxIn& txin :  vin)
567             if (txin.prevout.IsNull())
568                 return DoS(10, error("CTransaction::CheckTransaction() : prevout is null"));
569     }
570
571     return true;
572 }
573
574 int64_t CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, enum GetMinFee_mode mode, unsigned int nBytes) const
575 {
576     int64_t nMinTxFee = MIN_TX_FEE, nMinRelayTxFee = MIN_RELAY_TX_FEE;
577
578     if(IsCoinStake())
579     {
580         // Enforce 0.01 as minimum fee for coinstake
581         nMinTxFee = CENT;
582         nMinRelayTxFee = CENT;
583     }
584
585     // Base fee is either nMinTxFee or nMinRelayTxFee
586     auto nBaseFee = (mode == GMF_RELAY) ? nMinRelayTxFee : nMinTxFee;
587
588     unsigned int nNewBlockSize = nBlockSize + nBytes;
589     int64_t nMinFee = (1 + (int64_t)nBytes / 1000) * nBaseFee;
590
591     if (fAllowFree)
592     {
593         if (nBlockSize == 1)
594         {
595             // Transactions under 1K are free
596             if (nBytes < 1000)
597                 nMinFee = 0;
598         }
599         else
600         {
601             // Free transaction area
602             if (nNewBlockSize < 27000)
603                 nMinFee = 0;
604         }
605     }
606
607     // To limit dust spam, require additional MIN_TX_FEE/MIN_RELAY_TX_FEE for
608     //    each non empty output which is less than 0.01
609     //
610     // It's safe to ignore empty outputs here, because these inputs are allowed
611     //     only for coinbase and coinstake transactions.
612     for(const CTxOut& txout :  vout)
613         if (txout.nValue < CENT && !txout.IsEmpty())
614             nMinFee += nBaseFee;
615
616     // Raise the price as the block approaches full
617     if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
618     {
619         if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
620             return MAX_MONEY;
621         nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
622     }
623
624     if (!MoneyRange(nMinFee))
625         nMinFee = MAX_MONEY;
626
627     return nMinFee;
628 }
629
630 string CTransaction::ToStringShort() const
631 {
632     string str;
633     str += strprintf("%s %s", GetHash().ToString().c_str(), IsCoinBase()? "base" : (IsCoinStake()? "stake" : "user"));
634     return str;
635 }
636
637 string CTransaction::ToString() const
638 {
639     string str;
640     str += IsCoinBase()? "Coinbase" : (IsCoinStake()? "Coinstake" : "CTransaction");
641     str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%" PRIszu ", vout.size=%" PRIszu ", nLockTime=%d)\n",
642         GetHash().ToString().substr(0,10).c_str(),
643         nTime,
644         nVersion,
645         vin.size(),
646         vout.size(),
647         nLockTime);
648     for (unsigned int i = 0; i < vin.size(); i++)
649         str += "    " + vin[i].ToString() + "\n";
650     for (unsigned int i = 0; i < vout.size(); i++)
651         str += "    " + vout[i].ToString() + "\n";
652     return str;
653 }
654
655 bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
656                         bool* pfMissingInputs)
657 {
658     if (pfMissingInputs)
659         *pfMissingInputs = false;
660
661     // Time (prevent mempool memory exhaustion attack)
662     if (tx.nTime > FutureDrift(GetAdjustedTime()))
663         return tx.DoS(10, error("CTxMemPool::accept() : transaction timestamp is too far in the future"));
664
665     if (!tx.CheckTransaction())
666         return error("CTxMemPool::accept() : CheckTransaction failed");
667
668     // Coinbase is only valid in a block, not as a loose transaction
669     if (tx.IsCoinBase())
670         return tx.DoS(100, error("CTxMemPool::accept() : coinbase as individual tx"));
671
672     // ppcoin: coinstake is also only valid in a block, not as a loose transaction
673     if (tx.IsCoinStake())
674         return tx.DoS(100, error("CTxMemPool::accept() : coinstake as individual tx"));
675
676     // To help v0.1.5 clients who would see it as a negative number
677     if ((int64_t)tx.nLockTime > std::numeric_limits<int>::max())
678         return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet");
679
680     // Rather not work on nonstandard transactions (unless -testnet)
681     string strNonStd;
682     if (!fTestNet && !tx.IsStandard(strNonStd))
683         return error("CTxMemPool::accept() : nonstandard transaction (%s)", strNonStd.c_str());
684
685     // Do we already have it?
686     auto hash = tx.GetHash();
687     {
688         LOCK(cs);
689         if (mapTx.count(hash))
690             return false;
691     }
692     if (fCheckInputs)
693         if (txdb.ContainsTx(hash))
694             return false;
695
696     // Check for conflicts with in-memory transactions
697     for (unsigned int i = 0; i < tx.vin.size(); i++)
698     {
699         auto outpoint = tx.vin[i].prevout;
700         if (mapNextTx.count(outpoint))
701         {
702             // Replacement feature isn't supported by Novacoin.
703             return false;
704         }
705     }
706
707     if (fCheckInputs)
708     {
709         MapPrevTx mapInputs;
710         map<uint256, CTxIndex> mapUnused;
711         bool fInvalid = false;
712         if (!tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
713         {
714             if (fInvalid)
715                 return error("CTxMemPool::accept() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
716             if (pfMissingInputs)
717                 *pfMissingInputs = true;
718             return false;
719         }
720
721         // Check for non-standard pay-to-script-hash in inputs
722         if (!tx.AreInputsStandard(mapInputs) && !fTestNet)
723             return error("CTxMemPool::accept() : nonstandard transaction input");
724
725         // Note: if you modify this code to accept non-standard transactions, then
726         // you should add code here to check that the transaction does a
727         // reasonable number of ECDSA signature verifications.
728
729         auto nFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
730         unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
731
732         // Don't accept it if it can't get into a block
733         auto txMinFee = tx.GetMinFee(1000, true, GMF_RELAY, nSize);
734         if (nFees < txMinFee)
735             return error("CTxMemPool::accept() : not enough fees %s, %" PRId64 " < %" PRId64,
736                          hash.ToString().c_str(),
737                          nFees, txMinFee);
738
739         // Continuously rate-limit free transactions
740         // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
741         // be annoying or make others' transactions take longer to confirm.
742         if (nFees < MIN_RELAY_TX_FEE)
743         {
744             static CCriticalSection cs;
745             static double dFreeCount;
746             static int64_t nLastTime;
747             auto nNow = GetTime();
748
749             {
750                 LOCK(cs);
751                 // Use an exponentially decaying ~10-minute window:
752                 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
753                 nLastTime = nNow;
754                 // -limitfreerelay unit is thousand-bytes-per-minute
755                 // At default rate it would take over a month to fill 1GB
756                 if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(tx))
757                     return error("CTxMemPool::accept() : free transaction rejected by rate limiter");
758                 if (fDebug)
759                     printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
760                 dFreeCount += nSize;
761             }
762         }
763
764         // Check against previous transactions
765         // This is done last to help prevent CPU exhaustion denial-of-service attacks.
766         if (!tx.ConnectInputs(txdb, mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false, true, STRICT_FLAGS))
767         {
768             return error("CTxMemPool::accept() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
769         }
770     }
771
772     // Store transaction in memory
773     {
774         LOCK(cs);
775         addUnchecked(hash, tx);
776     }
777
778     printf("CTxMemPool::accept() : accepted %s (poolsz %" PRIszu ")\n",
779            hash.ToString().substr(0,10).c_str(),
780            mapTx.size());
781     return true;
782 }
783
784 bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
785 {
786     return mempool.accept(txdb, *this, fCheckInputs, pfMissingInputs);
787 }
788
789 bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx)
790 {
791     // Add to memory pool without checking anything.  Don't call this directly,
792     // call CTxMemPool::accept to properly check the transaction first.
793     {
794         mapTx[hash] = tx;
795         for (unsigned int i = 0; i < tx.vin.size(); i++)
796             mapNextTx[tx.vin[i].prevout] = CInPoint(&mapTx[hash], i);
797         nTransactionsUpdated++;
798     }
799     return true;
800 }
801
802
803 bool CTxMemPool::remove(CTransaction &tx)
804 {
805     // Remove transaction from memory pool
806     {
807         LOCK(cs);
808         auto hash = tx.GetHash();
809         if (mapTx.count(hash))
810         {
811             for(const CTxIn& txin :  tx.vin)
812                 mapNextTx.erase(txin.prevout);
813             mapTx.erase(hash);
814             nTransactionsUpdated++;
815         }
816     }
817     return true;
818 }
819
820 void CTxMemPool::clear()
821 {
822     LOCK(cs);
823     mapTx.clear();
824     mapNextTx.clear();
825     ++nTransactionsUpdated;
826 }
827
828 void CTxMemPool::queryHashes(std::vector<uint256>& vtxid)
829 {
830     vtxid.clear();
831
832     LOCK(cs);
833     vtxid.reserve(mapTx.size());
834     for (auto mi = mapTx.begin(); mi != mapTx.end(); ++mi)
835         vtxid.push_back((*mi).first);
836 }
837
838
839 string CTxIn::ToString() const
840 {
841     string str;
842     str += "CTxIn(";
843     str += CTxIn::prevout.ToString();
844     if (CTxIn::prevout.IsNull())
845         str += strprintf(", coinbase %s", HexStr(CTxIn::scriptSig).c_str());
846     else
847         str += strprintf(", scriptSig=%s", CTxIn::scriptSig.ToString().substr(0,24).c_str());
848     if (CTxIn::nSequence != numeric_limits<unsigned int>::max())
849         str += strprintf(", nSequence=%" PRIu32, CTxIn::nSequence);
850     str += ")";
851     return str;
852 }
853
854
855 int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
856 {
857     if (hashBlock == 0 || nIndex == -1)
858         return 0;
859
860     // Find the block it claims to be in
861     auto mi = mapBlockIndex.find(hashBlock);
862     if (mi == mapBlockIndex.end())
863         return 0;
864     CBlockIndex* pindex = (*mi).second;
865     if (!pindex || !pindex->IsInMainChain())
866         return 0;
867
868     // Make sure the merkle branch connects to this block
869     if (!fMerkleVerified)
870     {
871         if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
872             return 0;
873         fMerkleVerified = true;
874     }
875
876     pindexRet = pindex;
877     return pindexBest->nHeight - pindex->nHeight + 1;
878 }
879
880
881 int CMerkleTx::GetBlocksToMaturity() const
882 {
883     if (!(IsCoinBase() || IsCoinStake()))
884         return 0;
885     return max(0, (nCoinbaseMaturity+20) - GetDepthInMainChain());
886 }
887
888
889 bool CMerkleTx::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs)
890 {
891     if (fClient)
892     {
893         if (!IsInMainChain() && !ClientConnectInputs())
894             return false;
895         return CTransaction::AcceptToMemoryPool(txdb, false);
896     }
897     else
898     {
899         return CTransaction::AcceptToMemoryPool(txdb, fCheckInputs);
900     }
901 }
902
903 bool CMerkleTx::AcceptToMemoryPool()
904 {
905     CTxDB txdb("r");
906     return AcceptToMemoryPool(txdb);
907 }
908
909
910
911 bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
912 {
913
914     {
915         LOCK(mempool.cs);
916         // Add previous supporting transactions first
917         for(CMerkleTx& tx :  vtxPrev)
918         {
919             if (!(tx.IsCoinBase() || tx.IsCoinStake()))
920             {
921                 auto hash = tx.GetHash();
922                 if (!mempool.exists(hash) && !txdb.ContainsTx(hash))
923                     tx.AcceptToMemoryPool(txdb, fCheckInputs);
924             }
925         }
926         return AcceptToMemoryPool(txdb, fCheckInputs);
927     }
928     return false;
929 }
930
931 bool CWalletTx::AcceptWalletTransaction()
932 {
933     CTxDB txdb("r");
934     return AcceptWalletTransaction(txdb);
935 }
936
937 int CTxIndex::GetDepthInMainChain() const
938 {
939     // Read block header
940     CBlock block;
941     if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false))
942         return 0;
943     // Find the block in the index
944     auto mi = mapBlockIndex.find(block.GetHash());
945     if (mi == mapBlockIndex.end())
946         return 0;
947     auto pindex = (*mi).second;
948     if (!pindex || !pindex->IsInMainChain())
949         return 0;
950     return 1 + nBestHeight - pindex->nHeight;
951 }
952
953 // Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
954 bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock)
955 {
956     {
957         LOCK(cs_main);
958         {
959             LOCK(mempool.cs);
960             if (mempool.exists(hash))
961             {
962                 tx = mempool.lookup(hash);
963                 return true;
964             }
965         }
966         CTxDB txdb("r");
967         CTxIndex txindex;
968         if (tx.ReadFromDisk(txdb, COutPoint(hash, 0), txindex))
969         {
970             CBlock block;
971             if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
972                 hashBlock = block.GetHash();
973             return true;
974         }
975     }
976     return false;
977 }
978
979
980 // Closure representing one script verification
981 // Note that this stores references to the spending transaction
982 class CScriptCheck
983 {
984 private:
985     CScript scriptPubKey;
986     const CTransaction *ptxTo = nullptr;
987     uint32_t nIn = 0;
988     unsigned int nFlags = 0;
989     int nHashType = 0;
990
991 public:
992     CScriptCheck() {}
993     CScriptCheck(const CTransaction& txFromIn, const CTransaction& txToIn, uint32_t nInIn, unsigned int nFlagsIn, int nHashTypeIn) :
994         scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey),
995         ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), nHashType(nHashTypeIn) { }
996
997     bool operator()() const;
998
999     void swap(CScriptCheck &check) {
1000         scriptPubKey.swap(check.scriptPubKey);
1001         std::swap(ptxTo, check.ptxTo);
1002         std::swap(nIn, check.nIn);
1003         std::swap(nFlags, check.nFlags);
1004         std::swap(nHashType, check.nHashType);
1005     }
1006 };
1007
1008
1009
1010
1011 //////////////////////////////////////////////////////////////////////////////
1012 //
1013 // CBlock and CBlockIndex
1014 //
1015
1016 static CBlockIndex* pblockindexFBBHLast;
1017 CBlockIndex* FindBlockByHeight(int nHeight)
1018 {
1019     CBlockIndex *pblockindex;
1020     if (nHeight < nBestHeight / 2)
1021         pblockindex = pindexGenesisBlock;
1022     else
1023         pblockindex = pindexBest;
1024     if (pblockindexFBBHLast && abs(nHeight - pblockindex->nHeight) > abs(nHeight - pblockindexFBBHLast->nHeight))
1025         pblockindex = pblockindexFBBHLast;
1026     while (pblockindex->nHeight > nHeight)
1027         pblockindex = pblockindex->pprev;
1028     while (pblockindex->nHeight < nHeight)
1029         pblockindex = pblockindex->pnext;
1030     pblockindexFBBHLast = pblockindex;
1031     return pblockindex;
1032 }
1033
1034 bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
1035 {
1036     if (!fReadTransactions)
1037     {
1038         *this = pindex->GetBlockHeader();
1039         return true;
1040     }
1041     if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions))
1042         return false;
1043     if (GetHash() != pindex->GetBlockHash())
1044         return error("CBlock::ReadFromDisk() : GetHash() doesn't match index");
1045     return true;
1046 }
1047
1048 uint256 static GetOrphanRoot(const CBlock* pblock)
1049 {
1050     // Work back to the first block in the orphan chain
1051     while (mapOrphanBlocks.count(pblock->hashPrevBlock))
1052         pblock = mapOrphanBlocks[pblock->hashPrevBlock];
1053     return pblock->GetHash();
1054 }
1055
1056 // ppcoin: find block wanted by given orphan block
1057 uint256 WantedByOrphan(const CBlock* pblockOrphan)
1058 {
1059     // Work back to the first block in the orphan chain
1060     while (mapOrphanBlocks.count(pblockOrphan->hashPrevBlock))
1061         pblockOrphan = mapOrphanBlocks[pblockOrphan->hashPrevBlock];
1062     return pblockOrphan->hashPrevBlock;
1063 }
1064
1065 // select stake target limit according to hard-coded conditions
1066 CBigNum inline GetProofOfStakeLimit(int nHeight, unsigned int nTime)
1067 {
1068     if(fTestNet) // separate proof of stake target limit for testnet
1069         return bnProofOfStakeLimit;
1070     if(nTime > TARGETS_SWITCH_TIME) // 27 bits since 20 July 2013
1071         return bnProofOfStakeLimit;
1072     if(nHeight + 1 > 15000) // 24 bits since block 15000
1073         return bnProofOfStakeLegacyLimit;
1074     if(nHeight + 1 > 14060) // 31 bits since block 14060 until 15000
1075         return bnProofOfStakeHardLimit;
1076
1077     return bnProofOfWorkLimit; // return bnProofOfWorkLimit of none matched
1078 }
1079
1080 // miner's coin base reward based on nBits
1081 int64_t GetProofOfWorkReward(unsigned int nBits, int64_t nFees)
1082 {
1083     CBigNum bnSubsidyLimit = MAX_MINT_PROOF_OF_WORK;
1084
1085     CBigNum bnTarget;
1086     bnTarget.SetCompact(nBits);
1087     CBigNum bnTargetLimit = bnProofOfWorkLimit;
1088     bnTargetLimit.SetCompact(bnTargetLimit.GetCompact());
1089
1090     // NovaCoin: subsidy is cut in half every 64x multiply of PoW difficulty
1091     // A reasonably continuous curve is used to avoid shock to market
1092     // (nSubsidyLimit / nSubsidy) ** 6 == bnProofOfWorkLimit / bnTarget
1093     //
1094     // Human readable form:
1095     //
1096     // nSubsidy = 100 / (diff ^ 1/6)
1097     //
1098     // Please note that we're using bisection to find an approximate solutuion
1099     CBigNum bnLowerBound = CENT;
1100     CBigNum bnUpperBound = bnSubsidyLimit;
1101     while (bnLowerBound + CENT <= bnUpperBound)
1102     {
1103         CBigNum bnMidValue = (bnLowerBound + bnUpperBound) / 2;
1104         if (bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit > bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnTarget)
1105             bnUpperBound = bnMidValue;
1106         else
1107             bnLowerBound = bnMidValue;
1108     }
1109
1110     int64_t nSubsidy = bnUpperBound.getuint64();
1111
1112     nSubsidy = (nSubsidy / CENT) * CENT;
1113     if (fDebug && GetBoolArg("-printcreation"))
1114         printf("GetProofOfWorkReward() : create=%s nBits=0x%08x nSubsidy=%" PRId64 "\n", FormatMoney(nSubsidy).c_str(), nBits, nSubsidy);
1115
1116     return min(nSubsidy, MAX_MINT_PROOF_OF_WORK) + nFees;
1117 }
1118
1119 // miner's coin stake reward based on nBits and coin age spent (coin-days)
1120 int64_t GetProofOfStakeReward(int64_t nCoinAge, unsigned int nBits, int64_t nTime, bool bCoinYearOnly)
1121 {
1122     int64_t nRewardCoinYear, nSubsidy, nSubsidyLimit = 10 * COIN;
1123
1124     // Stage 2 of emission process is mostly PoS-based.
1125
1126     CBigNum bnRewardCoinYearLimit = MAX_MINT_PROOF_OF_STAKE; // Base stake mint rate, 100% year interest
1127     CBigNum bnTarget;
1128     bnTarget.SetCompact(nBits);
1129     CBigNum bnTargetLimit = GetProofOfStakeLimit(0, nTime);
1130     bnTargetLimit.SetCompact(bnTargetLimit.GetCompact());
1131
1132     // A reasonably continuous curve is used to avoid shock to market
1133
1134     CBigNum bnLowerBound = 1 * CENT, // Lower interest bound is 1% per year
1135         bnUpperBound = bnRewardCoinYearLimit, // Upper interest bound is 100% per year
1136         bnMidPart, bnRewardPart;
1137
1138     while (bnLowerBound + CENT <= bnUpperBound)
1139     {
1140         auto bnMidValue = (bnLowerBound + bnUpperBound) / 2;
1141
1142         //
1143         // Reward for coin-year is cut in half every 8x multiply of PoS difficulty
1144         //
1145         // (nRewardCoinYearLimit / nRewardCoinYear) ** 3 == bnProofOfStakeLimit / bnTarget
1146         //
1147         // Human readable form: nRewardCoinYear = 1 / (posdiff ^ 1/3)
1148         //
1149
1150         bnMidPart = bnMidValue * bnMidValue * bnMidValue;
1151         bnRewardPart = bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit;
1152
1153         if (bnMidPart * bnTargetLimit > bnRewardPart * bnTarget)
1154             bnUpperBound = bnMidValue;
1155         else
1156             bnLowerBound = bnMidValue;
1157     }
1158
1159     nRewardCoinYear = bnUpperBound.getuint64();
1160     nRewardCoinYear = min((nRewardCoinYear / CENT) * CENT, MAX_MINT_PROOF_OF_STAKE);
1161
1162     if(bCoinYearOnly)
1163         return nRewardCoinYear;
1164
1165     nSubsidy = nCoinAge * nRewardCoinYear * 33 / (365 * 33 + 8);
1166
1167     // Set reasonable reward limit for large inputs
1168     //
1169     // This will stimulate large holders to use smaller inputs, that's good for the network protection
1170
1171     if (fDebug && GetBoolArg("-printcreation") && nSubsidyLimit < nSubsidy)
1172         printf("GetProofOfStakeReward(): %s is greater than %s, coinstake reward will be truncated\n", FormatMoney(nSubsidy).c_str(), FormatMoney(nSubsidyLimit).c_str());
1173
1174     nSubsidy = min(nSubsidy, nSubsidyLimit);
1175
1176     if (fDebug && GetBoolArg("-printcreation"))
1177         printf("GetProofOfStakeReward(): create=%s nCoinAge=%" PRId64 " nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits);
1178
1179     return nSubsidy;
1180 }
1181
1182 static const int64_t nTargetTimespan = 7 * nOneDay;  // one week
1183
1184 // get proof of work blocks max spacing according to hard-coded conditions
1185 int64_t inline GetTargetSpacingWorkMax(int nHeight, unsigned int nTime)
1186 {
1187     if(nTime > TARGETS_SWITCH_TIME)
1188         return 3 * nStakeTargetSpacing; // 30 minutes on mainNet since 20 Jul 2013 00:00:00
1189
1190     if(fTestNet)
1191         return 3 * nStakeTargetSpacing; // 15 minutes on testNet
1192
1193     return 12 * nStakeTargetSpacing; // 2 hours otherwise
1194 }
1195
1196 //
1197 // maximum nBits value could possible be required nTime after
1198 //
1199 unsigned int ComputeMaxBits(CBigNum bnTargetLimit, unsigned int nBase, int64_t nTime)
1200 {
1201     CBigNum bnResult;
1202     bnResult.SetCompact(nBase);
1203     bnResult *= 2;
1204     while (nTime > 0 && bnResult < bnTargetLimit)
1205     {
1206         // Maximum 200% adjustment per day...
1207         bnResult *= 2;
1208         nTime -= nOneDay;
1209     }
1210     if (bnResult > bnTargetLimit)
1211         bnResult = bnTargetLimit;
1212     return bnResult.GetCompact();
1213 }
1214
1215 //
1216 // minimum amount of work that could possibly be required nTime after
1217 // minimum proof-of-work required was nBase
1218 //
1219 unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime)
1220 {
1221     return ComputeMaxBits(bnProofOfWorkLimit, nBase, nTime);
1222 }
1223
1224 //
1225 // minimum amount of stake that could possibly be required nTime after
1226 // minimum proof-of-stake required was nBase
1227 //
1228 unsigned int ComputeMinStake(unsigned int nBase, int64_t nTime, unsigned int nBlockTime)
1229 {
1230     return ComputeMaxBits(GetProofOfStakeLimit(0, nBlockTime), nBase, nTime);
1231 }
1232
1233
1234 // ppcoin: find last block index up to pindex
1235 const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake)
1236 {
1237     while (pindex && pindex->pprev && (pindex->IsProofOfStake() != fProofOfStake))
1238         pindex = pindex->pprev;
1239     return pindex;
1240 }
1241
1242 unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake)
1243 {
1244     if (pindexLast == NULL)
1245         return bnProofOfWorkLimit.GetCompact(); // genesis block
1246
1247     CBigNum bnTargetLimit = !fProofOfStake ? bnProofOfWorkLimit : GetProofOfStakeLimit(pindexLast->nHeight, pindexLast->nTime);
1248
1249     const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake);
1250     if (pindexPrev->pprev == NULL)
1251         return bnTargetLimit.GetCompact(); // first block
1252     const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake);
1253     if (pindexPrevPrev->pprev == NULL)
1254         return bnTargetLimit.GetCompact(); // second block
1255
1256     int64_t nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime();
1257
1258     // ppcoin: target change every block
1259     // ppcoin: retarget with exponential moving toward target spacing
1260     CBigNum bnNew;
1261     bnNew.SetCompact(pindexPrev->nBits);
1262     int64_t nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(GetTargetSpacingWorkMax(pindexLast->nHeight, pindexLast->nTime), (int64_t) nStakeTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight));
1263     int64_t nInterval = nTargetTimespan / nTargetSpacing;
1264     bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);
1265     bnNew /= ((nInterval + 1) * nTargetSpacing);
1266
1267     if (bnNew > bnTargetLimit)
1268         bnNew = bnTargetLimit;
1269
1270     return bnNew.GetCompact();
1271 }
1272
1273 bool CheckProofOfWork(uint256 hash, unsigned int nBits)
1274 {
1275     CBigNum bnTarget;
1276     bnTarget.SetCompact(nBits);
1277
1278     // Check range
1279     if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit)
1280         return error("CheckProofOfWork() : nBits below minimum work");
1281
1282     // Check proof of work matches claimed amount
1283     if (hash > bnTarget.getuint256())
1284         return error("CheckProofOfWork() : hash doesn't match nBits");
1285
1286     return true;
1287 }
1288
1289 // Return maximum amount of blocks that other nodes claim to have
1290 int GetNumBlocksOfPeers()
1291 {
1292     return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate());
1293 }
1294
1295 bool IsInitialBlockDownload()
1296 {
1297     if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate())
1298         return true;
1299     static int64_t nLastUpdate;
1300     static CBlockIndex* pindexLastBest;
1301     auto nCurrentTime = GetTime();
1302     if (pindexBest != pindexLastBest)
1303     {
1304         pindexLastBest = pindexBest;
1305         nLastUpdate = nCurrentTime;
1306     }
1307     return (nCurrentTime - nLastUpdate < 10 &&
1308             pindexBest->GetBlockTime() < nCurrentTime - nOneDay);
1309 }
1310
1311 void static InvalidChainFound(CBlockIndex* pindexNew)
1312 {
1313     if (pindexNew->nChainTrust > nBestInvalidTrust)
1314     {
1315         nBestInvalidTrust = pindexNew->nChainTrust;
1316         CTxDB().WriteBestInvalidTrust(CBigNum(nBestInvalidTrust));
1317         uiInterface.NotifyBlocksChanged();
1318     }
1319
1320     auto nBestInvalidBlockTrust = pindexNew->nChainTrust - pindexNew->pprev->nChainTrust;
1321     auto nBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->nChainTrust - pindexBest->pprev->nChainTrust) : pindexBest->nChainTrust;
1322
1323     printf("InvalidChainFound: invalid block=%s  height=%d  trust=%s  blocktrust=%" PRId64 "  date=%s\n",
1324       pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight,
1325       CBigNum(pindexNew->nChainTrust).ToString().c_str(), nBestInvalidBlockTrust.Get64(),
1326       DateTimeStrFormat("%x %H:%M:%S", pindexNew->GetBlockTime()).c_str());
1327     printf("InvalidChainFound:  current best=%s  height=%d  trust=%s  blocktrust=%" PRId64 "  date=%s\n",
1328       hashBestChain.ToString().substr(0,20).c_str(), nBestHeight,
1329       CBigNum(pindexBest->nChainTrust).ToString().c_str(),
1330       nBestBlockTrust.Get64(),
1331       DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str());
1332 }
1333
1334 void CBlock::UpdateTime(const CBlockIndex* pindexPrev)
1335 {
1336     nTime = max(GetBlockTime(), GetAdjustedTime());
1337 }
1338
1339 unsigned int CBlock::GetStakeEntropyBit(unsigned int nHeight) const
1340 {
1341     // Protocol switch to support p2pool at novacoin block #9689
1342     if (nHeight >= 9689 || fTestNet)
1343     {
1344         // Take last bit of block hash as entropy bit
1345         auto nEntropyBit = (GetHash().Get32()) & (uint32_t)1;
1346         if (fDebug && GetBoolArg("-printstakemodifier"))
1347             printf("GetStakeEntropyBit: nTime=%" PRIu32 " hashBlock=%s nEntropyBit=%" PRIu32 "\n", nTime, GetHash().ToString().c_str(), nEntropyBit);
1348         return nEntropyBit;
1349     }
1350
1351     // Before novacoin block #9689 - get from pregenerated table
1352     int nBitNum = nHeight & 0xFF;
1353     int nItemNum = nHeight / 0xFF;
1354
1355     auto nEntropyBit = ((entropyStore[nItemNum] & (uint256(1) << nBitNum)) >> nBitNum).Get32();
1356     if (fDebug && GetBoolArg("-printstakemodifier"))
1357         printf("GetStakeEntropyBit: from pregenerated table, nHeight=%" PRIu32 " nEntropyBit=%" PRIu32 "\n", nHeight, nEntropyBit);
1358     return nEntropyBit;
1359 }
1360
1361 bool CTransaction::DisconnectInputs(CTxDB& txdb)
1362 {
1363     // Relinquish previous transactions' spent pointers
1364     if (!IsCoinBase())
1365     {
1366         for(const CTxIn& txin :  vin)
1367         {
1368             auto prevout = txin.prevout;
1369
1370             // Get prev txindex from disk
1371             CTxIndex txindex;
1372             if (!txdb.ReadTxIndex(prevout.hash, txindex))
1373                 return error("DisconnectInputs() : ReadTxIndex failed");
1374
1375             if (prevout.n >= txindex.vSpent.size())
1376                 return error("DisconnectInputs() : prevout.n out of range");
1377
1378             // Mark outpoint as not spent
1379             txindex.vSpent[prevout.n].SetNull();
1380
1381             // Write back
1382             if (!txdb.UpdateTxIndex(prevout.hash, txindex))
1383                 return error("DisconnectInputs() : UpdateTxIndex failed");
1384         }
1385     }
1386
1387     // Remove transaction from index
1388     // This can fail if a duplicate of this transaction was in a chain that got
1389     // reorganized away. This is only possible if this transaction was completely
1390     // spent, so erasing it would be a no-op anyway.
1391     txdb.EraseTxIndex(*this);
1392
1393     return true;
1394 }
1395
1396
1397 bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTestPool,
1398                                bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid)
1399 {
1400     // FetchInputs can return false either because we just haven't seen some inputs
1401     // (in which case the transaction should be stored as an orphan)
1402     // or because the transaction is malformed (in which case the transaction should
1403     // be dropped).  If tx is definitely invalid, fInvalid will be set to true.
1404     fInvalid = false;
1405
1406     if (IsCoinBase())
1407         return true; // Coinbase transactions have no inputs to fetch.
1408
1409     for (unsigned int i = 0; i < vin.size(); i++)
1410     {
1411         auto prevout = vin[i].prevout;
1412         if (inputsRet.count(prevout.hash))
1413             continue; // Got it already
1414
1415         // Read txindex
1416         CTxIndex& txindex = inputsRet[prevout.hash].first;
1417         bool fFound = true;
1418         if ((fBlock || fMiner) && mapTestPool.count(prevout.hash))
1419         {
1420             // Get txindex from current proposed changes
1421             txindex = mapTestPool.find(prevout.hash)->second;
1422         }
1423         else
1424         {
1425             // Read txindex from txdb
1426             fFound = txdb.ReadTxIndex(prevout.hash, txindex);
1427         }
1428         if (!fFound && (fBlock || fMiner))
1429             return fMiner ? false : error("FetchInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(),  prevout.hash.ToString().substr(0,10).c_str());
1430
1431         // Read txPrev
1432         CTransaction& txPrev = inputsRet[prevout.hash].second;
1433         if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
1434         {
1435             // Get prev tx from single transactions in memory
1436             {
1437                 LOCK(mempool.cs);
1438                 if (!mempool.exists(prevout.hash))
1439                     return error("FetchInputs() : %s mempool Tx prev not found %s", GetHash().ToString().substr(0,10).c_str(),  prevout.hash.ToString().substr(0,10).c_str());
1440                 txPrev = mempool.lookup(prevout.hash);
1441             }
1442             if (!fFound)
1443                 txindex.vSpent.resize(txPrev.vout.size());
1444         }
1445         else
1446         {
1447             // Get prev tx from disk
1448             if (!txPrev.ReadFromDisk(txindex.pos))
1449                 return error("FetchInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(),  prevout.hash.ToString().substr(0,10).c_str());
1450         }
1451     }
1452
1453     // Make sure all prevout.n indexes are valid:
1454     for (unsigned int i = 0; i < vin.size(); i++)
1455     {
1456         const COutPoint prevout = vin[i].prevout;
1457         assert(inputsRet.count(prevout.hash) != 0);
1458         const CTxIndex& txindex = inputsRet[prevout.hash].first;
1459         const CTransaction& txPrev = inputsRet[prevout.hash].second;
1460         if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
1461         {
1462             // Revisit this if/when transaction replacement is implemented and allows
1463             // adding inputs:
1464             fInvalid = true;
1465             return DoS(100, error("FetchInputs() : %s prevout.n out of range %d %" PRIszu " %" PRIszu " prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
1466         }
1467     }
1468
1469     return true;
1470 }
1471
1472 const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const
1473 {
1474     auto mi = inputs.find(input.prevout.hash);
1475     if (mi == inputs.end())
1476         throw std::runtime_error("CTransaction::GetOutputFor() : prevout.hash not found");
1477
1478     const auto& txPrev = (mi->second).second;
1479     if (input.prevout.n >= txPrev.vout.size())
1480         throw std::runtime_error("CTransaction::GetOutputFor() : prevout.n out of range");
1481
1482     return txPrev.vout[input.prevout.n];
1483 }
1484
1485 int64_t CTransaction::GetValueOut() const
1486 {
1487     CBigNum nValueOut = 0;
1488     for(const auto& txout :  vout)
1489     {
1490         nValueOut += txout.nValue;
1491         if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
1492             throw runtime_error("CTransaction::GetValueOut() : value out of range");
1493     }
1494     return nValueOut.getint64();
1495 }
1496
1497 int64_t CTransaction::GetValueIn(const MapPrevTx& inputs) const
1498 {
1499     if (IsCoinBase())
1500         return 0;
1501
1502     CBigNum nResult = 0;
1503     for (uint32_t i = 0; i < vin.size(); i++)
1504     {
1505         const auto& txOut = GetOutputFor(vin[i], inputs);
1506         nResult += txOut.nValue;
1507         if (!MoneyRange(txOut.nValue) || !MoneyRange(nResult))
1508             throw runtime_error("CTransaction::GetValueIn() : value out of range");
1509     }
1510     return nResult.getint64();
1511
1512 }
1513
1514 unsigned int CTransaction::GetP2SHSigOpCount(const MapPrevTx& inputs) const
1515 {
1516     if (IsCoinBase())
1517         return 0;
1518
1519     unsigned int nSigOps = 0;
1520     for (unsigned int i = 0; i < vin.size(); i++)
1521     {
1522         const CTxOut& prevout = GetOutputFor(vin[i], inputs);
1523         if (prevout.scriptPubKey.IsPayToScriptHash())
1524             nSigOps += prevout.scriptPubKey.GetSigOpCount(vin[i].scriptSig);
1525     }
1526     return nSigOps;
1527 }
1528
1529 bool CScriptCheck::operator()() const {
1530     const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1531     if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags, nHashType))
1532         return error("CScriptCheck() : %s VerifySignature failed", ptxTo->GetHash().ToString().substr(0,10).c_str());
1533     return true;
1534 }
1535
1536 bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, uint32_t nIn, unsigned int flags, int nHashType)
1537 {
1538     return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)();
1539 }
1540
1541 bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
1542     const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks)
1543 {
1544     // Take over previous transactions' spent pointers
1545     // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain
1546     // fMiner is true when called from the internal bitcoin miner
1547     // ... both are false when called from CTransaction::AcceptToMemoryPool
1548
1549     if (!IsCoinBase())
1550     {
1551         int64_t nValueIn = 0;
1552         {
1553             CBigNum bnValueIn = 0;
1554             for (uint32_t i = 0; i < vin.size(); i++)
1555             {
1556                 auto prevout = vin[i].prevout;
1557                 assert(inputs.count(prevout.hash) > 0);
1558                 CTxIndex& txindex = inputs[prevout.hash].first;
1559                 CTransaction& txPrev = inputs[prevout.hash].second;
1560
1561                 if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
1562                     return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %" PRIszu " %" PRIszu " prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
1563
1564                 // If prev is coinbase or coinstake, check that it's matured
1565                 if (txPrev.IsCoinBase() || txPrev.IsCoinStake())
1566                     for (const CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < nCoinbaseMaturity; pindex = pindex->pprev)
1567                         if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
1568                             return error("ConnectInputs() : tried to spend %s at depth %d", txPrev.IsCoinBase() ? "coinbase" : "coinstake", pindexBlock->nHeight - pindex->nHeight);
1569
1570                 // ppcoin: check transaction timestamp
1571                 if (txPrev.nTime > nTime)
1572                     return DoS(100, error("ConnectInputs() : transaction timestamp earlier than input transaction"));
1573
1574                 // Check for negative or overflow input values
1575                 bnValueIn += txPrev.vout[prevout.n].nValue;
1576                 if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(bnValueIn))
1577                     return DoS(100, error("ConnectInputs() : txin values out of range"));
1578             }
1579             nValueIn = bnValueIn.getint64();
1580         }
1581
1582         if (pvChecks)
1583             pvChecks->reserve(vin.size());
1584
1585         // The first loop above does all the inexpensive checks.
1586         // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
1587         // Helps prevent CPU exhaustion attacks.
1588         for (unsigned int i = 0; i < vin.size(); i++)
1589         {
1590             auto prevout = vin[i].prevout;
1591             assert(inputs.count(prevout.hash) > 0);
1592             CTxIndex& txindex = inputs[prevout.hash].first;
1593             CTransaction& txPrev = inputs[prevout.hash].second;
1594
1595             // Check for conflicts (double-spend)
1596             // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
1597             // for an attacker to attempt to split the network.
1598             if (!txindex.vSpent[prevout.n].IsNull())
1599                 return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
1600
1601             // Skip ECDSA signature verification when connecting blocks (fBlock=true)
1602             // before the last blockchain checkpoint. This is safe because block merkle hashes are
1603             // still computed and checked, and any change will be caught at the next checkpoint.
1604             if (fScriptChecks)
1605             {
1606                 // Verify signature
1607                 CScriptCheck check(txPrev, *this, i, flags, 0);
1608                 if (pvChecks)
1609                 {
1610                     pvChecks->push_back(CScriptCheck());
1611                     check.swap(pvChecks->back());
1612                 }
1613                 else if (!check())
1614                 {
1615                     if (flags & STRICT_FLAGS)
1616                     {
1617                         // Don't trigger DoS code in case of STRICT_FLAGS caused failure.
1618                         CScriptCheck check(txPrev, *this, i, flags & ~STRICT_FLAGS, 0);
1619                         if (check())
1620                             return error("ConnectInputs() : %s strict VerifySignature failed", GetHash().ToString().substr(0,10).c_str());
1621                     }
1622                     return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()));
1623                 }
1624             }
1625
1626             // Mark outpoints as spent
1627             txindex.vSpent[prevout.n] = posThisTx;
1628
1629             // Write back
1630             if (fBlock || fMiner)
1631             {
1632                 mapTestPool[prevout.hash] = txindex;
1633             }
1634         }
1635
1636         if (IsCoinStake())
1637         {
1638             if (nTime >  Checkpoints::GetLastCheckpointTime())
1639             {
1640                 unsigned int nTxSize = GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION);
1641
1642                 // coin stake tx earns reward instead of paying fee
1643                 uint64_t nCoinAge;
1644                 if (!GetCoinAge(txdb, nCoinAge))
1645                     return error("ConnectInputs() : %s unable to get coin age for coinstake", GetHash().ToString().substr(0,10).c_str());
1646
1647                 auto nReward = GetValueOut() - nValueIn;
1648                 auto nCalculatedReward = GetProofOfStakeReward(nCoinAge, pindexBlock->nBits, nTime) - GetMinFee(1, false, GMF_BLOCK, nTxSize) + CENT;
1649
1650                 if (nReward > nCalculatedReward)
1651                     return DoS(100, error("ConnectInputs() : coinstake pays too much(actual=%" PRId64 " vs calculated=%" PRId64 ")", nReward, nCalculatedReward));
1652             }
1653         }
1654         else
1655         {
1656             if (nValueIn < GetValueOut())
1657                 return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str()));
1658
1659             // Tally transaction fees
1660             auto nTxFee = nValueIn - GetValueOut();
1661             if (!MoneyRange(nTxFee))
1662                 return DoS(100, error("ConnectInputs() : nFees out of range"));
1663         }
1664     }
1665
1666     return true;
1667 }
1668
1669
1670 bool CTransaction::ClientConnectInputs()
1671 {
1672     if (IsCoinBase())
1673         return false;
1674
1675     // Take over previous transactions' spent pointers
1676     {
1677         LOCK(mempool.cs);
1678         CBigNum bnValueIn = 0;
1679         for (uint32_t i = 0; i < vin.size(); i++)
1680         {
1681             // Get prev tx from single transactions in memory
1682             auto prevout = vin[i].prevout;
1683             if (!mempool.exists(prevout.hash))
1684                 return false;
1685             CTransaction& txPrev = mempool.lookup(prevout.hash);
1686
1687             if (prevout.n >= txPrev.vout.size())
1688                 return false;
1689
1690             // Verify signature
1691             if (!VerifySignature(txPrev, *this, i, SCRIPT_VERIFY_NOCACHE | SCRIPT_VERIFY_P2SH, 0))
1692                 return error("ClientConnectInputs() : VerifySignature failed");
1693
1694             ///// this is redundant with the mempool.mapNextTx stuff,
1695             ///// not sure which I want to get rid of
1696             ///// this has to go away now that posNext is gone
1697             // // Check for conflicts
1698             // if (!txPrev.vout[prevout.n].posNext.IsNull())
1699             //     return error("ConnectInputs() : prev tx already used");
1700             //
1701             // // Flag outpoints as used
1702             // txPrev.vout[prevout.n].posNext = posThisTx;
1703
1704             bnValueIn += txPrev.vout[prevout.n].nValue;
1705
1706             if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(bnValueIn))
1707                 return error("ClientConnectInputs() : txin values out of range");
1708         }
1709         if (GetValueOut() > bnValueIn.getint64())
1710             return false;
1711     }
1712
1713     return true;
1714 }
1715
1716 int64_t CBlock::GetMaxTransactionTime() const
1717 {
1718     int64_t maxTransactionTime = 0;
1719     for(const auto& tx : vtx)
1720         maxTransactionTime = max(maxTransactionTime, (int64_t)tx.nTime);
1721     return maxTransactionTime;
1722 }
1723
1724 uint256 CBlock::BuildMerkleTree() const
1725 {
1726     vMerkleTree.clear();
1727     for(const auto& tx :  vtx)
1728         vMerkleTree.push_back(tx.GetHash());
1729     int j = 0;
1730     for (int nSize = (int)vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
1731     {
1732         for (int i = 0; i < nSize; i += 2)
1733         {
1734             int i2 = min(i+1, nSize-1);
1735             vMerkleTree.push_back(Hash(vMerkleTree[j+i].begin(),  vMerkleTree[j+i].end(),
1736                                        vMerkleTree[j+i2].begin(), vMerkleTree[j+i2].end()));
1737         }
1738         j += nSize;
1739     }
1740     return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
1741 }
1742
1743 vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
1744 {
1745     if (vMerkleTree.empty())
1746         BuildMerkleTree();
1747     vector<uint256> vMerkleBranch;
1748     int j = 0;
1749     for (int nSize = (int)vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
1750     {
1751         int i = min(nIndex^1, nSize-1);
1752         vMerkleBranch.push_back(vMerkleTree[j+i]);
1753         nIndex >>= 1;
1754         j += nSize;
1755     }
1756     return vMerkleBranch;
1757 }
1758
1759 uint256 CBlock::CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex)
1760 {
1761     if (nIndex == -1)
1762         return 0;
1763     for(const uint256& otherside :  vMerkleBranch)
1764     {
1765         if (nIndex & 1)
1766             hash = Hash(otherside.begin(), otherside.end(), hash.begin(), hash.end());
1767         else
1768             hash = Hash(hash.begin(), hash.end(), otherside.begin(), otherside.end());
1769         nIndex >>= 1;
1770     }
1771     return hash;
1772 }
1773
1774 bool CBlock::WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
1775 {
1776     // Open history file to append
1777     auto fileout = CAutoFile(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION);
1778     if (!fileout)
1779         return error("CBlock::WriteToDisk() : AppendBlockFile failed");
1780
1781     // Write index header
1782     unsigned int nSize = fileout.GetSerializeSize(*this);
1783     fileout << nNetworkID << nSize;
1784
1785     // Write block
1786     long fileOutPos = ftell(fileout);
1787     if (fileOutPos < 0)
1788         return error("CBlock::WriteToDisk() : ftell failed");
1789     nBlockPosRet = fileOutPos;
1790     fileout << *this;
1791
1792     // Flush stdio buffers and commit to disk before returning
1793     fflush(fileout);
1794     if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
1795         FileCommit(fileout);
1796
1797     return true;
1798 }
1799
1800 bool CBlock::ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions)
1801 {
1802     SetNull();
1803
1804     // Open history file to read
1805     auto filein = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb"), SER_DISK, CLIENT_VERSION);
1806     if (!filein)
1807         return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
1808     if (!fReadTransactions)
1809         filein.nType |= SER_BLOCKHEADERONLY;
1810
1811     // Read block
1812     try {
1813         filein >> *this;
1814     }
1815     catch (const std::exception&) {
1816         return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION);
1817     }
1818
1819     // Check the header
1820     if (fReadTransactions && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits))
1821         return error("CBlock::ReadFromDisk() : errors in block header");
1822
1823     return true;
1824 }
1825
1826 void CBlock::print() const
1827 {
1828     printf("CBlock(hash=%s, ver=%" PRId32 ", hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%" PRIu32 ", nBits=%08x, nNonce=%" PRIu32 ", vtx=%" PRIszu ", vchBlockSig=%s)\n",
1829         GetHash().ToString().c_str(),
1830         nVersion,
1831         hashPrevBlock.ToString().c_str(),
1832         hashMerkleRoot.ToString().c_str(),
1833         nTime, nBits, nNonce,
1834         vtx.size(),
1835         HexStr(vchBlockSig.begin(), vchBlockSig.end()).c_str());
1836     for (unsigned int i = 0; i < vtx.size(); i++)
1837     {
1838         printf("  ");
1839         vtx[i].print();
1840     }
1841     printf("  vMerkleTree: ");
1842     for (unsigned int i = 0; i < vMerkleTree.size(); i++)
1843         printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
1844     printf("\n");
1845 }
1846
1847 bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
1848 {
1849     // Disconnect in reverse order
1850     for (int i = vtx.size()-1; i >= 0; i--)
1851         if (!vtx[i].DisconnectInputs(txdb))
1852             return false;
1853
1854     // Update block index on disk without changing it in memory.
1855     // The memory index structure will be changed after the db commits.
1856     if (pindex->pprev)
1857     {
1858         CDiskBlockIndex blockindexPrev(pindex->pprev);
1859         blockindexPrev.hashNext = 0;
1860         if (!txdb.WriteBlockIndex(blockindexPrev))
1861             return error("DisconnectBlock() : WriteBlockIndex failed");
1862     }
1863
1864     // ppcoin: clean up wallet after disconnecting coinstake
1865     for(CTransaction& tx :  vtx)
1866         SyncWithWallets(tx, this, false, false);
1867
1868     return true;
1869 }
1870
1871 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
1872
1873 void ThreadScriptCheck(void*) {
1874     vnThreadsRunning[THREAD_SCRIPTCHECK]++;
1875     RenameThread("novacoin-scriptch");
1876     scriptcheckqueue.Thread();
1877     vnThreadsRunning[THREAD_SCRIPTCHECK]--;
1878 }
1879
1880 void ThreadScriptCheckQuit() {
1881     scriptcheckqueue.Quit();
1882 }
1883
1884 bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
1885 {
1886     // Check it again in case a previous version let a bad block in, but skip BlockSig checking
1887     if (!CheckBlock(!fJustCheck, !fJustCheck, false))
1888         return false;
1889
1890     // Do not allow blocks that contain transactions which 'overwrite' older transactions,
1891     // unless those are already completely spent.
1892     // If such overwrites are allowed, coinbases and transactions depending upon those
1893     // can be duplicated to remove the ability to spend the first instance -- even after
1894     // being sent to another address.
1895     // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
1896     // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
1897     // already refuses previously-known transaction ids entirely.
1898     // This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC.
1899     // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
1900     // two in the chain that violate it. This prevents exploiting the issue against nodes in their
1901     // initial block download.
1902     bool fEnforceBIP30 = true; // Always active in NovaCoin
1903     bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();
1904
1905     //// issue here: it doesn't know the version
1906     unsigned int nTxPos;
1907     if (fJustCheck)
1908         // FetchInputs treats CDiskTxPos(1,1,1) as a special "refer to memorypool" indicator
1909         // Since we're just checking the block and not actually connecting it, it might not (and probably shouldn't) be on the disk to get the transaction from
1910         nTxPos = 1;
1911     else
1912         nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - (2 * GetSizeOfCompactSize(0)) + GetSizeOfCompactSize(vtx.size());
1913
1914     map<uint256, CTxIndex> mapQueuedChanges;
1915     CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
1916
1917     int64_t nFees = 0;
1918     int64_t nValueIn = 0;
1919     int64_t nValueOut = 0;
1920     unsigned int nSigOps = 0;
1921     for(auto& tx :  vtx)
1922     {
1923         auto hashTx = tx.GetHash();
1924
1925         if (fEnforceBIP30) {
1926             CTxIndex txindexOld;
1927             if (txdb.ReadTxIndex(hashTx, txindexOld)) {
1928                 for(CDiskTxPos &pos :  txindexOld.vSpent)
1929                     if (pos.IsNull())
1930                         return false;
1931             }
1932         }
1933
1934         nSigOps += tx.GetLegacySigOpCount();
1935         if (nSigOps > MAX_BLOCK_SIGOPS)
1936             return DoS(100, error("ConnectBlock() : too many sigops"));
1937
1938         CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
1939         if (!fJustCheck)
1940             nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
1941
1942         MapPrevTx mapInputs;
1943         if (tx.IsCoinBase())
1944             nValueOut += tx.GetValueOut();
1945         else
1946         {
1947             bool fInvalid;
1948             if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid))
1949                 return false;
1950
1951             // Add in sigops done by pay-to-script-hash inputs;
1952             // this is to prevent a "rogue miner" from creating
1953             // an incredibly-expensive-to-validate block.
1954             nSigOps += tx.GetP2SHSigOpCount(mapInputs);
1955             if (nSigOps > MAX_BLOCK_SIGOPS)
1956                 return DoS(100, error("ConnectBlock() : too many sigops"));
1957
1958             auto nTxValueIn = tx.GetValueIn(mapInputs);
1959             auto nTxValueOut = tx.GetValueOut();
1960             nValueIn += nTxValueIn;
1961             nValueOut += nTxValueOut;
1962             if (!tx.IsCoinStake())
1963                 nFees += nTxValueIn - nTxValueOut;
1964
1965             unsigned int nFlags = SCRIPT_VERIFY_NOCACHE | SCRIPT_VERIFY_P2SH;
1966
1967             if (tx.nTime >= CHECKLOCKTIMEVERIFY_SWITCH_TIME) {
1968                 nFlags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
1969                 // OP_CHECKSEQUENCEVERIFY is senseless without BIP68, so we're going disable it for now.
1970                 // nFlags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
1971             }
1972
1973             std::vector<CScriptCheck> vChecks;
1974             if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fScriptChecks, nFlags, nScriptCheckThreads ? &vChecks : NULL))
1975                 return false;
1976             control.Add(vChecks);
1977         }
1978
1979         mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size());
1980     }
1981
1982     if (!control.Wait())
1983         return DoS(100, false);
1984
1985     if (IsProofOfWork())
1986     {
1987         auto nBlockReward = GetProofOfWorkReward(nBits, nFees);
1988
1989         // Check coinbase reward
1990         if (vtx[0].GetValueOut() > nBlockReward)
1991             return error("CheckBlock() : coinbase reward exceeded (actual=%" PRId64 " vs calculated=%" PRId64 ")",
1992                    vtx[0].GetValueOut(),
1993                    nBlockReward);
1994     }
1995
1996     // track money supply and mint amount info
1997     pindex->nMint = nValueOut - nValueIn + nFees;
1998     pindex->nMoneySupply = (pindex->pprev? pindex->pprev->nMoneySupply : 0) + nValueOut - nValueIn;
1999     if (!txdb.WriteBlockIndex(CDiskBlockIndex(pindex)))
2000         return error("Connect() : WriteBlockIndex for pindex failed");
2001
2002     // fees are not collected by proof-of-stake miners
2003     // fees are destroyed to compensate the entire network
2004     if (fDebug && IsProofOfStake() && GetBoolArg("-printcreation"))
2005         printf("ConnectBlock() : destroy=%s nFees=%" PRId64 "\n", FormatMoney(nFees).c_str(), nFees);
2006
2007     if (fJustCheck)
2008         return true;
2009
2010     // Write queued txindex changes
2011     for (auto mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi)
2012     {
2013         if (!txdb.UpdateTxIndex((*mi).first, (*mi).second))
2014             return error("ConnectBlock() : UpdateTxIndex failed");
2015     }
2016
2017     // Update block index on disk without changing it in memory.
2018     // The memory index structure will be changed after the db commits.
2019     if (pindex->pprev)
2020     {
2021         CDiskBlockIndex blockindexPrev(pindex->pprev);
2022         blockindexPrev.hashNext = pindex->GetBlockHash();
2023         if (!txdb.WriteBlockIndex(blockindexPrev))
2024             return error("ConnectBlock() : WriteBlockIndex failed");
2025     }
2026
2027     // Watch for transactions paying to me
2028     for(CTransaction& tx :  vtx)
2029         SyncWithWallets(tx, this, true);
2030
2031
2032     return true;
2033 }
2034
2035 bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
2036 {
2037     printf("REORGANIZE\n");
2038
2039     // Find the fork
2040     CBlockIndex* pfork = pindexBest;
2041     CBlockIndex* plonger = pindexNew;
2042     while (pfork != plonger)
2043     {
2044         while (plonger->nHeight > pfork->nHeight)
2045             if ((plonger = plonger->pprev) == NULL)
2046                 return error("Reorganize() : plonger->pprev is null");
2047         if (pfork == plonger)
2048             break;
2049         if ((pfork = pfork->pprev) == NULL)
2050             return error("Reorganize() : pfork->pprev is null");
2051     }
2052
2053     // List of what to disconnect
2054     vector<CBlockIndex*> vDisconnect;
2055     for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev)
2056         vDisconnect.push_back(pindex);
2057
2058     // List of what to connect
2059     vector<CBlockIndex*> vConnect;
2060     for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev)
2061         vConnect.push_back(pindex);
2062     reverse(vConnect.begin(), vConnect.end());
2063
2064     printf("REORGANIZE: Disconnect %" PRIszu " blocks; %s..%s\n", vDisconnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexBest->GetBlockHash().ToString().substr(0,20).c_str());
2065     printf("REORGANIZE: Connect %" PRIszu " blocks; %s..%s\n", vConnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->GetBlockHash().ToString().substr(0,20).c_str());
2066
2067     // Disconnect shorter branch
2068     vector<CTransaction> vResurrect;
2069     for(CBlockIndex* pindex :  vDisconnect)
2070     {
2071         CBlock block;
2072         if (!block.ReadFromDisk(pindex))
2073             return error("Reorganize() : ReadFromDisk for disconnect failed");
2074         if (!block.DisconnectBlock(txdb, pindex))
2075             return error("Reorganize() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str());
2076
2077         // Queue memory transactions to resurrect
2078         for(const CTransaction& tx :  block.vtx)
2079             if (!(tx.IsCoinBase() || tx.IsCoinStake()))
2080                 vResurrect.push_back(tx);
2081     }
2082
2083     // Connect longer branch
2084     vector<CTransaction> vDelete;
2085     for (unsigned int i = 0; i < vConnect.size(); i++)
2086     {
2087         CBlockIndex* pindex = vConnect[i];
2088         CBlock block;
2089         if (!block.ReadFromDisk(pindex))
2090             return error("Reorganize() : ReadFromDisk for connect failed");
2091         if (!block.ConnectBlock(txdb, pindex))
2092         {
2093             // Invalid block
2094             return error("Reorganize() : ConnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str());
2095         }
2096
2097         // Queue memory transactions to delete
2098         for(const CTransaction& tx :  block.vtx)
2099             vDelete.push_back(tx);
2100     }
2101     if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
2102         return error("Reorganize() : WriteHashBestChain failed");
2103
2104     // Make sure it's successfully written to disk before changing memory structure
2105     if (!txdb.TxnCommit())
2106         return error("Reorganize() : TxnCommit failed");
2107
2108     // Disconnect shorter branch
2109     for(CBlockIndex* pindex :  vDisconnect)
2110         if (pindex->pprev)
2111             pindex->pprev->pnext = NULL;
2112
2113     // Connect longer branch
2114     for(CBlockIndex* pindex :  vConnect)
2115         if (pindex->pprev)
2116             pindex->pprev->pnext = pindex;
2117
2118     // Resurrect memory transactions that were in the disconnected branch
2119     for(CTransaction& tx :  vResurrect)
2120         tx.AcceptToMemoryPool(txdb, false);
2121
2122     // Delete redundant memory transactions that are in the connected branch
2123     for(CTransaction& tx :  vDelete)
2124         mempool.remove(tx);
2125
2126     printf("REORGANIZE: done\n");
2127
2128     return true;
2129 }
2130
2131
2132 // Called from inside SetBestChain: attaches a block to the new best chain being built
2133 bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew)
2134 {
2135     auto hash = GetHash();
2136
2137     // Adding to current best branch
2138     if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
2139     {
2140         txdb.TxnAbort();
2141         InvalidChainFound(pindexNew);
2142         return false;
2143     }
2144     if (!txdb.TxnCommit())
2145         return error("SetBestChain() : TxnCommit failed");
2146
2147     // Add to current best branch
2148     pindexNew->pprev->pnext = pindexNew;
2149
2150     // Delete redundant memory transactions
2151     for(CTransaction& tx :  vtx)
2152         mempool.remove(tx);
2153
2154     return true;
2155 }
2156
2157 bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
2158 {
2159     auto hash = GetHash();
2160
2161     if (!txdb.TxnBegin())
2162         return error("SetBestChain() : TxnBegin failed");
2163
2164     if (pindexGenesisBlock == NULL && hash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet))
2165     {
2166         txdb.WriteHashBestChain(hash);
2167         if (!txdb.TxnCommit())
2168             return error("SetBestChain() : TxnCommit failed");
2169         pindexGenesisBlock = pindexNew;
2170     }
2171     else if (hashPrevBlock == hashBestChain)
2172     {
2173         if (!SetBestChainInner(txdb, pindexNew))
2174             return error("SetBestChain() : SetBestChainInner failed");
2175     }
2176     else
2177     {
2178         // the first block in the new chain that will cause it to become the new best chain
2179         CBlockIndex *pindexIntermediate = pindexNew;
2180
2181         // list of blocks that need to be connected afterwards
2182         std::vector<CBlockIndex*> vpindexSecondary;
2183
2184         // Reorganize is costly in terms of db load, as it works in a single db transaction.
2185         // Try to limit how much needs to be done inside
2186         while (pindexIntermediate->pprev && pindexIntermediate->pprev->nChainTrust > pindexBest->nChainTrust)
2187         {
2188             vpindexSecondary.push_back(pindexIntermediate);
2189             pindexIntermediate = pindexIntermediate->pprev;
2190         }
2191
2192         if (!vpindexSecondary.empty())
2193             printf("Postponing %" PRIszu " reconnects\n", vpindexSecondary.size());
2194
2195         // Switch to new best branch
2196         if (!Reorganize(txdb, pindexIntermediate))
2197         {
2198             txdb.TxnAbort();
2199             InvalidChainFound(pindexNew);
2200             return error("SetBestChain() : Reorganize failed");
2201         }
2202
2203         // Connect further blocks
2204         for (std::vector<CBlockIndex*>::reverse_iterator rit = vpindexSecondary.rbegin(); rit != vpindexSecondary.rend(); ++rit)
2205         {
2206             CBlock block;
2207             if (!block.ReadFromDisk(*rit))
2208             {
2209                 printf("SetBestChain() : ReadFromDisk failed\n");
2210                 break;
2211             }
2212             if (!txdb.TxnBegin()) {
2213                 printf("SetBestChain() : TxnBegin 2 failed\n");
2214                 break;
2215             }
2216             // errors now are not fatal, we still did a reorganisation to a new chain in a valid way
2217             if (!block.SetBestChainInner(txdb, *rit))
2218                 break;
2219         }
2220     }
2221
2222     // Update best block in wallet (so we can detect restored wallets)
2223     bool fIsInitialDownload = IsInitialBlockDownload();
2224     if (!fIsInitialDownload)
2225     {
2226         const CBlockLocator locator(pindexNew);
2227         ::SetBestChain(locator);
2228     }
2229
2230     // New best block
2231     hashBestChain = hash;
2232     pindexBest = pindexNew;
2233     pblockindexFBBHLast = NULL;
2234     nBestHeight = pindexBest->nHeight;
2235     nBestChainTrust = pindexNew->nChainTrust;
2236     nTimeBestReceived = GetTime();
2237     nTransactionsUpdated++;
2238
2239     uint256 nBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->nChainTrust - pindexBest->pprev->nChainTrust) : pindexBest->nChainTrust;
2240
2241     printf("SetBestChain: new best=%s  height=%d  trust=%s  blocktrust=%" PRId64 "  date=%s\n",
2242       hashBestChain.ToString().substr(0,20).c_str(), nBestHeight,
2243       CBigNum(nBestChainTrust).ToString().c_str(),
2244       nBestBlockTrust.Get64(),
2245       DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str());
2246
2247     // Check the version of the last 100 blocks to see if we need to upgrade:
2248     if (!fIsInitialDownload)
2249     {
2250         int nUpgraded = 0;
2251         const CBlockIndex* pindex = pindexBest;
2252         for (int i = 0; i < 100 && pindex != NULL; i++)
2253         {
2254             if (pindex->nVersion > CBlock::CURRENT_VERSION)
2255                 ++nUpgraded;
2256             pindex = pindex->pprev;
2257         }
2258         if (nUpgraded > 0)
2259             printf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION);
2260         if (nUpgraded > 100/2)
2261             // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
2262             strMiscWarning = _("Warning: This version is obsolete, upgrade required!");
2263     }
2264
2265     auto strCmd = GetArg("-blocknotify", "");
2266
2267     if (!fIsInitialDownload && !strCmd.empty())
2268         // thread runs free
2269         boost::thread t(runCommand, regex_replace(strCmd, static_cast<regex>("%s"), hashBestChain.GetHex()));
2270
2271     return true;
2272 }
2273
2274 // ppcoin: total coin age spent in transaction, in the unit of coin-days.
2275 // Only those coins meeting minimum age requirement counts. As those
2276 // transactions not in main chain are not currently indexed so we
2277 // might not find out about their coin age. Older transactions are 
2278 // guaranteed to be in main chain by sync-checkpoint. This rule is
2279 // introduced to help nodes establish a consistent view of the coin
2280 // age (trust score) of competing branches.
2281 bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const
2282 {
2283     CBigNum bnCentSecond = 0;  // coin age in the unit of cent-seconds
2284     nCoinAge = 0;
2285
2286     if (IsCoinBase())
2287         return true;
2288
2289     for(const CTxIn& txin :  vin)
2290     {
2291         // First try finding the previous transaction in database
2292         CTransaction txPrev;
2293         CTxIndex txindex;
2294         if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
2295             continue;  // previous transaction not in main chain
2296         if (nTime < txPrev.nTime)
2297             return false;  // Transaction timestamp violation
2298
2299         // Read block header
2300         CBlock block;
2301         if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
2302             return false; // unable to read block of previous transaction
2303         if (block.GetBlockTime() + nStakeMinAge > nTime)
2304             continue; // only count coins meeting min age requirement
2305
2306         auto nValueIn = txPrev.vout[txin.prevout.n].nValue;
2307         bnCentSecond += CBigNum(nValueIn) * (nTime-txPrev.nTime) / CENT;
2308
2309         if (fDebug && GetBoolArg("-printcoinage"))
2310             printf("coin age nValueIn=%" PRId64 " nTimeDiff=%d bnCentSecond=%s\n", nValueIn, nTime - txPrev.nTime, bnCentSecond.ToString().c_str());
2311     }
2312
2313     auto bnCoinDay = bnCentSecond * CENT / COIN / nOneDay;
2314     if (fDebug && GetBoolArg("-printcoinage"))
2315         printf("coin age bnCoinDay=%s\n", bnCoinDay.ToString().c_str());
2316     nCoinAge = bnCoinDay.getuint64();
2317     return true;
2318 }
2319
2320 // ppcoin: total coin age spent in block, in the unit of coin-days.
2321 bool CBlock::GetCoinAge(uint64_t& nCoinAge) const
2322 {
2323     nCoinAge = 0;
2324
2325     CTxDB txdb("r");
2326     for(const CTransaction& tx :  vtx)
2327     {
2328         uint64_t nTxCoinAge;
2329         if (tx.GetCoinAge(txdb, nTxCoinAge))
2330             nCoinAge += nTxCoinAge;
2331         else
2332             return false;
2333     }
2334
2335     if (nCoinAge == 0) // block coin age minimum 1 coin-day
2336         nCoinAge = 1;
2337     if (fDebug && GetBoolArg("-printcoinage"))
2338         printf("block coin age total nCoinDays=%" PRId64 "\n", nCoinAge);
2339     return true;
2340 }
2341
2342 bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
2343 {
2344     // Check for duplicate
2345     auto hash = GetHash();
2346     if (mapBlockIndex.count(hash))
2347         return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
2348
2349     // Construct new block index object
2350     CBlockIndex* pindexNew = new(nothrow) CBlockIndex(nFile, nBlockPos, *this);
2351     if (!pindexNew)
2352         return error("AddToBlockIndex() : new CBlockIndex failed");
2353     pindexNew->phashBlock = &hash;
2354     auto miPrev = mapBlockIndex.find(hashPrevBlock);
2355     if (miPrev != mapBlockIndex.end())
2356     {
2357         pindexNew->pprev = (*miPrev).second;
2358         pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
2359     }
2360
2361     // ppcoin: compute chain trust score
2362     pindexNew->nChainTrust = (pindexNew->pprev ? pindexNew->pprev->nChainTrust : 0) + pindexNew->GetBlockTrust();
2363
2364     // ppcoin: compute stake entropy bit for stake modifier
2365     if (!pindexNew->SetStakeEntropyBit(GetStakeEntropyBit(pindexNew->nHeight)))
2366         return error("AddToBlockIndex() : SetStakeEntropyBit() failed");
2367
2368     // ppcoin: record proof-of-stake hash value
2369     if (pindexNew->IsProofOfStake())
2370     {
2371         if (!mapProofOfStake.count(hash))
2372             return error("AddToBlockIndex() : hashProofOfStake not found in map");
2373         pindexNew->hashProofOfStake = mapProofOfStake[hash];
2374     }
2375
2376     // ppcoin: compute stake modifier
2377     uint64_t nStakeModifier = 0;
2378     bool fGeneratedStakeModifier = false;
2379     if (!ComputeNextStakeModifier(pindexNew, nStakeModifier, fGeneratedStakeModifier))
2380         return error("AddToBlockIndex() : ComputeNextStakeModifier() failed");
2381     pindexNew->SetStakeModifier(nStakeModifier, fGeneratedStakeModifier);
2382     pindexNew->nStakeModifierChecksum = GetStakeModifierChecksum(pindexNew);
2383     if (!CheckStakeModifierCheckpoints(pindexNew->nHeight, pindexNew->nStakeModifierChecksum))
2384         return error("AddToBlockIndex() : Rejected by stake modifier checkpoint height=%d, modifier=0x%016" PRIx64, pindexNew->nHeight, nStakeModifier);
2385
2386     // Add to mapBlockIndex
2387     auto mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
2388     if (pindexNew->IsProofOfStake())
2389         setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime));
2390     pindexNew->phashBlock = &((*mi).first);
2391
2392     // Write to disk block index
2393     CTxDB txdb;
2394     if (!txdb.TxnBegin())
2395         return false;
2396     txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
2397     if (!txdb.TxnCommit())
2398         return false;
2399
2400     // New best
2401     if (pindexNew->nChainTrust > nBestChainTrust)
2402         if (!SetBestChain(txdb, pindexNew))
2403             return false;
2404
2405     if (pindexNew == pindexBest)
2406     {
2407         // Notify UI to display prev block's coinbase if it was ours
2408         static uint256 hashPrevBestCoinBase;
2409         UpdatedTransaction(hashPrevBestCoinBase);
2410         hashPrevBestCoinBase = vtx[0].GetHash();
2411     }
2412
2413     static int8_t counter = 0;
2414     if( (++counter & 0x0F) == 0 || !IsInitialBlockDownload()) // repaint every 16 blocks if not in initial block download
2415         uiInterface.NotifyBlocksChanged();
2416     return true;
2417 }
2418
2419
2420
2421
2422 bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) const
2423 {
2424     // These are checks that are independent of context
2425     // that can be verified before saving an orphan block.
2426
2427     set<uint256> uniqueTx; // tx hashes
2428     unsigned int nSigOps = 0; // total sigops
2429
2430     // Size limits
2431     if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
2432         return DoS(100, error("CheckBlock() : size limits failed"));
2433
2434     bool fProofOfStake = IsProofOfStake();
2435
2436     // First transaction must be coinbase, the rest must not be
2437     if (!vtx[0].IsCoinBase())
2438         return DoS(100, error("CheckBlock() : first tx is not coinbase"));
2439
2440     if (!vtx[0].CheckTransaction())
2441         return DoS(vtx[0].nDoS, error("CheckBlock() : CheckTransaction failed on coinbase"));
2442
2443     uniqueTx.insert(vtx[0].GetHash());
2444     nSigOps += vtx[0].GetLegacySigOpCount();
2445
2446     if (fProofOfStake)
2447     {
2448         // Proof-of-STake related checkings. Note that we know here that 1st transactions is coinstake. We don't need 
2449         //   check the type of 1st transaction because it's performed earlier by IsProofOfStake()
2450
2451         // nNonce must be zero for proof-of-stake blocks
2452         if (nNonce != 0)
2453             return DoS(100, error("CheckBlock() : non-zero nonce in proof-of-stake block"));
2454
2455         // Coinbase output should be empty if proof-of-stake block
2456         if (vtx[0].vout.size() != 1 || !vtx[0].vout[0].IsEmpty())
2457             return DoS(100, error("CheckBlock() : coinbase output not empty for proof-of-stake block"));
2458
2459         // Check coinstake timestamp
2460         if (GetBlockTime() != (int64_t)vtx[1].nTime)
2461             return DoS(50, error("CheckBlock() : coinstake timestamp violation nTimeBlock=%" PRId64 " nTimeTx=%u", GetBlockTime(), vtx[1].nTime));
2462
2463         // NovaCoin: check proof-of-stake block signature
2464         if (fCheckSig && !CheckBlockSignature())
2465             return DoS(100, error("CheckBlock() : bad proof-of-stake block signature"));
2466
2467         if (!vtx[1].CheckTransaction())
2468             return DoS(vtx[1].nDoS, error("CheckBlock() : CheckTransaction failed on coinstake"));
2469
2470         uniqueTx.insert(vtx[1].GetHash());
2471         nSigOps += vtx[1].GetLegacySigOpCount();
2472     }
2473     else
2474     {
2475         // Check proof of work matches claimed amount
2476         if (fCheckPOW && !CheckProofOfWork(GetHash(), nBits))
2477             return DoS(50, error("CheckBlock() : proof of work failed"));
2478
2479         // Check timestamp
2480         if (GetBlockTime() > FutureDrift(GetAdjustedTime()))
2481             return error("CheckBlock() : block timestamp too far in the future");
2482
2483         // Check coinbase timestamp
2484         if (GetBlockTime() < PastDrift((int64_t)vtx[0].nTime))
2485             return DoS(50, error("CheckBlock() : coinbase timestamp is too late"));
2486     }
2487
2488     // Iterate all transactions starting from second for proof-of-stake block 
2489     //    or first for proof-of-work block
2490     for (unsigned int i = fProofOfStake ? 2 : 1; i < vtx.size(); i++)
2491     {
2492         const CTransaction& tx = vtx[i];
2493
2494         // Reject coinbase transactions at non-zero index
2495         if (tx.IsCoinBase())
2496             return DoS(100, error("CheckBlock() : coinbase at wrong index"));
2497
2498         // Reject coinstake transactions at index != 1
2499         if (tx.IsCoinStake())
2500             return DoS(100, error("CheckBlock() : coinstake at wrong index"));
2501
2502         // Check transaction timestamp
2503         if (GetBlockTime() < (int64_t)tx.nTime)
2504             return DoS(50, error("CheckBlock() : block timestamp earlier than transaction timestamp"));
2505
2506         // Check transaction consistency
2507         if (!tx.CheckTransaction())
2508             return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed"));
2509
2510         // Add transaction hash into list of unique transaction IDs
2511         uniqueTx.insert(tx.GetHash());
2512
2513         // Calculate sigops count
2514         nSigOps += tx.GetLegacySigOpCount();
2515     }
2516
2517     // Check for duplicate txids. This is caught by ConnectInputs(),
2518     // but catching it earlier avoids a potential DoS attack:
2519     if (uniqueTx.size() != vtx.size())
2520         return DoS(100, error("CheckBlock() : duplicate transaction"));
2521
2522     // Reject block if validation would consume too much resources.
2523     if (nSigOps > MAX_BLOCK_SIGOPS)
2524         return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"));
2525
2526     // Check merkle root
2527     if (fCheckMerkleRoot && hashMerkleRoot != BuildMerkleTree())
2528         return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));
2529
2530     return true;
2531 }
2532
2533 bool CBlock::AcceptBlock()
2534 {
2535     // Check for duplicate
2536     auto hash = GetHash();
2537     if (mapBlockIndex.count(hash))
2538         return error("AcceptBlock() : block already in mapBlockIndex");
2539
2540     // Get prev block index
2541     auto mi = mapBlockIndex.find(hashPrevBlock);
2542     if (mi == mapBlockIndex.end())
2543         return DoS(10, error("AcceptBlock() : prev block not found"));
2544     CBlockIndex* pindexPrev = (*mi).second;
2545     int nHeight = pindexPrev->nHeight+1;
2546
2547     // Check proof-of-work or proof-of-stake
2548     if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake()))
2549         return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake"));
2550
2551     int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
2552     int nMaxOffset = 12 * nOneHour; // 12 hours
2553     if (fTestNet || pindexPrev->nTime < 1450569600)
2554         nMaxOffset = 7 * nOneWeek; // One week (permanently on testNet or until 20 Dec, 2015 on mainNet)
2555
2556     // Check timestamp against prev
2557     if (GetBlockTime() <= nMedianTimePast || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime())
2558         return error("AcceptBlock() : block's timestamp is too early");
2559
2560     // Don't accept blocks with future timestamps
2561     if (pindexPrev->nHeight > 1 && nMedianTimePast  + nMaxOffset < GetBlockTime())
2562         return error("AcceptBlock() : block's timestamp is too far in the future");
2563
2564     // Check that all transactions are finalized
2565     for(const CTransaction& tx :  vtx)
2566         if (!tx.IsFinal(nHeight, GetBlockTime()))
2567             return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
2568
2569     // Check that the block chain matches the known block chain up to a checkpoint
2570     if (!Checkpoints::CheckHardened(nHeight, hash))
2571         return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight));
2572
2573     bool cpSatisfies = Checkpoints::CheckSync(hash, pindexPrev);
2574
2575     // Check that the block satisfies synchronized checkpoint
2576     if (CheckpointsMode == Checkpoints::CP_STRICT && !cpSatisfies)
2577         return error("AcceptBlock() : rejected by synchronized checkpoint");
2578
2579     if (CheckpointsMode == Checkpoints::CP_ADVISORY && !cpSatisfies)
2580         strMiscWarning = _("WARNING: syncronized checkpoint violation detected, but skipped!");
2581
2582     // Enforce rule that the coinbase starts with serialized block height
2583     auto expect = CScript() << nHeight;
2584     if (vtx[0].vin[0].scriptSig.size() < expect.size() ||
2585         !std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin()))
2586         return DoS(100, error("AcceptBlock() : block height mismatch in coinbase"));
2587
2588     // Write block to history file
2589     if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION)))
2590         return error("AcceptBlock() : out of disk space");
2591     unsigned int nFile = std::numeric_limits<unsigned int>::max();
2592     unsigned int nBlockPos = 0;
2593     if (!WriteToDisk(nFile, nBlockPos))
2594         return error("AcceptBlock() : WriteToDisk failed");
2595     if (!AddToBlockIndex(nFile, nBlockPos))
2596         return error("AcceptBlock() : AddToBlockIndex failed");
2597
2598     // Relay inventory, but don't relay old inventory during initial block download
2599     int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
2600     if (hashBestChain == hash)
2601     {
2602         LOCK(cs_vNodes);
2603         for(CNode* pnode :  vNodes)
2604             if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
2605                 pnode->PushInventory(CInv(MSG_BLOCK, hash));
2606     }
2607
2608     // ppcoin: check pending sync-checkpoint
2609     Checkpoints::AcceptPendingSyncCheckpoint();
2610
2611     return true;
2612 }
2613
2614 uint256 CBlockIndex::GetBlockTrust() const
2615 {
2616     CBigNum bnTarget;
2617     bnTarget.SetCompact(nBits);
2618
2619     if (bnTarget <= 0)
2620         return 0;
2621
2622     // Return 1 for the first 12 blocks
2623     if (pprev == NULL || pprev->nHeight < 12)
2624         return 1;
2625
2626     const CBlockIndex* currentIndex = pprev;
2627
2628     if(IsProofOfStake())
2629     {
2630         CBigNum bnNewTrust = (CBigNum(1)<<256) / (bnTarget+1);
2631
2632         // Return 1/3 of score if parent block is not the PoW block
2633         if (!pprev->IsProofOfWork())
2634             return (bnNewTrust / 3).getuint256();
2635
2636         int nPoWCount = 0;
2637
2638         // Check last 12 blocks type
2639         while (pprev->nHeight - currentIndex->nHeight < 12)
2640         {
2641             if (currentIndex->IsProofOfWork())
2642                 nPoWCount++;
2643             currentIndex = currentIndex->pprev;
2644         }
2645
2646         // Return 1/3 of score if less than 3 PoW blocks found
2647         if (nPoWCount < 3)
2648             return (bnNewTrust / 3).getuint256();
2649
2650         return bnNewTrust.getuint256();
2651     }
2652     else
2653     {
2654         // Calculate work amount for block
2655         CBigNum bnPoWTrust = CBigNum(nPoWBase) / (bnTarget+1);
2656
2657         // Set nPowTrust to 1 if PoW difficulty is too low
2658         if (bnPoWTrust < 1)
2659             bnPoWTrust = 1;
2660
2661         CBigNum bnLastBlockTrust = CBigNum(pprev->nChainTrust - pprev->pprev->nChainTrust);
2662
2663         // Return nPoWTrust + 2/3 of previous block score if two parent blocks are not PoS blocks
2664         if (!(pprev->IsProofOfStake() && pprev->pprev->IsProofOfStake()))
2665             return (bnPoWTrust + 2 * bnLastBlockTrust / 3).getuint256();
2666
2667         int nPoSCount = 0;
2668
2669         // Check last 12 blocks type
2670         while (pprev->nHeight - currentIndex->nHeight < 12)
2671         {
2672             if (currentIndex->IsProofOfStake())
2673                 nPoSCount++;
2674             currentIndex = currentIndex->pprev;
2675         }
2676
2677         // Return nPoWTrust + 2/3 of previous block score if less than 7 PoS blocks found
2678         if (nPoSCount < 7)
2679             return (bnPoWTrust + 2 * bnLastBlockTrust / 3).getuint256();
2680
2681         bnTarget.SetCompact(pprev->nBits);
2682
2683         if (bnTarget <= 0)
2684             return 0;
2685
2686         CBigNum bnNewTrust = (CBigNum(1)<<256) / (bnTarget+1);
2687
2688         // Return nPoWTrust + full trust score for previous block nBits
2689         return (bnPoWTrust + bnNewTrust).getuint256();
2690     }
2691 }
2692
2693 CBlock CBlockIndex::GetBlockHeader() const
2694 {
2695     CBlock block;
2696     block.nVersion       = nVersion;
2697     if (pprev)
2698         block.hashPrevBlock = pprev->GetBlockHash();
2699     block.hashMerkleRoot = hashMerkleRoot;
2700     block.nTime          = nTime;
2701     block.nBits          = nBits;
2702     block.nNonce         = nNonce;
2703     return block;
2704 }
2705
2706 enum { nMedianTimeSpan=11 };
2707
2708 int64_t CBlockIndex::GetMedianTimePast() const
2709 {
2710     int64_t pmedian[nMedianTimeSpan];
2711     int64_t* pbegin = &pmedian[nMedianTimeSpan];
2712     int64_t* pend = &pmedian[nMedianTimeSpan];
2713     const CBlockIndex* pindex = this;
2714     for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
2715         *(--pbegin) = pindex->GetBlockTime();
2716     sort(pbegin, pend);
2717     return pbegin[(pend - pbegin)/2];
2718 }
2719
2720 int64_t CBlockIndex::GetMedianTime() const
2721 {
2722     const CBlockIndex* pindex = this;
2723     for (int i = 0; i < nMedianTimeSpan/2; i++)
2724     {
2725         if (!pindex->pnext)
2726             return GetBlockTime();
2727         pindex = pindex->pnext;
2728     }
2729     return pindex->GetMedianTimePast();
2730 }
2731
2732 bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck)
2733 {
2734     unsigned int nFound = 0;
2735     for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++)
2736     {
2737         if (pstart->nVersion >= minVersion)
2738             ++nFound;
2739         pstart = pstart->pprev;
2740     }
2741     return (nFound >= nRequired);
2742 }
2743
2744 bool CBlockIndex::SetStakeEntropyBit(unsigned int nEntropyBit)
2745 {
2746     if (nEntropyBit > 1)
2747         return false;
2748     nFlags |= (nEntropyBit? BLOCK_STAKE_ENTROPY : 0);
2749     return true;
2750 }
2751
2752 void CBlockIndex::SetStakeModifier(uint64_t nModifier, bool fGeneratedStakeModifier)
2753 {
2754     nStakeModifier = nModifier;
2755     if (fGeneratedStakeModifier)
2756         nFlags |= BLOCK_STAKE_MODIFIER;
2757 }
2758
2759 string CBlockIndex::ToString() const
2760 {
2761     return strprintf("CBlockIndex(nprev=%p, pnext=%p, nFile=%u, nBlockPos=%-6d nHeight=%d, nMint=%s, nMoneySupply=%s, nFlags=(%s)(%d)(%s), nStakeModifier=%016" PRIx64 ", nStakeModifierChecksum=%08x, hashProofOfStake=%s, prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)",
2762         (const void*)pprev, (const void*)pnext, nFile, nBlockPos, nHeight,
2763         FormatMoney(nMint).c_str(), FormatMoney(nMoneySupply).c_str(),
2764         GeneratedStakeModifier() ? "MOD" : "-", GetStakeEntropyBit(), IsProofOfStake()? "PoS" : "PoW",
2765         nStakeModifier, nStakeModifierChecksum,
2766         hashProofOfStake.ToString().c_str(),
2767         prevoutStake.ToString().c_str(), nStakeTime,
2768         hashMerkleRoot.ToString().c_str(),
2769         GetBlockHash().ToString().c_str());
2770 }
2771
2772 bool static ReserealizeBlockSignature(CBlock* pblock)
2773 {
2774     if (pblock->IsProofOfWork())
2775     {
2776         pblock->vchBlockSig.clear();
2777         return true;
2778     }
2779
2780     return CPubKey::ReserealizeSignature(pblock->vchBlockSig);
2781 }
2782
2783 bool static IsCanonicalBlockSignature(CBlock* pblock)
2784 {
2785     if (pblock->IsProofOfWork())
2786         return pblock->vchBlockSig.empty();
2787
2788     return IsDERSignature(pblock->vchBlockSig);
2789 }
2790
2791 bool ProcessBlock(CNode* pfrom, CBlock* pblock)
2792 {
2793     // Check for duplicate
2794     auto hash = pblock->GetHash();
2795     if (mapBlockIndex.count(hash))
2796         return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str());
2797     if (mapOrphanBlocks.count(hash))
2798         return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str());
2799
2800     // Check that block isn't listed as unconditionally banned.
2801     if (!Checkpoints::CheckBanned(hash)) {
2802         if (pfrom)
2803             pfrom->Misbehaving(100);
2804         return error("ProcessBlock() : block %s is rejected by hard-coded banlist", hash.GetHex().substr(0,20).c_str());
2805     }
2806
2807     // Check proof-of-stake
2808     // Limited duplicity on stake: prevents block flood attack
2809     // Duplicate stake allowed only when there is orphan child block
2810     if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash) && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
2811         return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str());
2812
2813     // Strip the garbage from newly received blocks, if we found some
2814     if (!IsCanonicalBlockSignature(pblock)) {
2815         if (!ReserealizeBlockSignature(pblock))
2816             printf("WARNING: ProcessBlock() : ReserealizeBlockSignature FAILED\n");
2817     }
2818
2819     // Preliminary checks
2820     if (!pblock->CheckBlock(true, true, (pblock->nTime > Checkpoints::GetLastCheckpointTime())))
2821         return error("ProcessBlock() : CheckBlock FAILED");
2822
2823     // ppcoin: verify hash target and signature of coinstake tx
2824     if (pblock->IsProofOfStake())
2825     {
2826         uint256 hashProofOfStake = 0, targetProofOfStake = 0;
2827         if (!CheckProofOfStake(pblock->vtx[1], pblock->nBits, hashProofOfStake, targetProofOfStake))
2828         {
2829             printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str());
2830             return false; // do not error here as we expect this during initial block download
2831         }
2832         if (!mapProofOfStake.count(hash)) // add to mapProofOfStake
2833             mapProofOfStake.insert(make_pair(hash, hashProofOfStake));
2834     }
2835
2836     CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint();
2837     if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
2838     {
2839         // Extra checks to prevent "fill up memory by spamming with bogus blocks"
2840         auto deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
2841         CBigNum bnNewBlock;
2842         bnNewBlock.SetCompact(pblock->nBits);
2843         CBigNum bnRequired;
2844
2845         if (pblock->IsProofOfStake())
2846             bnRequired.SetCompact(ComputeMinStake(GetLastBlockIndex(pcheckpoint, true)->nBits, deltaTime, pblock->nTime));
2847         else
2848             bnRequired.SetCompact(ComputeMinWork(GetLastBlockIndex(pcheckpoint, false)->nBits, deltaTime));
2849
2850         if (bnNewBlock > bnRequired)
2851         {
2852             if (pfrom)
2853                 pfrom->Misbehaving(100);
2854             return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work");
2855         }
2856     }
2857
2858     // ppcoin: ask for pending sync-checkpoint if any
2859     if (!IsInitialBlockDownload())
2860         Checkpoints::AskForPendingSyncCheckpoint(pfrom);
2861
2862     // If don't already have its previous block, shunt it off to holding area until we get it
2863     if (!mapBlockIndex.count(pblock->hashPrevBlock))
2864     {
2865         printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
2866         // ppcoin: check proof-of-stake
2867         if (pblock->IsProofOfStake())
2868         {
2869             // Limited duplicity on stake: prevents block flood attack
2870             // Duplicate stake allowed only when there is orphan child block
2871             if (setStakeSeenOrphan.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash) && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
2872                 return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str());
2873             else
2874                 setStakeSeenOrphan.insert(pblock->GetProofOfStake());
2875         }
2876         CBlock* pblock2 = new CBlock(*pblock);
2877         mapOrphanBlocks.insert(make_pair(hash, pblock2));
2878         mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2));
2879
2880         // Ask this guy to fill in what we're missing
2881         if (pfrom)
2882         {
2883             pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2));
2884             // ppcoin: getblocks may not obtain the ancestor block rejected
2885             // earlier by duplicate-stake check so we ask for it again directly
2886             if (!IsInitialBlockDownload())
2887                 pfrom->AskFor(CInv(MSG_BLOCK, WantedByOrphan(pblock2)));
2888         }
2889         return true;
2890     }
2891
2892     // Store to disk
2893     if (!pblock->AcceptBlock())
2894         return error("ProcessBlock() : AcceptBlock FAILED");
2895
2896     // Recursively process any orphan blocks that depended on this one
2897     vector<uint256> vWorkQueue;
2898     vWorkQueue.push_back(hash);
2899     for (unsigned int i = 0; i < vWorkQueue.size(); i++)
2900     {
2901         auto hashPrev = vWorkQueue[i];
2902         for (auto mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
2903              mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
2904              ++mi)
2905         {
2906             CBlock* pblockOrphan = (*mi).second;
2907             if (pblockOrphan->AcceptBlock())
2908                 vWorkQueue.push_back(pblockOrphan->GetHash());
2909             mapOrphanBlocks.erase(pblockOrphan->GetHash());
2910             setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake());
2911             delete pblockOrphan;
2912         }
2913         mapOrphanBlocksByPrev.erase(hashPrev);
2914     }
2915
2916     printf("ProcessBlock: ACCEPTED\n");
2917
2918     // ppcoin: if responsible for sync-checkpoint send it
2919     if (pfrom && !CSyncCheckpoint::strMasterPrivKey.empty())
2920         Checkpoints::SendSyncCheckpoint(Checkpoints::AutoSelectSyncCheckpoint());
2921
2922     return true;
2923 }
2924
2925 // ppcoin: check block signature
2926 bool CBlock::CheckBlockSignature() const
2927 {
2928     if (vchBlockSig.empty())
2929         return false;
2930
2931     txnouttype whichType;
2932     vector<valtype> vSolutions;
2933     if (!Solver(vtx[1].vout[1].scriptPubKey, whichType, vSolutions))
2934         return false;
2935
2936     if (whichType == TX_PUBKEY)
2937     {
2938         auto& vchPubKey = vSolutions[0];
2939         CPubKey key(vchPubKey);
2940         if (!key.IsValid())
2941             return false;
2942         return key.Verify(GetHash(), vchBlockSig);
2943     }
2944
2945     return false;
2946 }
2947
2948
2949
2950 //
2951 // CDiskBlockIndex
2952 //
2953
2954 uint256 CDiskBlockIndex::GetBlockHash() const
2955 {
2956     if (fUseFastIndex && blockHash != 0)
2957         return blockHash;
2958
2959     CBlock block;
2960     block.nVersion        = nVersion;
2961     block.hashPrevBlock   = hashPrev;
2962     block.hashMerkleRoot  = hashMerkleRoot;
2963     block.nTime           = nTime;
2964     block.nBits           = nBits;
2965     block.nNonce          = nNonce;
2966
2967     const_cast<CDiskBlockIndex*>(this)->blockHash = block.GetHash();
2968
2969     return blockHash;
2970 }
2971
2972 string CDiskBlockIndex::ToString() const
2973 {
2974     string str = "CDiskBlockIndex(";
2975     str += CBlockIndex::ToString();
2976     str += strprintf("\n                hashBlock=%s, hashPrev=%s, hashNext=%s)",
2977         GetBlockHash().ToString().c_str(),
2978         hashPrev.ToString().c_str(),
2979         hashNext.ToString().c_str());
2980     return str;
2981 }
2982
2983 //
2984 //CBlockLocator
2985 //
2986
2987 void CBlockLocator::Set(const CBlockIndex* pindex)
2988 {
2989     vHave.clear();
2990     int nStep = 1;
2991     while (pindex)
2992     {
2993         vHave.push_back(pindex->GetBlockHash());
2994         // Exponentially larger steps back
2995         for (int i = 0; pindex && i < nStep; i++)
2996             pindex = pindex->pprev;
2997         if (vHave.size() > 10)
2998             nStep *= 2;
2999     }
3000     vHave.push_back((!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet));
3001 }
3002
3003 int CBlockLocator::GetDistanceBack()
3004 {
3005     // Retrace how far back it was in the sender's branch
3006     int nDistance = 0;
3007     int nStep = 1;
3008     for(const auto& hash :  vHave)
3009     {
3010         auto mi = mapBlockIndex.find(hash);
3011         if (mi != mapBlockIndex.end())
3012         {
3013             auto pindex = (*mi).second;
3014             if (pindex->IsInMainChain())
3015                 return nDistance;
3016         }
3017         nDistance += nStep;
3018         if (nDistance > 10)
3019             nStep *= 2;
3020     }
3021     return nDistance;
3022 }
3023
3024 CBlockIndex* CBlockLocator::GetBlockIndex()
3025 {
3026     // Find the first block the caller has in the main chain
3027     for(const auto& hash : vHave)
3028     {
3029         auto mi = mapBlockIndex.find(hash);
3030         if (mi != mapBlockIndex.end())
3031         {
3032             auto pindex = (*mi).second;
3033             if (pindex->IsInMainChain())
3034                 return pindex;
3035         }
3036     }
3037     return pindexGenesisBlock;
3038 }
3039
3040 uint256 CBlockLocator::GetBlockHash()
3041 {
3042     // Find the first block the caller has in the main chain
3043     for(const uint256& hash :  vHave)
3044     {
3045         auto mi = mapBlockIndex.find(hash);
3046         if (mi != mapBlockIndex.end())
3047         {
3048             auto pindex = (*mi).second;
3049             if (pindex->IsInMainChain())
3050                 return hash;
3051         }
3052     }
3053     return (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet);
3054 }
3055
3056 int CBlockLocator::GetHeight()
3057 {
3058     CBlockIndex* pindex = GetBlockIndex();
3059     if (!pindex)
3060         return 0;
3061     return pindex->nHeight;
3062 }
3063
3064 bool CheckDiskSpace(uint64_t nAdditionalBytes)
3065 {
3066     uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
3067
3068     // Check for nMinDiskSpace bytes (currently 50MB)
3069     if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
3070     {
3071         fShutdown = true;
3072         string strMessage("Warning: Disk space is low!");
3073         strMiscWarning = strMessage;
3074         printf("*** %s\n", strMessage.c_str());
3075         uiInterface.ThreadSafeMessageBox(strMessage, "NovaCoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
3076         StartShutdown();
3077         return false;
3078     }
3079     return true;
3080 }
3081
3082 static filesystem::path BlockFilePath(unsigned int nFile)
3083 {
3084     string strBlockFn = strprintf("blk%04u.dat", nFile);
3085     return GetDataDir() / strBlockFn;
3086 }
3087
3088 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
3089 {
3090     if ((nFile < 1) || (nFile == std::numeric_limits<uint32_t>::max()))
3091         return NULL;
3092     FILE* file = fopen(BlockFilePath(nFile).string().c_str(), pszMode);
3093     if (!file)
3094         return NULL;
3095     if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
3096     {
3097         if (fseek(file, nBlockPos, SEEK_SET) != 0)
3098         {
3099             fclose(file);
3100             return NULL;
3101         }
3102     }
3103     return file;
3104 }
3105
3106 static unsigned int nCurrentBlockFile = 1;
3107
3108 FILE* AppendBlockFile(unsigned int& nFileRet)
3109 {
3110     nFileRet = 0;
3111     for ( ; ; )
3112     {
3113         FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");
3114         if (!file)
3115             return NULL;
3116         if (fseek(file, 0, SEEK_END) != 0)
3117         {
3118             fclose(file);
3119             return NULL;
3120         }
3121         // FAT32 file size max 4GB, fseek and ftell max 2GB, so we must stay under 2GB
3122         if (ftell(file) < (long)(0x7F000000 - MAX_SIZE))
3123         {
3124             nFileRet = nCurrentBlockFile;
3125             return file;
3126         }
3127         fclose(file);
3128         nCurrentBlockFile++;
3129     }
3130 }
3131
3132 void UnloadBlockIndex()
3133 {
3134     mapBlockIndex.clear();
3135     setStakeSeen.clear();
3136     pindexGenesisBlock = NULL;
3137     nBestHeight = 0;
3138     nBestChainTrust = 0;
3139     nBestInvalidTrust = 0;
3140     hashBestChain = 0;
3141     pindexBest = NULL;
3142 }
3143
3144 bool LoadBlockIndex(bool fAllowNew)
3145 {
3146     if (fTestNet)
3147     {
3148         nNetworkID = 0xefc0f2cd;
3149
3150         bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; // 16 bits PoW target limit for testnet
3151         nStakeMinAge = 2 * nOneHour; // test net min age is 2 hours
3152         nModifierInterval = 20 * 60; // test modifier interval is 20 minutes
3153         nCoinbaseMaturity = 10; // test maturity is 10 blocks
3154         nStakeTargetSpacing = 5 * 60; // test block spacing is 5 minutes
3155     }
3156
3157     //
3158     // Load block index
3159     //
3160     CTxDB txdb("cr+");
3161     if (!txdb.LoadBlockIndex())
3162         return false;
3163
3164     //
3165     // Init with genesis block
3166     //
3167     if (mapBlockIndex.empty())
3168     {
3169         if (!fAllowNew)
3170             return false;
3171
3172         // Genesis block
3173
3174         // MainNet:
3175
3176         //CBlock(hash=00000a060336cbb72fe969666d337b87198b1add2abaa59cca226820b32933a4, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=4cb33b3b6a861dcbc685d3e614a9cafb945738d6833f182855679f2fad02057b, nTime=1360105017, nBits=1e0fffff, nNonce=1575379, vtx=1, vchBlockSig=)
3177         //  Coinbase(hash=4cb33b3b6a, nTime=1360105017, ver=1, vin.size=1, vout.size=1, nLockTime=0)
3178         //    CTxIn(COutPoint(0000000000, 4294967295), coinbase 04ffff001d020f274468747470733a2f2f626974636f696e74616c6b2e6f72672f696e6465782e7068703f746f7069633d3133343137392e6d736731353032313936236d736731353032313936)
3179         //    CTxOut(empty)
3180         //  vMerkleTree: 4cb33b3b6a
3181
3182         // TestNet:
3183
3184         //CBlock(hash=0000c763e402f2436da9ed36c7286f62c3f6e5dbafce9ff289bd43d7459327eb, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=4cb33b3b6a861dcbc685d3e614a9cafb945738d6833f182855679f2fad02057b, nTime=1360105017, nBits=1f00ffff, nNonce=46534, vtx=1, vchBlockSig=)
3185         //  Coinbase(hash=4cb33b3b6a, nTime=1360105017, ver=1, vin.size=1, vout.size=1, nLockTime=0)
3186         //    CTxIn(COutPoint(0000000000, 4294967295), coinbase 04ffff001d020f274468747470733a2f2f626974636f696e74616c6b2e6f72672f696e6465782e7068703f746f7069633d3133343137392e6d736731353032313936236d736731353032313936)
3187         //    CTxOut(empty)
3188         //  vMerkleTree: 4cb33b3b6a
3189
3190         const string strTimestamp = "https://bitcointalk.org/index.php?topic=134179.msg1502196#msg1502196";
3191         CTransaction txNew;
3192         txNew.nTime = 1360105017;
3193         txNew.vin.resize(1);
3194         txNew.vout.resize(1);
3195         txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector<unsigned char>(strTimestamp.begin(), strTimestamp.end());
3196         txNew.vout[0].SetEmpty();
3197         CBlock block;
3198         block.vtx.push_back(txNew);
3199         block.hashPrevBlock = 0;
3200         block.hashMerkleRoot = block.BuildMerkleTree();
3201         block.nVersion = 1;
3202         block.nTime    = 1360105017;
3203         block.nBits    = bnProofOfWorkLimit.GetCompact();
3204         block.nNonce   = !fTestNet ? 1575379 : 46534;
3205
3206         //// debug print
3207         assert(block.hashMerkleRoot == uint256("0x4cb33b3b6a861dcbc685d3e614a9cafb945738d6833f182855679f2fad02057b"));
3208         block.print();
3209         assert(block.GetHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet));
3210         assert(block.CheckBlock());
3211
3212         // Start new block file
3213         unsigned int nFile;
3214         unsigned int nBlockPos;
3215         if (!block.WriteToDisk(nFile, nBlockPos))
3216             return error("LoadBlockIndex() : writing genesis block to disk failed");
3217         if (!block.AddToBlockIndex(nFile, nBlockPos))
3218             return error("LoadBlockIndex() : genesis block not accepted");
3219
3220         // initialize synchronized checkpoint
3221         if (!Checkpoints::WriteSyncCheckpoint((!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)))
3222             return error("LoadBlockIndex() : failed to init sync checkpoint");
3223
3224         // upgrade time set to zero if txdb initialized
3225         {
3226             if (!txdb.WriteModifierUpgradeTime(0))
3227                 return error("LoadBlockIndex() : failed to init upgrade info");
3228             printf(" Upgrade Info: ModifierUpgradeTime txdb initialization\n");
3229         }
3230     }
3231
3232     {
3233         CTxDB txdb("r+");
3234         string strPubKey = "";
3235         if (!txdb.ReadCheckpointPubKey(strPubKey) || strPubKey != CSyncCheckpoint::strMasterPubKey)
3236         {
3237             // write checkpoint master key to db
3238             txdb.TxnBegin();
3239             if (!txdb.WriteCheckpointPubKey(CSyncCheckpoint::strMasterPubKey))
3240                 return error("LoadBlockIndex() : failed to write new checkpoint master key to db");
3241             if (!txdb.TxnCommit())
3242                 return error("LoadBlockIndex() : failed to commit new checkpoint master key to db");
3243             if ((!fTestNet) && !Checkpoints::ResetSyncCheckpoint())
3244                 return error("LoadBlockIndex() : failed to reset sync-checkpoint");
3245         }
3246
3247         // upgrade time set to zero if blocktreedb initialized
3248         if (txdb.ReadModifierUpgradeTime(nModifierUpgradeTime))
3249         {
3250             if (nModifierUpgradeTime)
3251                 printf(" Upgrade Info: blocktreedb upgrade detected at timestamp %d\n", nModifierUpgradeTime);
3252             else
3253                 printf(" Upgrade Info: no blocktreedb upgrade detected.\n");
3254         }
3255         else
3256         {
3257             nModifierUpgradeTime = GetTime();
3258             printf(" Upgrade Info: upgrading blocktreedb at timestamp %u\n", nModifierUpgradeTime);
3259             if (!txdb.WriteModifierUpgradeTime(nModifierUpgradeTime))
3260                 return error("LoadBlockIndex() : failed to write upgrade info");
3261         }
3262
3263 #ifndef USE_LEVELDB
3264         txdb.Close();
3265 #endif
3266     }
3267
3268     return true;
3269 }
3270
3271
3272
3273 void PrintBlockTree()
3274 {
3275     // pre-compute tree structure
3276     map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
3277     for (auto mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
3278     {
3279         CBlockIndex* pindex = (*mi).second;
3280         mapNext[pindex->pprev].push_back(pindex);
3281         // test
3282         //while (rand() % 3 == 0)
3283         //    mapNext[pindex->pprev].push_back(pindex);
3284     }
3285
3286     vector<pair<int, CBlockIndex*> > vStack;
3287     vStack.push_back(make_pair(0, pindexGenesisBlock));
3288
3289     int nPrevCol = 0;
3290     while (!vStack.empty())
3291     {
3292         int nCol = vStack.back().first;
3293         CBlockIndex* pindex = vStack.back().second;
3294         vStack.pop_back();
3295
3296         // print split or gap
3297         if (nCol > nPrevCol)
3298         {
3299             for (int i = 0; i < nCol-1; i++)
3300                 printf("| ");
3301             printf("|\\\n");
3302         }
3303         else if (nCol < nPrevCol)
3304         {
3305             for (int i = 0; i < nCol; i++)
3306                 printf("| ");
3307             printf("|\n");
3308        }
3309         nPrevCol = nCol;
3310
3311         // print columns
3312         for (int i = 0; i < nCol; i++)
3313             printf("| ");
3314
3315         // print item
3316         CBlock block;
3317         block.ReadFromDisk(pindex);
3318         printf("%d (%u,%u) %s  %08x  %s  mint %7s  tx %" PRIszu "",
3319             pindex->nHeight,
3320             pindex->nFile,
3321             pindex->nBlockPos,
3322             block.GetHash().ToString().c_str(),
3323             block.nBits,
3324             DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
3325             FormatMoney(pindex->nMint).c_str(),
3326             block.vtx.size());
3327
3328         PrintWallets(block);
3329
3330         // put the main time-chain first
3331         vector<CBlockIndex*>& vNext = mapNext[pindex];
3332         for (unsigned int i = 0; i < vNext.size(); i++)
3333         {
3334             if (vNext[i]->pnext)
3335             {
3336                 swap(vNext[0], vNext[i]);
3337                 break;
3338             }
3339         }
3340
3341         // iterate children
3342         for (unsigned int i = 0; i < vNext.size(); i++)
3343             vStack.push_back(make_pair(nCol+i, vNext[i]));
3344     }
3345 }
3346
3347 bool LoadExternalBlockFile(FILE* fileIn, CClientUIInterface& uiInterface)
3348 {
3349     auto nStart = GetTimeMillis();
3350     vector<uint8_t> pchData(10 * (8+MAX_BLOCK_SIZE));
3351     int32_t nLoaded = 0;
3352     {
3353         LOCK(cs_main);
3354         try {
3355             CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION);
3356             uint32_t nPos = 0;
3357             while (nPos != std::numeric_limits<uint32_t>::max() && blkdat.good() && !fRequestShutdown)
3358             {
3359                 do
3360                 {
3361                     fseek(blkdat, nPos, SEEK_SET);
3362                     auto nRead = fread(&pchData[0], 1, pchData.size(), blkdat);
3363                     if (nRead <= 8)
3364                     {
3365                         nPos = numeric_limits<uint32_t>::max();
3366                         break;
3367                     }
3368                     auto it = pchData.begin();
3369                     while(it != pchData.end() && !fRequestShutdown)
3370                     {
3371                         auto nBlockLength = *reinterpret_cast<const uint32_t*>(&(*(it+4)));
3372                         auto SeekToNext = [&pchData, &it, &nPos, &nBlockLength]() {
3373                             auto previt = it;
3374                             it = search(it+8, pchData.end(), BEGIN(nNetworkID), END(nNetworkID));
3375                             if (it != pchData.end())
3376                                 nPos += (it - previt);
3377                         };
3378                         if (nBlockLength > 0)
3379                         {
3380                             if (nBlockLength > (uint32_t)distance(it, pchData.end()))
3381                             {
3382                                 SeekToNext();
3383                                 break; // We've reached the end of buffer
3384                             }
3385                             else
3386                             {
3387                                 CBlock block;
3388                                 try
3389                                 {
3390                                     vector<unsigned char> vchBlockBytes(it+8, it+8+nBlockLength);
3391                                     CDataStream blockData(vchBlockBytes, SER_NETWORK, PROTOCOL_VERSION);
3392                                     blockData >> block;
3393                                 }
3394                                 catch (const std::exception&)
3395                                 {
3396                                     printf("LoadExternalBlockFile() : Deserialize error caught at the position %" PRIu32 ", this block may be truncated.", nPos);
3397                                     SeekToNext();
3398                                     break;
3399                                 }
3400                                 if (ProcessBlock(NULL, &block))
3401                                     nLoaded++;
3402                                 advance(it, 8 + nBlockLength);
3403                                 nPos += (8 + nBlockLength);
3404                                 {
3405                                     static int64_t nLastUpdate = 0;
3406                                     if (GetTimeMillis() - nLastUpdate > 1000)
3407                                     {
3408                                         uiInterface.InitMessage(strprintf(_("%" PRId32 " blocks were read."), nLoaded));
3409                                         nLastUpdate = GetTimeMillis();
3410                                     }
3411                                 }
3412                             }
3413                         }
3414                         else
3415                         {
3416                             SeekToNext();
3417                         }
3418                     }
3419                 }
3420                 while(!fRequestShutdown);
3421             }
3422         }
3423         catch (const std::exception&) {
3424             printf("%s() : I/O error caught during load\n",
3425                    BOOST_CURRENT_FUNCTION);
3426         }
3427     }
3428     printf("Loaded %i blocks from external file in %" PRId64 "ms\n", nLoaded, GetTimeMillis() - nStart);
3429     return nLoaded > 0;
3430 }
3431
3432 //////////////////////////////////////////////////////////////////////////////
3433 //
3434 // CAlert
3435 //
3436
3437 extern map<uint256, CAlert> mapAlerts;
3438 extern CCriticalSection cs_mapAlerts;
3439
3440 string GetWarnings(string strFor)
3441 {
3442     int nPriority = 0;
3443     string strStatusBar;
3444     string strRPC;
3445
3446     if (GetBoolArg("-testsafemode"))
3447         strRPC = "test";
3448
3449     // Misc warnings like out of disk space and clock is wrong
3450     if (!strMiscWarning.empty())
3451     {
3452         nPriority = 1000;
3453         strStatusBar = strMiscWarning;
3454     }
3455
3456     // if detected unmet upgrade requirement enter safe mode
3457     // Note: Modifier upgrade requires blockchain redownload if past protocol switch
3458     if (IsFixedModifierInterval(nModifierUpgradeTime + nOneDay)) // 1 day margin
3459     {
3460         nPriority = 5000;
3461         strStatusBar = strRPC = "WARNING: Blockchain redownload required approaching or past v.0.4.4.6u4 upgrade deadline.";
3462     }
3463
3464     // if detected invalid checkpoint enter safe mode
3465     if (Checkpoints::hashInvalidCheckpoint != 0)
3466     {
3467         nPriority = 3000;
3468         strStatusBar = strRPC = _("WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers.");
3469     }
3470
3471     // Alerts
3472     {
3473         LOCK(cs_mapAlerts);
3474         for(auto& item : mapAlerts)
3475         {
3476             const CAlert& alert = item.second;
3477             if (alert.AppliesToMe() && alert.nPriority > nPriority)
3478             {
3479                 nPriority = alert.nPriority;
3480                 strStatusBar = alert.strStatusBar;
3481                 if (nPriority > 1000)
3482                     strRPC = strStatusBar;
3483             }
3484         }
3485     }
3486
3487     if (strFor == "statusbar")
3488         return strStatusBar;
3489     else if (strFor == "rpc")
3490         return strRPC;
3491     assert(!"GetWarnings() : invalid parameter");
3492     return "error";
3493 }
3494
3495
3496
3497
3498
3499
3500
3501
3502 //////////////////////////////////////////////////////////////////////////////
3503 //
3504 // Messages
3505 //
3506
3507
3508 bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
3509 {
3510     int nType = inv.GetType();
3511     auto nHash = inv.GetHash();
3512
3513     switch (nType)
3514     {
3515     case MSG_TX:
3516         {
3517         bool txInMap = false;
3518             {
3519             LOCK(mempool.cs);
3520             txInMap = (mempool.exists(nHash));
3521             }
3522         return txInMap ||
3523                mapOrphanTransactions.count(nHash) ||
3524                txdb.ContainsTx(nHash);
3525         }
3526
3527     case MSG_BLOCK:
3528         return mapBlockIndex.count(nHash) ||
3529                mapOrphanBlocks.count(nHash);
3530     }
3531     // Don't know what it is, just say we already got one
3532     return true;
3533 }
3534
3535 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
3536 {
3537     static map<CService, CPubKey> mapReuseKey;
3538     RandAddSeedPerfmon();
3539     if (fDebug)
3540         printf("received: %s (%" PRIszu " bytes)\n", strCommand.c_str(), vRecv.size());
3541     if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
3542     {
3543         printf("dropmessagestest DROPPING RECV MESSAGE\n");
3544         return true;
3545     }
3546
3547     if (strCommand == "version")
3548     {
3549         // Each connection can only send one version message
3550         if (pfrom->nVersion != 0)
3551         {
3552             pfrom->Misbehaving(1);
3553             return false;
3554         }
3555
3556         int64_t nTime;
3557         CAddress addrMe;
3558         CAddress addrFrom;
3559         uint64_t nNonce = 1;
3560         vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
3561         if (pfrom->nVersion < MIN_PROTO_VERSION)
3562         {
3563             // Since February 20, 2012, the protocol is initiated at version 209,
3564             // and earlier versions are no longer supported
3565             printf("partner %s using obsolete version %i; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion);
3566             pfrom->fDisconnect = true;
3567             return false;
3568         }
3569
3570         if (pfrom->nVersion == 10300)
3571             pfrom->nVersion = 300;
3572         if (!vRecv.empty())
3573             vRecv >> addrFrom >> nNonce;
3574         if (!vRecv.empty())
3575             vRecv >> pfrom->strSubVer;
3576         if (!vRecv.empty())
3577             vRecv >> pfrom->nStartingHeight;
3578
3579         if (pfrom->fInbound && addrMe.IsRoutable())
3580         {
3581             pfrom->addrLocal = addrMe;
3582             SeenLocal(addrMe);
3583         }
3584
3585         // Disconnect if we connected to ourself
3586         if (nNonce == nLocalHostNonce && nNonce > 1)
3587         {
3588             printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
3589             pfrom->fDisconnect = true;
3590             return true;
3591         }
3592
3593         if (pfrom->nVersion < 60010)
3594         {
3595             printf("partner %s using a buggy client %d, disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion);
3596             pfrom->fDisconnect = true;
3597             return true;
3598         }
3599
3600         // record my external IP reported by peer
3601         if (addrFrom.IsRoutable() && addrMe.IsRoutable())
3602             addrSeenByPeer = addrMe;
3603
3604         // Be shy and don't send version until we hear
3605         if (pfrom->fInbound)
3606             pfrom->PushVersion();
3607
3608         pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
3609
3610         AddTimeData(pfrom->addr, nTime);
3611
3612         // Change version
3613         pfrom->PushMessage("verack");
3614         pfrom->vSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
3615
3616         if (!pfrom->fInbound)
3617         {
3618             // Advertise our address
3619             if (!fNoListen && !IsInitialBlockDownload())
3620             {
3621                 auto addr = GetLocalAddress(&pfrom->addr);
3622                 if (addr.IsRoutable())
3623                     pfrom->PushAddress(addr);
3624             }
3625
3626             // Get recent addresses
3627             if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
3628             {
3629                 pfrom->PushMessage("getaddr");
3630                 pfrom->fGetAddr = true;
3631             }
3632             addrman.Good(pfrom->addr);
3633         } else {
3634             if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
3635             {
3636                 addrman.Add(addrFrom, addrFrom);
3637                 addrman.Good(addrFrom);
3638             }
3639         }
3640
3641         // Ask the first connected node for block updates
3642         static int nAskedForBlocks = 0;
3643         if (!pfrom->fClient && !pfrom->fOneShot &&
3644             (pfrom->nStartingHeight > (nBestHeight - 144)) &&
3645             (pfrom->nVersion < NOBLKS_VERSION_START ||
3646              pfrom->nVersion >= NOBLKS_VERSION_END) &&
3647              (nAskedForBlocks < 1 || vNodes.size() <= 1))
3648         {
3649             nAskedForBlocks++;
3650             pfrom->PushGetBlocks(pindexBest, uint256(0));
3651         }
3652
3653         // Relay alerts
3654         {
3655             LOCK(cs_mapAlerts);
3656             for(auto& item : mapAlerts)
3657                 item.second.RelayTo(pfrom);
3658         }
3659
3660         // Relay sync-checkpoint
3661         {
3662             LOCK(Checkpoints::cs_hashSyncCheckpoint);
3663             if (!Checkpoints::checkpointMessage.IsNull())
3664                 Checkpoints::checkpointMessage.RelayTo(pfrom);
3665         }
3666
3667         pfrom->fSuccessfullyConnected = true;
3668
3669         printf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str());
3670
3671         cPeerBlockCounts.input(pfrom->nStartingHeight);
3672
3673         // ppcoin: ask for pending sync-checkpoint if any
3674         if (!IsInitialBlockDownload())
3675             Checkpoints::AskForPendingSyncCheckpoint(pfrom);
3676     }
3677
3678
3679     else if (pfrom->nVersion == 0)
3680     {
3681         // Must have a version message before anything else
3682         pfrom->Misbehaving(1);
3683         return false;
3684     }
3685
3686
3687     else if (strCommand == "verack")
3688     {
3689         pfrom->vRecv.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
3690     }
3691
3692
3693     else if (strCommand == "addr")
3694     {
3695         vector<CAddress> vAddr;
3696         vRecv >> vAddr;
3697
3698         // Don't want addr from older versions unless seeding
3699         if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
3700             return true;
3701         if (vAddr.size() > 1000)
3702         {
3703             pfrom->Misbehaving(20);
3704             return error("message addr size() = %" PRIszu "", vAddr.size());
3705         }
3706
3707         // Store the new addresses
3708         vector<CAddress> vAddrOk;
3709         auto nNow = GetAdjustedTime();
3710         auto nSince = nNow - 10 * 60;
3711         for(CAddress& addr :  vAddr)
3712         {
3713             if (fShutdown)
3714                 return true;
3715             if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
3716                 addr.nTime = nNow - 5 * nOneDay;
3717             pfrom->AddAddressKnown(addr);
3718             bool fReachable = IsReachable(addr);
3719             if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
3720             {
3721                 // Relay to a limited number of other nodes
3722                 {
3723                     LOCK(cs_vNodes);
3724                     // Use deterministic randomness to send to the same nodes for 24 hours
3725                     // at a time so the setAddrKnowns of the chosen nodes prevent repeats
3726                     static uint256 hashSalt;
3727                     if (hashSalt == 0)
3728                         hashSalt = GetRandHash();
3729                     uint64_t hashAddr = addr.GetHash();
3730                     uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/nOneDay);
3731                     hashRand = Hash(hashRand.begin(), hashRand.end());
3732                     multimap<uint256, CNode*> mapMix;
3733                     for(CNode* pnode :  vNodes)
3734                     {
3735                         if (pnode->nVersion < CADDR_TIME_VERSION)
3736                             continue;
3737                         unsigned int nPointer;
3738                         memcpy(&nPointer, &pnode, sizeof(nPointer));
3739                         uint256 hashKey = hashRand ^ nPointer;
3740                         hashKey = Hash(hashKey.begin(), hashKey.end());
3741                         mapMix.insert(make_pair(hashKey, pnode));
3742                     }
3743                     int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
3744                     for (auto mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
3745                         ((*mi).second)->PushAddress(addr);
3746                 }
3747             }
3748             // Do not store addresses outside our network
3749             if (fReachable)
3750                 vAddrOk.push_back(addr);
3751         }
3752         addrman.Add(vAddrOk, pfrom->addr, 2 * nOneHour);
3753         if (vAddr.size() < 1000)
3754             pfrom->fGetAddr = false;
3755         if (pfrom->fOneShot)
3756             pfrom->fDisconnect = true;
3757     }
3758
3759     else if (strCommand == "inv")
3760     {
3761         vector<CInv> vInv;
3762         vRecv >> vInv;
3763         if (vInv.size() > MAX_INV_SZ)
3764         {
3765             pfrom->Misbehaving(20);
3766             return error("message inv size() = %" PRIszu "", vInv.size());
3767         }
3768
3769         // find last block in inv vector
3770         int nLastBlock = -1;
3771         for (size_t nInv = 0; nInv < vInv.size(); nInv++) {
3772             if (vInv[vInv.size() - 1 - nInv].GetType() == MSG_BLOCK) {
3773                 nLastBlock = (int) (vInv.size() - 1 - nInv);
3774                 break;
3775             }
3776         }
3777         CTxDB txdb("r");
3778         for (size_t nInv = 0; nInv < vInv.size(); nInv++)
3779         {
3780             const CInv &inv = vInv[nInv];
3781             int nType = inv.GetType();
3782             auto nHash = inv.GetHash();
3783
3784             if (fShutdown)
3785                 return true;
3786             pfrom->AddInventoryKnown(inv);
3787
3788             bool fAlreadyHave = AlreadyHave(txdb, inv);
3789             if (fDebug)
3790                 printf("  got inventory: %s  %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
3791
3792             if (!fAlreadyHave)
3793                 pfrom->AskFor(inv);
3794             else if (nType == MSG_BLOCK && mapOrphanBlocks.count(nHash)) {
3795                 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[nHash]));
3796             } else if (nType == nLastBlock) {
3797                 // In case we are on a very long side-chain, it is possible that we already have
3798                 // the last block in an inv bundle sent in response to getblocks. Try to detect
3799                 // this situation and push another getblocks to continue.
3800                 pfrom->PushGetBlocks(mapBlockIndex[nHash], uint256(0));
3801                 if (fDebug)
3802                     printf("force request: %s\n", inv.ToString().c_str());
3803             }
3804
3805             // Track requests for our stuff
3806             Inventory(nHash);
3807         }
3808     }
3809
3810
3811     else if (strCommand == "getdata")
3812     {
3813         vector<CInv> vInv;
3814         vRecv >> vInv;
3815         if (vInv.size() > MAX_INV_SZ)
3816         {
3817             pfrom->Misbehaving(20);
3818             return error("message getdata size() = %" PRIszu "", vInv.size());
3819         }
3820
3821         if (fDebugNet || (vInv.size() != 1))
3822             printf("received getdata (%" PRIszu " invsz)\n", vInv.size());
3823
3824         for(const CInv& inv :  vInv)
3825         {
3826             if (fShutdown)
3827                 return true;
3828             if (fDebugNet || (vInv.size() == 1))
3829                 printf("received getdata for: %s\n", inv.ToString().c_str());
3830
3831             int nType = inv.GetType();
3832             auto nHash = inv.GetHash();
3833
3834             if (nType == MSG_BLOCK)
3835             {
3836                 // Send block from disk
3837                 auto mi = mapBlockIndex.find(nHash);
3838                 if (mi != mapBlockIndex.end())
3839                 {
3840                     CBlock block;
3841                     block.ReadFromDisk((*mi).second);
3842                     pfrom->PushMessage("block", block);
3843
3844                     // Trigger them to send a getblocks request for the next batch of inventory
3845                     if (nHash == pfrom->hashContinue)
3846                     {
3847                         // ppcoin: send latest proof-of-work block to allow the
3848                         // download node to accept as orphan (proof-of-stake 
3849                         // block might be rejected by stake connection check)
3850                         vector<CInv> vInv;
3851                         vInv.push_back(CInv(MSG_BLOCK, GetLastBlockIndex(pindexBest, false)->GetBlockHash()));
3852                         pfrom->PushMessage("inv", vInv);
3853                         pfrom->hashContinue = 0;
3854                     }
3855                 }
3856             }
3857             else if (inv.IsKnownType())
3858             {
3859                 // Send stream from relay memory
3860                 bool pushed = false;
3861                 {
3862                     LOCK(cs_mapRelay);
3863                     auto mi = mapRelay.find(inv);
3864                     if (mi != mapRelay.end()) {
3865                         pfrom->PushMessage(inv.GetCommand(), (*mi).second);
3866                         pushed = true;
3867                     }
3868                 }
3869                 if (!pushed && nType == MSG_TX) {
3870                     LOCK(mempool.cs);
3871                     if (mempool.exists(nHash)) {
3872                         CTransaction tx = mempool.lookup(nHash);
3873                         CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
3874                         ss.reserve(1000);
3875                         ss << tx;
3876                         pfrom->PushMessage("tx", ss);
3877                     }
3878                 }
3879             }
3880
3881             // Track requests for our stuff
3882             Inventory(nHash);
3883         }
3884     }
3885
3886
3887     else if (strCommand == "getblocks")
3888     {
3889         CBlockLocator locator;
3890         uint256 hashStop;
3891         vRecv >> locator >> hashStop;
3892
3893         // Find the last block the caller has in the main chain
3894         CBlockIndex* pindex = locator.GetBlockIndex();
3895
3896         // Send the rest of the chain
3897         if (pindex)
3898             pindex = pindex->pnext;
3899         int nLimit = 500;
3900         printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
3901         for (; pindex; pindex = pindex->pnext)
3902         {
3903             if (pindex->GetBlockHash() == hashStop)
3904             {
3905                 printf("  getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str());
3906                 // ppcoin: tell downloading node about the latest block if it's
3907                 // without risk being rejected due to stake connection check
3908                 if (hashStop != hashBestChain && pindex->GetBlockTime() + nStakeMinAge > pindexBest->GetBlockTime())
3909                     pfrom->PushInventory(CInv(MSG_BLOCK, hashBestChain));
3910                 break;
3911             }
3912             pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
3913             if (--nLimit <= 0)
3914             {
3915                 // When this block is requested, we'll send an inv that'll make them
3916                 // getblocks the next batch of inventory.
3917                 printf("  getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str());
3918                 pfrom->hashContinue = pindex->GetBlockHash();
3919                 break;
3920             }
3921         }
3922     }
3923     else if (strCommand == "checkpoint")
3924     {
3925         CSyncCheckpoint checkpoint;
3926         vRecv >> checkpoint;
3927
3928         if (checkpoint.ProcessSyncCheckpoint(pfrom))
3929         {
3930             // Relay
3931             pfrom->hashCheckpointKnown = checkpoint.hashCheckpoint;
3932             LOCK(cs_vNodes);
3933             for(CNode* pnode :  vNodes)
3934                 checkpoint.RelayTo(pnode);
3935         }
3936     }
3937
3938     else if (strCommand == "getheaders")
3939     {
3940         CBlockLocator locator;
3941         uint256 hashStop;
3942         vRecv >> locator >> hashStop;
3943
3944         CBlockIndex* pindex = NULL;
3945         if (locator.IsNull())
3946         {
3947             // If locator is null, return the hashStop block
3948             auto mi = mapBlockIndex.find(hashStop);
3949             if (mi == mapBlockIndex.end())
3950                 return true;
3951             pindex = (*mi).second;
3952         }
3953         else
3954         {
3955             // Find the last block the caller has in the main chain
3956             pindex = locator.GetBlockIndex();
3957             if (pindex)
3958                 pindex = pindex->pnext;
3959         }
3960
3961         vector<CBlock> vHeaders;
3962         int nLimit = 2000;
3963         printf("getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str());
3964         for (; pindex; pindex = pindex->pnext)
3965         {
3966             vHeaders.push_back(pindex->GetBlockHeader());
3967             if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
3968                 break;
3969         }
3970         pfrom->PushMessage("headers", vHeaders);
3971     }
3972
3973
3974     else if (strCommand == "tx")
3975     {
3976         vector<uint256> vWorkQueue;
3977         vector<uint256> vEraseQueue;
3978         CDataStream vMsg(vRecv);
3979         CTxDB txdb("r");
3980         CTransaction tx;
3981         vRecv >> tx;
3982
3983         CInv inv(MSG_TX, tx.GetHash());
3984         pfrom->AddInventoryKnown(inv);
3985
3986         bool fMissingInputs = false;
3987         if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs))
3988         {
3989             auto nHash = inv.GetHash();
3990
3991             SyncWithWallets(tx, NULL, true);
3992             RelayTransaction(tx, nHash);
3993             mapAlreadyAskedFor.erase(inv);
3994             vWorkQueue.push_back(nHash);
3995             vEraseQueue.push_back(nHash);
3996
3997             // Recursively process any orphan transactions that depended on this one
3998             for (unsigned int i = 0; i < vWorkQueue.size(); i++)
3999             {
4000                 auto hashPrev = vWorkQueue[i];
4001                 for (auto mi = mapOrphanTransactionsByPrev[hashPrev].begin();
4002                      mi != mapOrphanTransactionsByPrev[hashPrev].end();
4003                      ++mi)
4004                 {
4005                     const uint256& orphanTxHash = *mi;
4006                     auto& orphanTx = mapOrphanTransactions[orphanTxHash];
4007                     bool fMissingInputs2 = false;
4008
4009                     if (orphanTx.AcceptToMemoryPool(txdb, true, &fMissingInputs2))
4010                     {
4011                         printf("   accepted orphan tx %s\n", orphanTxHash.ToString().substr(0,10).c_str());
4012                         SyncWithWallets(tx, NULL, true);
4013                         RelayTransaction(orphanTx, orphanTxHash);
4014                         mapAlreadyAskedFor.erase(CInv(MSG_TX, orphanTxHash));
4015                         vWorkQueue.push_back(orphanTxHash);
4016                         vEraseQueue.push_back(orphanTxHash);
4017                     }
4018                     else if (!fMissingInputs2)
4019                     {
4020                         // invalid orphan
4021                         vEraseQueue.push_back(orphanTxHash);
4022                         printf("   removed invalid orphan tx %s\n", orphanTxHash.ToString().substr(0,10).c_str());
4023                     }
4024                 }
4025             }
4026
4027             for(uint256 hash :  vEraseQueue)
4028                 EraseOrphanTx(hash);
4029         }
4030         else if (fMissingInputs)
4031         {
4032             AddOrphanTx(tx);
4033
4034             // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
4035             unsigned int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
4036             if (nEvicted > 0)
4037                 printf("mapOrphan overflow, removed %u tx\n", nEvicted);
4038         }
4039         if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
4040     }
4041
4042
4043     else if (strCommand == "block")
4044     {
4045         CBlock block;
4046         vRecv >> block;
4047         auto hashBlock = block.GetHash();
4048
4049         printf("received block %s\n", hashBlock.ToString().substr(0,20).c_str());
4050         // block.print();
4051
4052         CInv inv(MSG_BLOCK, hashBlock);
4053         pfrom->AddInventoryKnown(inv);
4054
4055         if (ProcessBlock(pfrom, &block))
4056             mapAlreadyAskedFor.erase(inv);
4057         if (block.nDoS) pfrom->Misbehaving(block.nDoS);
4058     }
4059
4060
4061     // This asymmetric behavior for inbound and outbound connections was introduced
4062     // to prevent a fingerprinting attack: an attacker can send specific fake addresses
4063     // to users' AddrMan and later request them by sending getaddr messages. 
4064     // Making users (which are behind NAT and can only make outgoing connections) ignore 
4065     // getaddr message mitigates the attack.
4066     else if ((strCommand == "getaddr") && (pfrom->fInbound))
4067     {
4068         // Don't return addresses older than nCutOff timestamp
4069         int64_t nCutOff = GetTime() - (nNodeLifespan * nOneDay);
4070         pfrom->vAddrToSend.clear();
4071         vector<CAddress> vAddr = addrman.GetAddr();
4072         for(const CAddress &addr :  vAddr)
4073             if(addr.nTime > nCutOff)
4074                 pfrom->PushAddress(addr);
4075     }
4076
4077
4078     else if (strCommand == "mempool")
4079     {
4080         std::vector<uint256> vtxid;
4081         mempool.queryHashes(vtxid);
4082         vector<CInv> vInv;
4083         for (unsigned int i = 0; i < vtxid.size(); i++) {
4084             CInv inv(MSG_TX, vtxid[i]);
4085             vInv.push_back(inv);
4086             if (i == (MAX_INV_SZ - 1))
4087                     break;
4088         }
4089         if (vInv.size() > 0)
4090             pfrom->PushMessage("inv", vInv);
4091     }
4092
4093
4094     else if (strCommand == "checkorder")
4095     {
4096         uint256 hashReply;
4097         vRecv >> hashReply;
4098
4099         if (!GetBoolArg("-allowreceivebyip"))
4100         {
4101             pfrom->PushMessage("reply", hashReply, 2, string(""));
4102             return true;
4103         }
4104
4105         CWalletTx order;
4106         vRecv >> order;
4107
4108         /// we have a chance to check the order here
4109
4110         // Keep giving the same key to the same ip until they use it
4111         if (!mapReuseKey.count(pfrom->addr))
4112             pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr], true);
4113
4114         // Send back approval of order and pubkey to use
4115         CScript scriptPubKey;
4116         scriptPubKey << mapReuseKey[pfrom->addr] << OP_CHECKSIG;
4117         pfrom->PushMessage("reply", hashReply, 0, scriptPubKey);
4118     }
4119
4120
4121     else if (strCommand == "reply")
4122     {
4123         uint256 hashReply;
4124         vRecv >> hashReply;
4125
4126         CRequestTracker tracker;
4127         {
4128             LOCK(pfrom->cs_mapRequests);
4129             auto mi = pfrom->mapRequests.find(hashReply);
4130             if (mi != pfrom->mapRequests.end())
4131             {
4132                 tracker = (*mi).second;
4133                 pfrom->mapRequests.erase(mi);
4134             }
4135         }
4136         if (!tracker.IsNull())
4137             tracker.fn(tracker.param1, vRecv);
4138     }
4139
4140
4141     else if (strCommand == "ping")
4142     {
4143         uint64_t nonce = 0;
4144         vRecv >> nonce;
4145         // Echo the message back with the nonce. This allows for two useful features:
4146         //
4147         // 1) A remote node can quickly check if the connection is operational
4148         // 2) Remote nodes can measure the latency of the network thread. If this node
4149         //    is overloaded it won't respond to pings quickly and the remote node can
4150         //    avoid sending us more work, like chain download requests.
4151         //
4152         // The nonce stops the remote getting confused between different pings: without
4153         // it, if the remote node sends a ping once per second and this node takes 5
4154         // seconds to respond to each, the 5th ping the remote sends would appear to
4155         // return very quickly.
4156         pfrom->PushMessage("pong", nonce);
4157     }
4158
4159
4160     else if (strCommand == "alert")
4161     {
4162         CAlert alert;
4163         vRecv >> alert;
4164
4165         auto alertHash = alert.GetHash();
4166         if (pfrom->setKnown.count(alertHash) == 0)
4167         {
4168             if (alert.ProcessAlert())
4169             {
4170                 // Relay
4171                 pfrom->setKnown.insert(alertHash);
4172                 {
4173                     LOCK(cs_vNodes);
4174                     for(CNode* pnode :  vNodes)
4175                         alert.RelayTo(pnode);
4176                 }
4177             }
4178             else {
4179                 // Small DoS penalty so peers that send us lots of
4180                 // duplicate/expired/invalid-signature/whatever alerts
4181                 // eventually get banned.
4182                 // This isn't a Misbehaving(100) (immediate ban) because the
4183                 // peer might be an older or different implementation with
4184                 // a different signature key, etc.
4185                 pfrom->Misbehaving(10);
4186             }
4187         }
4188     }
4189
4190
4191     else
4192     {
4193         // Ignore unknown commands for extensibility
4194     }
4195
4196
4197     // Update the last seen time for this node's address
4198     if (pfrom->fNetworkNode)
4199         if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
4200             AddressCurrentlyConnected(pfrom->addr);
4201
4202
4203     return true;
4204 }
4205
4206 bool ProcessMessages(CNode* pfrom)
4207 {
4208     CDataStream& vRecv = pfrom->vRecv;
4209     if (vRecv.empty())
4210         return true;
4211     //if (fDebug)
4212     //    printf("ProcessMessages(%u bytes)\n", vRecv.size());
4213
4214     //
4215     // Message format
4216     //  (4) message start
4217     //  (12) command
4218     //  (4) size
4219     //  (4) checksum
4220     //  (x) data
4221     //
4222
4223     for ( ; ; )
4224     {
4225         // Don't bother if send buffer is too full to respond anyway
4226         if (pfrom->vSend.size() >= SendBufferSize())
4227             break;
4228
4229         // Scan for message start
4230         CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(nNetworkID), END(nNetworkID));
4231         int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
4232         if (vRecv.end() - pstart < nHeaderSize)
4233         {
4234             if ((int)vRecv.size() > nHeaderSize)
4235             {
4236                 printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
4237                 vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
4238             }
4239             break;
4240         }
4241         if (pstart - vRecv.begin() > 0)
4242             printf("\n\nPROCESSMESSAGE SKIPPED %" PRIpdd " BYTES\n\n", pstart - vRecv.begin());
4243         vRecv.erase(vRecv.begin(), pstart);
4244
4245         // Read header
4246         vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
4247         CMessageHeader hdr;
4248         vRecv >> hdr;
4249         if (!hdr.IsValid())
4250         {
4251             printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
4252             continue;
4253         }
4254         string strCommand = hdr.GetCommand();
4255
4256         // Message size
4257         unsigned int nMessageSize = hdr.nMessageSize;
4258         if (nMessageSize > MAX_SIZE)
4259         {
4260             printf("ProcessMessages(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
4261             continue;
4262         }
4263         if (nMessageSize > vRecv.size())
4264         {
4265             // Rewind and wait for rest of message
4266             vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
4267             break;
4268         }
4269
4270         // Checksum
4271         auto hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
4272         unsigned int nChecksum = 0;
4273         memcpy(&nChecksum, &hash, sizeof(nChecksum));
4274         if (nChecksum != hdr.nChecksum)
4275         {
4276             printf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
4277                strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
4278             continue;
4279         }
4280
4281         // Copy message to its own buffer
4282         CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
4283         vRecv.ignore(nMessageSize);
4284
4285         // Process message
4286         bool fRet = false;
4287         try
4288         {
4289             {
4290                 LOCK(cs_main);
4291                 fRet = ProcessMessage(pfrom, strCommand, vMsg);
4292             }
4293             if (fShutdown)
4294                 return true;
4295         }
4296         catch (std::ios_base::failure& e)
4297         {
4298             if (strstr(e.what(), "end of data"))
4299             {
4300                 // Allow exceptions from under-length message on vRecv
4301                 printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
4302             }
4303             else if (strstr(e.what(), "size too large"))
4304             {
4305                 // Allow exceptions from over-long size
4306                 printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
4307             }
4308             else
4309             {
4310                 PrintExceptionContinue(&e, "ProcessMessages()");
4311             }
4312         }
4313         catch (std::exception& e) {
4314             PrintExceptionContinue(&e, "ProcessMessages()");
4315         } catch (...) {
4316             PrintExceptionContinue(NULL, "ProcessMessages()");
4317         }
4318
4319         if (!fRet)
4320             printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
4321     }
4322
4323     vRecv.Compact();
4324     return true;
4325 }
4326
4327
4328 bool SendMessages(CNode* pto)
4329 {
4330     TRY_LOCK(cs_main, lockMain);
4331     if (lockMain) {
4332         // Current time in microseconds
4333         auto nNow = GetTimeMicros();
4334
4335         // Don't send anything until we get their version message
4336         if (pto->nVersion == 0)
4337             return true;
4338
4339         // Keep-alive ping. We send a nonce of zero because we don't use it anywhere
4340         // right now.
4341         if (pto->nLastSend && GetTime() - pto->nLastSend > nPingInterval && pto->vSend.empty()) {
4342             uint64_t nonce = 0;
4343             pto->PushMessage("ping", nonce);
4344         }
4345
4346         // Start block sync
4347         if (pto->fStartSync) {
4348             pto->fStartSync = false;
4349             pto->PushGetBlocks(pindexBest, uint256(0));
4350         }
4351
4352         // Resend wallet transactions that haven't gotten in a block yet
4353         ResendWalletTransactions();
4354
4355         // Address refresh broadcast
4356         if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
4357             AdvertiseLocal(pto);
4358             pto->nNextLocalAddrSend = PoissonNextSend(nNow, nOneDay);
4359         }
4360
4361         //
4362         // Message: addr
4363         //
4364         if (pto->nNextAddrSend < nNow) {
4365             pto->nNextAddrSend = PoissonNextSend(nNow, 30);
4366             vector<CAddress> vAddr;
4367             vAddr.reserve(pto->vAddrToSend.size());
4368             for(const CAddress& addr :  pto->vAddrToSend)
4369             {
4370                 if (pto->setAddrKnown.insert(addr).second)
4371                 {
4372                     vAddr.push_back(addr);
4373                     // receiver rejects addr messages larger than 1000
4374                     if (vAddr.size() >= 1000)
4375                     {
4376                         pto->PushMessage("addr", vAddr);
4377                         vAddr.clear();
4378                     }
4379                 }
4380             }
4381             pto->vAddrToSend.clear();
4382             if (!vAddr.empty())
4383                 pto->PushMessage("addr", vAddr);
4384         }
4385
4386         //
4387         // Message: inventory
4388         //
4389         vector<CInv> vInv;
4390         vector<CInv> vInvWait;
4391         {
4392             bool fSendTrickle = false;
4393             if (pto->nNextInvSend < nNow) {
4394                 fSendTrickle = true;
4395                 pto->nNextInvSend = PoissonNextSend(nNow, 5);
4396             }
4397             LOCK(pto->cs_inventory);
4398             vInv.reserve(pto->vInventoryToSend.size());
4399             vInvWait.reserve(pto->vInventoryToSend.size());
4400             for(const CInv& inv :  pto->vInventoryToSend)
4401             {
4402                 if (pto->setInventoryKnown.count(inv))
4403                     continue;
4404
4405                 // trickle out tx inv to protect privacy
4406                 if (inv.GetType() == MSG_TX && !fSendTrickle)
4407                 {
4408                     // 1/4 of tx invs blast to all immediately
4409                     static uint256 hashSalt;
4410                     if (hashSalt == 0)
4411                         hashSalt = GetRandHash();
4412                     uint256 hashRand = inv.GetHash() ^ hashSalt;
4413                     hashRand = Hash(hashRand.begin(), hashRand.end());
4414                     bool fTrickleWait = ((hashRand & 3) != 0);
4415
4416                     if (fTrickleWait)
4417                     {
4418                         vInvWait.push_back(inv);
4419                         continue;
4420                     }
4421                 }
4422
4423                 // returns true if wasn't already contained in the set
4424                 if (pto->setInventoryKnown.insert(inv).second)
4425                 {
4426                     vInv.push_back(inv);
4427                     if (vInv.size() >= 1000)
4428                     {
4429                         pto->PushMessage("inv", vInv);
4430                         vInv.clear();
4431                     }
4432                 }
4433             }
4434             pto->vInventoryToSend = vInvWait;
4435         }
4436         if (!vInv.empty())
4437             pto->PushMessage("inv", vInv);
4438
4439
4440         //
4441         // Message: getdata
4442         //
4443         vector<CInv> vGetData;
4444         CTxDB txdb("r");
4445         while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
4446         {
4447             const CInv& inv = (*pto->mapAskFor.begin()).second;
4448             if (!AlreadyHave(txdb, inv))
4449             {
4450                 if (fDebugNet)
4451                     printf("sending getdata: %s\n", inv.ToString().c_str());
4452                 vGetData.push_back(inv);
4453                 if (vGetData.size() >= 1000)
4454                 {
4455                     pto->PushMessage("getdata", vGetData);
4456                     vGetData.clear();
4457                 }
4458                 mapAlreadyAskedFor[inv] = nNow;
4459             }
4460             pto->mapAskFor.erase(pto->mapAskFor.begin());
4461         }
4462         if (!vGetData.empty())
4463             pto->PushMessage("getdata", vGetData);
4464
4465     }
4466     return true;
4467 }
4468
4469
4470 class CMainCleanup
4471 {
4472 public:
4473     CMainCleanup() {}
4474     ~CMainCleanup() {
4475         // block headers
4476         auto it1 = mapBlockIndex.begin();
4477         for (; it1 != mapBlockIndex.end(); it1++)
4478             delete (*it1).second;
4479         mapBlockIndex.clear();
4480
4481         // orphan blocks
4482         auto it2 = mapOrphanBlocks.begin();
4483         for (; it2 != mapOrphanBlocks.end(); it2++)
4484             delete (*it2).second;
4485         mapOrphanBlocks.clear();
4486
4487         // orphan transactions
4488     }
4489 } instance_of_cmaincleanup;