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