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