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