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