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